dix/window: fix UnmapNotify and DestroyNotify order in DestroySubwindows

The X11 protocol requires each window to be destroyed in turn.
Previously, DestroySubwindows unmapped all child windows first.
This sent all UnmapNotify events before any DestroyNotify events.
Removing the UnmapSubwindows call lets each child window be unmapped
and destroyed individually. This restores correct event ordering.

Each child now runs its own ValidateTree pass instead of sharing one.
This diverges from xorg/main, which still carries the UnmapSubwindows
shortcut and its XXX comment.

Signed-off-by: Mason Green <mason@greenm01.net>
(cherry picked from commit 12a1661046)
This commit is contained in:
Mason Green 2026-10-09 09:46:55 -04:00 • committed by Enrico Weigelt
commit 9105358907

View file

@ -1075,15 +1075,10 @@ DeleteWindow(void *value, XID wid)
int
DestroySubwindows(WindowPtr pWin, ClientPtr client)
{
/* XXX
* The protocol is quite clear that each window should be
* destroyed in turn, however, unmapping all of the first
* eliminates most of the calls to ValidateTree. So,
* this implementation is incorrect in that all of the
* UnmapNotifies occur before all of the DestroyNotifies.
* If you care, simply delete the call to UnmapSubwindows.
*/
UnmapSubwindows(pWin);
/* The protocol requires each window to be destroyed in turn.
* Unmapping each child window individually ensures correct UnmapNotify
* and DestroyNotify event ordering. Each child now runs its own
* ValidateTree pass, which the old bulk unmap avoided; correctness wins. */
while (pWin->lastChild) {
int rc = XaceHookResourceAccess(client,
pWin->lastChild->drawable.id, X11_RESTYPE_WINDOW,