Since we get the ClientMessage after the surface is created, there's
no good way to synchronize the two streams. In this case, what we
need to do is delay the surface commit until after we get the
ClientMessage. Ideally, we'd be using a better surface system overall
where committing the surface didn't depend on what type it is, but
oh well, this is a good short-term hack for now.
The make_toplevel / window_unmanaging interface has never made
a lot of sense to me. Replace it with set_window, which does
effectively the same thing.
It's still not perfect in the case of XWayland, but I don't think
XWayland will ever make me happy.
Previously, a sequence like this would crash a client:
=> surface.attach(buffer)
=> buffer.destroy()
The correct behavior is to wait until we release the buffer before
destroying it.
=> surface.attach(buffer)
=> surface.attach(buffer2)
<= buffer.release()
=> buffer.destroy()
The protocol upstream says that "the surface contents are undefined"
in a case like this. Personally, I think that this is broken behavior
and no client should ever do it, so I explicitly killed any client
that tried to do this.
But unfortunately, as we're all well aware, XWayland does this.
Rather than wait for XWayland to be fixed, let's just allow this.
Technically, since we always copy SHM buffers into GL textures, we
could release the buffer as soon as the Cogl texture is made.
Since we do this copy, the semantics we apply are that the texture is
"frozen" in time until another newer buffer is attached. For simple
clients that simply abort on exit and don't wait for the buffer event
anyhow, this has the added bonus that we'll get nice destroy animations.
Do to a bad mixup, the surface listener was never actually fired.
This was accidentally fixed as part of a refactoring in a27fb19,
but the surface listener was broken, and we started crashing. To
fix, just remove the surface listener, as we've mostly been testing
without it.
This is not needed since the instance is being destroyed and in fact
actively harmful when code called from other handlers disconnects us
for other reasons. In that case we might crash because the
disconnection doesn't prevent other handlers from running in the
current signal emission and thus we try to remove ourselves from an
empty list.
This changes the user data of all surface extensions resources to be
the MetaWaylandSurface instead of the MetaWaylandSurfaceExtension,
which means that we no longer need all these pesky wl_container_ofs
in implementations.
Don't set the surface actor to a new buffer if it's becoming unmapped.
This is also technically wrong since we'll send out the release event,
but oh well.
We should probably decouple MetaWaylandBuffer from the CoglTexture
at some point, so we can send out releases on-demand.
This time, to make way for MetaSurfaceActorEmpty. This also fixes
destroy effects as a side effect. It still has issues if we try
to re-assign an actor that's already toplevel (e.g. somebody
re-popping up a menu that's already being destroyed), but this
will be fixed soon.
The idea here is that MetaWindowActor will do the unparenting of
the surface actor when it itself is destroyed. To prevent bad issues
with picking, we only make the surface actor reactive when it's
toplevel.
The rendering logic before was somewhat complex. We had three independent
cases to take into account when doing rendering:
* X11 compositor. In this case, we're a traditional X11 compositor,
not a Wayland compositor. We use XCompositeNameWindowPixmap to get
the backing pixmap for the window, and deal with the COMPOSITE
extension messiness.
In this case, meta_is_wayland_compositor() is FALSE.
* Wayland clients. In this case, we're a Wayland compositor managing
Wayland surfaces. The rendering for this is fairly straightforward,
as Cogl handles most of the complexity with EGL and SHM buffers...
Wayland clients give us the input and opaque regions through
wl_surface.
In this case, meta_is_wayland_compositor() is TRUE and
priv->window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND.
* XWayland clients. In this case, we're a Wayland compositor, like
above, and XWayland hands us Wayland surfaces. XWayland handles
the COMPOSITE extension messiness for us, and hands us a buffer
like any other Wayland client. We have to fetch the input and
opaque regions from the X11 window ourselves.
In this case, meta_is_wayland_compositor() is TRUE and
priv->window->client_type == META_WINDOW_CLIENT_TYPE_X11.
We now split the rendering logic into two subclasses, which are:
* MetaSurfaceActorX11, which handles the X11 compositor case, in that
it uses XCompositeNameWindowPixmap to get the backing pixmap, and
deal with all the COMPOSITE extension messiness.
* MetaSurfaceActorWayland, which handles the Wayland compositor case
for both native Wayland clients and XWayland clients. XWayland handles
COMPOSITE for us, and handles pushing a surface over through the
xf86-video-wayland DDX.
Frame sync is still in MetaWindowActor, as it needs to work for both the
X11 compositor and XWayland client cases. When Wayland's video display
protocol lands, this will need to be significantly overhauled, as it would
have to work for any wl_surface, including subsurfaces, so we would need
surface-level discretion.
https://bugzilla.gnome.org/show_bug.cgi?id=720631
This reverts commit 283a81eac0.
This can't be done yet, as it will crash when we try to do a destroy
effect from a plugin. The surface actor needs to outlive the surface
in this case.
Though, the unparenting happening is wrong anyway for a destroy effect.
We need to figure out a sane way of doing this unparenting only after
all effects have finished.
As resource destruction can happen in any order at shutdown, we
need to be flexible here. A client disconnecting without cleaning
up all its resources should not assert fail.
The input region was set on the shaped texture, but the shaped texture
was never picked properly, as it was never set to be reactive. Move the
pick implementation and reactivity to the MetaSurfaceActor, and update
the code everywhere else to expect a MetaSurfaceActor.
I tested this with meta_window_get_input_rect and decided to change
it at the last minute. Turns out meta_window_get_rect is unlike all
the others. Just access window->rect directly instead.
Now that we call set_custom_frame_extents, the frame rect corresponds
to the "visible window geometry" used for constrainment, while the
x/y fields in get_xdg_popup instead are relative to the surface.
Both the pointer/keyboard resource and surface resource can be destroyed
at any point in the destruction process, so we need to have destroy
listeners on both. To make the code easier to follow, rename ->focus
to ->focus_surface at the same time, and rearrange the code so that
the two of them are always grouped together.
To prevent the MetaSurfaceActor from being destroyed, we normally
unparent it before we unmanage the window. However, this doesn't
work for XWayland windows, which we unmanage when we get UnmapNotify
or DestroyNotify, not when we get the wl_surface_destroy.
To solve this, add an early hook in meta_window_unmanage that
unparents the surface actor if we have one. At the same time, clean
up the destruction code to remove old comments and assumptions about
how wl_shell behaves.
This was a bad idea, as ping/pong has moved to a client-specific
request/event pair, rather than a surface-specific one. Revert
the changes we made here and correct the code to make up for it.
This reverts commit aa3643cdde.
We want to remove a bunch of auxilliary duties from the MetaWindowActor
and MetaSurfaceActor, including some details of how culling is done.
Move the unobscured region culling code to the MetaShapedTexture, which
helps the actor become "more independent".
https://bugzilla.gnome.org/show_bug.cgi?id=720631
This is considered "undefined" by upstream. Right now GTK+ does this
a lot, so we shouldn't crash. Let's make them crash instead and send
them an error instead.