summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJon TURNEY <jon.turney@dronecode.org.uk>2009-10-03 12:57:03 +0100
committerJon TURNEY <jon.turney@dronecode.org.uk>2009-10-15 18:35:25 +0100
commit69094bffec191c2e6fd797f71d9b9b11ca38982c (patch)
tree6fe4ba9888fcefe7f89f48daac4321b6370261dc
parentcbb831019386d5043e923dff91c0d139800f0649 (diff)
Workaround for SWT/Motif bug
It expects all top-level windows to get reparented, and waits until they do. So workaround that in our internal WM forcing a reparent event to occur, even though we don't actually need to reparent the window to frame it (as the frame is a native window, not an X window) Signed-off-by: Jon TURNEY <jon.turney@dronecode.org.uk>
-rw-r--r--hw/xwin/winmultiwindowwindow.c13
-rw-r--r--hw/xwin/winmultiwindowwm.c119
2 files changed, 79 insertions, 53 deletions
diff --git a/hw/xwin/winmultiwindowwindow.c b/hw/xwin/winmultiwindowwindow.c
index 27f6bfbc3..f127646cd 100644
--- a/hw/xwin/winmultiwindowwindow.c
+++ b/hw/xwin/winmultiwindowwindow.c
@@ -65,19 +65,6 @@ static void
winFindWindow (pointer value, XID id, pointer cdata);
/*
- * Macros
- */
-
-#define SubSend(pWin) \
- ((pWin->eventMask|wOtherEventMasks(pWin)) & SubstructureNotifyMask)
-
-#define StrSend(pWin) \
- ((pWin->eventMask|wOtherEventMasks(pWin)) & StructureNotifyMask)
-
-#define SubStrSend(pWin,pParent) (StrSend(pWin) || SubSend(pParent))
-
-
-/*
* CreateWindow - See Porting Layer Definition - p. 37
*/
diff --git a/hw/xwin/winmultiwindowwm.c b/hw/xwin/winmultiwindowwm.c
index 2ef2d5940..dc0d9a83e 100644
--- a/hw/xwin/winmultiwindowwm.c
+++ b/hw/xwin/winmultiwindowwm.c
@@ -203,7 +203,7 @@ static jmp_buf g_jmpWMEntry;
static jmp_buf g_jmpXMsgProcEntry;
static Bool g_shutdown = FALSE;
static Bool redirectError = FALSE;
-static Bool g_fAnotherWMRunnig = FALSE;
+static Bool g_fAnotherWMRunning = FALSE;
/*
* PushMessage - Push a message onto the queue
@@ -629,7 +629,7 @@ winMultiWindowWMProc (void *pArg)
{
WMMsgNodePtr pNode;
- if(g_fAnotherWMRunnig)/* Another Window manager exists. */
+ if(g_fAnotherWMRunning)/* Another Window manager exists. */
{
Sleep (1000);
continue;
@@ -942,26 +942,15 @@ winMultiWindowXMsgProc (void *pArg)
"successfully opened the display.\n");
/* Check if another window manager is already running */
- if (pProcArg->pWMInfo->fAllowOtherWM)
- {
- g_fAnotherWMRunnig = CheckAnotherWindowManager (pProcArg->pDisplay, pProcArg->dwScreen);
- } else {
- redirectError = FALSE;
- XSetErrorHandler (winRedirectErrorHandler);
- XSelectInput(pProcArg->pDisplay,
- RootWindow (pProcArg->pDisplay, pProcArg->dwScreen),
- SubstructureNotifyMask | ButtonPressMask);
- XSync (pProcArg->pDisplay, 0);
- XSetErrorHandler (winMultiWindowXMsgProcErrorHandler);
- if (redirectError)
- {
- ErrorF ("winMultiWindowXMsgProc - "
- "another window manager is running. Exiting.\n");
- pthread_exit (NULL);
+ g_fAnotherWMRunning = CheckAnotherWindowManager (pProcArg->pDisplay, pProcArg->dwScreen);
+
+ if (g_fAnotherWMRunning && !pProcArg->pWMInfo->fAllowOtherWM)
+ {
+ ErrorF ("winMultiWindowXMsgProc - "
+ "another window manager is running. Exiting.\n");
+ pthread_exit (NULL);
}
- g_fAnotherWMRunnig = FALSE;
- }
-
+
/* Set up the supported icon sizes */
xis = XAllocIconSize ();
if (xis)
@@ -1006,17 +995,17 @@ winMultiWindowXMsgProc (void *pArg)
{
if (CheckAnotherWindowManager (pProcArg->pDisplay, pProcArg->dwScreen))
{
- if (!g_fAnotherWMRunnig)
+ if (!g_fAnotherWMRunning)
{
- g_fAnotherWMRunnig = TRUE;
+ g_fAnotherWMRunning = TRUE;
SendMessage(*(HWND*)pProcArg->hwndScreen, WM_UNMANAGE, 0, 0);
}
}
else
{
- if (g_fAnotherWMRunnig)
+ if (g_fAnotherWMRunning)
{
- g_fAnotherWMRunnig = FALSE;
+ g_fAnotherWMRunning = FALSE;
SendMessage(*(HWND*)pProcArg->hwndScreen, WM_MANAGE, 0, 0);
}
}
@@ -1046,6 +1035,60 @@ winMultiWindowXMsgProc (void *pArg)
event.xcreatewindow.window,
0);
}
+ else if (event.type == MapNotify)
+ {
+ /* Fake a reparentNotify event as SWT/Motif expects a
+ Window Manager to reparent a top-level window when
+ it is mapped and waits until they do.
+
+ We don't actually need to reparent, as the frame is
+ a native window, not an X window
+
+ We do this on MapNotify, not MapRequest like a real
+ Window Manager would, so we don't have do get involved
+ in actually mapping the window via it's (non-existent)
+ parent...
+
+ See sourceware bugzilla #9848
+ */
+
+ XWindowAttributes attr;
+ Window root;
+ Window parent;
+ Window *children;
+ unsigned int nchildren;
+
+ if (XGetWindowAttributes(event.xmap.display,
+ event.xmap.window,
+ &attr) &&
+ XQueryTree(event.xmap.display,
+ event.xmap.window,
+ &root, &parent, &children, &nchildren))
+ {
+ if (children) XFree(children);
+
+ /*
+ It's a top-level window if the parent window is a root window
+ Only non-override_redirect windows can get reparented
+ */
+ if ((attr.root == parent) && !event.xmap.override_redirect)
+ {
+ XEvent event_send;
+
+ event_send.type = ReparentNotify;
+ event_send.xreparent.event = event.xmap.window;
+ event_send.xreparent.window = event.xmap.window;
+ event_send.xreparent.parent = parent;
+ event_send.xreparent.x = attr.x;
+ event_send.xreparent.y = attr.y;
+
+ XSendEvent(event.xmap.display,
+ event.xmap.window,
+ True, StructureNotifyMask,
+ &event_send);
+ }
+ }
+ }
else if (event.type == PropertyNotify
&& event.xproperty.atom == atmWmName)
{
@@ -1432,27 +1475,23 @@ winRedirectErrorHandler (Display *pDisplay, XErrorEvent *pErr)
static Bool
CheckAnotherWindowManager (Display *pDisplay, DWORD dwScreen)
{
+ /*
+ Try to select the events which only one client at a time is allowed to select.
+ If this causes an error, another window manager is already running...
+ */
redirectError = FALSE;
XSetErrorHandler (winRedirectErrorHandler);
XSelectInput(pDisplay, RootWindow (pDisplay, dwScreen),
- // SubstructureNotifyMask | ButtonPressMask
- ColormapChangeMask | EnterWindowMask | PropertyChangeMask |
- SubstructureRedirectMask | KeyPressMask |
- ButtonPressMask | ButtonReleaseMask);
+ ResizeRedirectMask | SubstructureRedirectMask | ButtonPressMask);
XSync (pDisplay, 0);
XSetErrorHandler (winMultiWindowXMsgProcErrorHandler);
- XSelectInput(pDisplay, RootWindow (pDisplay, dwScreen),
- SubstructureNotifyMask);
+
+ /*
+ Side effect: select the events we are actually interested in...
+ */
+ XSelectInput(pDisplay, RootWindow (pDisplay, dwScreen), SubstructureNotifyMask);
XSync (pDisplay, 0);
- if (redirectError)
- {
- //ErrorF ("CheckAnotherWindowManager() - another window manager is running. Exiting.\n");
- return TRUE;
- }
- else
- {
- return FALSE;
- }
+ return redirectError;
}
/*