xwayland: Fix windows disappearing on reparenting

If the wayland surface isn't available yet when we process the
WL_SURFACE_ID ClientMessage, we schedule a later function to try the
association again after we get a chance to process wayland requests.

This works fine except on cases where the MetaWindow already had a
previous surface attached (i.e. when the xwindow is reparented) since
we only break the existing association on the later function which
means that when processing the old surface's destruction we destroy
the MetaWindow and cancel the pending later function leaving us
without a MetaWindow and an invisible surface.

Fix this by detaching the old surface as soon as possible so that the
MetaWindow survives.

https://bugzilla.gnome.org/show_bug.cgi?id=743339
This commit is contained in:
Rui Matos 2015-09-25 16:18:55 +02:00
parent 9abc071283
commit 69c267b142

View File

@ -55,13 +55,6 @@ associate_window_with_surface (MetaWindow *window,
{ {
MetaDisplay *display = window->display; MetaDisplay *display = window->display;
/* If the window has an existing surface, like if we're
* undecorating or decorating the window, then we need
* to detach the window from its old surface.
*/
if (window->surface)
window->surface->window = NULL;
if (!meta_wayland_surface_assign_role (surface, if (!meta_wayland_surface_assign_role (surface,
META_TYPE_WAYLAND_SURFACE_ROLE_XWAYLAND)) META_TYPE_WAYLAND_SURFACE_ROLE_XWAYLAND))
{ {
@ -88,6 +81,16 @@ associate_window_with_surface_id (MetaXWaylandManager *manager,
{ {
struct wl_resource *resource; struct wl_resource *resource;
/* If the window has an existing surface, like if we're
* undecorating or decorating the window, then we need
* to detach the window from its old surface.
*/
if (window->surface)
{
meta_wayland_surface_set_window (window->surface, NULL);
window->surface = NULL;
}
resource = wl_client_get_object (manager->client, surface_id); resource = wl_client_get_object (manager->client, surface_id);
if (resource) if (resource)
{ {