From 59ff7da7b6a2a46c3c78515eef274357d54072ec Mon Sep 17 00:00:00 2001 From: Deron Johnson Date: Tue, 14 Dec 2004 00:23:59 +0000 Subject: Fix 192: Xserver race condition causes stuck popups. ZZ --- dix/window.c | 42 ++++++++++++++++++++++++++++++++++++++++-- include/windowstr.h | 8 ++++++++ 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/dix/window.c b/dix/window.c index f72f63a4c..fc438d5c6 100644 --- a/dix/window.c +++ b/dix/window.c @@ -1,4 +1,4 @@ -/* $XdotOrg: xc/programs/Xserver/dix/window.c,v 1.6 2004/07/31 08:24:13 anholt Exp $ */ +/* $XdotOrg: xc/programs/Xserver/dix/window.c,v 1.6.4.1 2004/09/16 23:37:22 deronj Exp $ */ /* $Xorg: window.c,v 1.4 2001/02/09 02:04:41 xorgcvs Exp $ */ /* @@ -833,6 +833,7 @@ CreateWindow(wid, pParent, x, y, w, h, bw, class, vmask, vlist, event.u.createNotify.override = pWin->overrideRedirect; DeliverEvents(pParent, &event, 1, NullWindow); } + return pWin; } @@ -2806,6 +2807,7 @@ MapWindow(pWin, client) redirToWm = RedirectSend(pParent) || (pParent->drawable.id == lgeDisplayServerPRW); /* Note: even send notifications for override redirect window */ + } else { redirToWm = !pWin->overrideRedirect && RedirectSend(pParent); } @@ -2836,11 +2838,44 @@ MapWindow(pWin, client) event.u.mapRequest.parent = pParent->drawable.id; if (MaybeDeliverEventsToClient(pParent, &event, 1, - SubstructureRedirectMask, client) == 1) + SubstructureRedirectMask, client) == 1) { +#ifdef LG3D + /* + ** Some clients assume that MapWindow is atomic for override redirect + ** windows; they fire off pairs of MapWindow and UnmapWindow requests + ** in rapid succession. But by forcing override redirect windows to + ** send MapRequest events to the window manager (see above) we have + ** made MapWindow no longer atomic for these windows. We need to + ** restore atomicity to this request by suspending request processing + ** for the client until the window has actually been mapped, whereupon + ** we can resume request processing for the client. + */ + if (pWin->overrideRedirect) { + if (pWin->optional == NULL) { + if (!MakeWindowOptional(pWin)) { + ErrorF("LG3D: Warning: MapWindow is not atomic for override redirect window\n"); + return Success; + } + } + pWin->optional->clientSleepingOnOvRedirMapWin = client; + ClientSleep(client, NULL, NULL); + } +#endif /* LG3D */ return(Success); + } } pWin->mapped = TRUE; + +#ifdef LG3D + { ClientPtr sleepingClient = wClientSleepingOnOvRedirMapWin(pWin); + if (sleepingClient != NULL) { + ClientWakeup(sleepingClient); + pWin->optional->clientSleepingOnOvRedirMapWin = NULL; + } + } +#endif /* LG3D */ + if (SubStrSend(pWin, pParent)) { event.u.u.type = MapNotify; @@ -3766,6 +3801,9 @@ MakeWindowOptional (pWin) optional->cursor = None; } optional->colormap = parentOptional->colormap; +#ifdef LG3D + optional->clientSleepingOnOvRedirMapWin = NULL; +#endif /* LG3D */ pWin->optional = optional; return TRUE; } diff --git a/include/windowstr.h b/include/windowstr.h index c89c7b18e..1b9005261 100644 --- a/include/windowstr.h +++ b/include/windowstr.h @@ -90,6 +90,10 @@ typedef struct _WindowOpt { #ifdef XINPUT struct _OtherInputMasks *inputMasks; /* default: NULL */ #endif +#ifdef LG3D + /* If non-null, specifies a client sleeping until the WM maps this window */ + ClientPtr clientSleepingOnOvRedirMapWin; +#endif /* LG3D */ } WindowOptRec, *WindowOptPtr; #define BackgroundPixel 2L @@ -178,6 +182,10 @@ extern Mask DontPropagateMasks[]; #define wClient(w) (clients[CLIENT_ID((w)->drawable.id)]) #define wBorderWidth(w) ((int) (w)->borderWidth) +#ifdef LG3D +#define wClientSleepingOnOvRedirMapWin(w) wUseDefault(w, clientSleepingOnOvRedirMapWin, NULL) +#endif /* LG3D */ + /* true when w needs a border drawn. */ #ifdef SHAPE -- cgit v1.2.3