window-actor: Handle surface reuse when window reparenting

The commit f2f4af0d missed one situation where mutter does things differently, i.e. changes what surface actor is associated with a given window actor: reparenting a Xwayland window when changing whether it is decorated.

To summarize, there are three types of window actors:

X11 window actors - directly tied to the backing X11 window. The corresponding surface actor is directly owned by the window actor and will never change.

Wayland window actors - gets its surface actor from MetaWaylandSurface at construction. A single MetaWaylandSurface may create and destroy multiple window actors over time, but a single window actor will never change surface actor.

Xwayland window actors - a mix between the above two types; the window corresponds to the X11 window, and so does the window actor, but the surface itself comes from the MetaWaylandSurface.

Normally when a X11 window is unmapped, the corresponding MetaWindow is unmanaged. With Xwayland, this happens indirectly via the destruction of the wl_surface. The exception to this is windows that are reparented during changing their decoration state - in this case on plain X11, the MetaWindow stays alive. With Xwayland however, there is a race condition; since the MetaWindow is tied to the wl_surface, if we receive the new surface ID atom before the destruction of the old wl_surface, we'll try to associate the existing MetaWindow and MetaWindowActor with the new wl_surface, hitting the assert. If the surface destruction arrives first, the MetaWindow and MetaWindowActor will be disposed, and the we wouldn't hit the assert.

To handle this race gracefully, reinstate handling of replacing the surface actor of an existing window actor, to handle this race, as it was handled before.

Eventually, it should be reconsidered whether the MetaWindow lifetime is tied to the wl_surface or if it should be changed to be consistent with plain X11, as this re-exposes another bug where the X11 client and mutter will enter a feedback loop where the window is repeatedly remapped. See

Fixes: #709 (closed)

Merge request reports