summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDeron Johnson <deron.johnson@sun.com>2004-12-14 00:23:59 +0000
committerDeron Johnson <deron.johnson@sun.com>2004-12-14 00:23:59 +0000
commit59ff7da7b6a2a46c3c78515eef274357d54072ec (patch)
tree70f7dc422c9994bf951801934f8ae4c82fa0e062
parent07373dbbc38e4e52803a8ca723a7d4fe11e721d5 (diff)
Fix 192: Xserver race condition causes stuck popups. ZZ
-rw-r--r--dix/window.c42
-rw-r--r--include/windowstr.h8
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