Browse Source

qt: unmap indirection X11 window before reparenting it back to root

Reparenting a mapped window to root causes it to become a toplevel
window and can cause window managers to reparent the window themselves
to show their decorations.

This could happen in two situations:

1. Theoretically it could happen briefly between WindowReleased and
   WindowClose.
2. It could trigger a race between VLC and the WM if there is a quick
   sequence of WindowOpen -> WindowReleased -> WindowClose -> WindowOpen
   such as when using single instance mode. If the X-server in this
   situation happens to re-use the XID of the X11 indirection window
   from the first WindowOpen for the second WindowOpen, this could
   result in the following race:
   - VLC creates a new X11 indirection window, reparents and maps it
   - VLC reparents it to root
   - VLC closes the connection, freeing the XID
   - VLC opens a new connection
   - VLC creates a new indirection window with the same XID as before
     and reparents and maps it
   - The X-server sends a MapRequest for the *first* X11 indirection
     window caused by the reparent to root to the WM
   - The WM sees a new toplevel window and reparents it. Because the XID
     used by that reparent request is the same as of the newly created
     indirection window, the new window ends up getting reparented.
   This then would result in the indirection window remaining as
   toplevel window. The exact order might change slightly between the
   different processes, but as long as the reparent request by the WM is
   the last one, the issue will trigger.

Closes #25692
cherry-pick-c5513cf9
Sebastian Keller 4 years ago
committed by Jean-Baptiste Kempf
parent
commit
9724414101
  1. 1
      modules/gui/qt/qt.cpp

1
modules/gui/qt/qt.cpp

@ -838,6 +838,7 @@ void WindowOrphaned(vout_window_t *wnd)
* window, WindowOpen() will skip reparenting. Then this call will be
* a no-op.
*/
XUnmapWindow (sys->dpy, wnd->handle.xid);
XReparentWindow(sys->dpy, wnd->handle.xid,
RootWindow(sys->dpy, DefaultScreen(sys->dpy)), 0, 0);
XSync(sys->dpy, True);

Loading…
Cancel
Save