[prev in list] [next in list] [prev in thread] [next in thread]
List: wine-devel
Subject: BadWindow errors
From: gerard patel <g.patel () wanadoo ! fr>
Date: 2000-08-27 15:20:24
[Download RAW message or body]
I have 3 applications that are sometimes outputing this kind of message in -managed \
mode, usually when exiting or when terminating a dialog :
X Error of failed request: BadWindow (invalid Window parameter)
Major opcode of failed request: 12 (X_ConfigureWindow)
Resource id in failed request: 0x10032ae
Serial number of failed request: 21957
Current serial number in output stream: 21958
Usually the failed request is ConfigureWindow, sometimes QueryTree.
I have sometimes seen similar messages on cemw.
One of these applications has this problem much more often than the others, so I used \
it to track what is happening.
The 'Resource id in failed request' are never Wine windows, always the X parents of
Wine windows, that is, the windows that my window manager is using to \
decorate/manage the top window(s) of Wine.
It seems that when Wine ask X to unmap a window, the WM is deleting the reparenting
window; all right, there is no reason for the WM to keep around a window that will
maybe never be used again. Unfortunately, it seems that the WM (well, my WM at least \
: KDE 1.1) can take the decision to zap its reparenting window at any time, not \
immediately when the real window is unmapped..Since Wine can try to reorder hidden \
windows, any restacking can fail.
The attached patch implements an error handler for restacking the windows.
[ ICCCM 4.1.5 :
Clients that must position themselves in the stack relative to some window that was \
originally a sibling must do the ConfigureWindow request (in case they are running \
under a nonreparenting window manager), be prepared to deal with a resulting error \
(...) ]
Comments, insights, test results appreciated as I am way beyond my familiar territory \
here - but I hope to submit a real patch based on what I have done so far.
Gerard
["restack.dif" (text/plain)]
--- wnd.c.orig Sun Aug 20 16:54:48 2000
+++ wnd.c Mon Aug 28 00:07:11 2000
@@ -581,11 +581,12 @@
WIN_ReleaseDesktop();
}
+
/***********************************************************************
* X11DRV_WND_FindDesktopXWindow [Internal]
*
* Find the actual X window which needs be restacked.
- * Used by X11DRV_WND_SetWindowPos().
+ * Used by X11DRV_WND_SetWindowPos(). Entered with X locked.
*/
static Window X11DRV_WND_FindDesktopXWindow( WND *wndPtr )
{
@@ -598,9 +599,10 @@
window = X11DRV_WND_GetXWindow(wndPtr);
for (;;)
{
- TSXQueryTree( display, window, &root, &parent,
- &children, &nchildren );
- TSXFree( children );
+ if (!XQueryTree( display, window, &root, &parent,
+ &children, &nchildren ))
+ return 0;
+ XFree( children );
if (parent == root)
return window;
window = parent;
@@ -608,6 +610,32 @@
}
}
+/* it's not possible to prevent all X errors when
+ reordering managed windows that were just unmapped
+ (the WM can delete the reparenting window at any
+ time, so catch the error instead */
+static int restackerror_handler(Display *display, XErrorEvent *error_evt)
+{
+ ERR("restack err %d\n", error_evt->error_code);
+ return 0;
+}
+
+static void X11DRV_WND_Restack(WND *wnd1, WND *wnd2)
+{
+ Window stack[2];
+ void *ptr;
+ EnterCriticalSection(&X11DRV_CritSection);
+ ptr = XSetErrorHandler(restackerror_handler);
+ if ((stack[0] = X11DRV_WND_FindDesktopXWindow( wnd1 )))
+ {
+ if ((stack[1] = X11DRV_WND_FindDesktopXWindow( wnd2 )))
+ XRestackWindows(display, stack, 2);
+ }
+ XSync(display, False);
+ XSetErrorHandler(ptr);
+ LeaveCriticalSection(&X11DRV_CritSection);
+}
+
/***********************************************************************
* WINPOS_SetXWindowPos
*
@@ -692,7 +720,6 @@
else if (winpos->hwndInsertAfter != HWND_BOTTOM)
{
WND* insertPtr = WIN_FindWndPtr( winpos->hwndInsertAfter );
- Window stack[2];
/* If the window where we should do the insert is zero-sized (not mapped)
don't used this window since it will possibly crash the X server,
@@ -731,20 +758,14 @@
}
else
{
- stack[0] = X11DRV_WND_FindDesktopXWindow( wndPrev );
- stack[1] = X11DRV_WND_FindDesktopXWindow( winposPtr );
-
- TSXRestackWindows(display, stack, 2);
+ X11DRV_WND_Restack(wndPrev, winposPtr);
changeMask &= ~CWStackMode;
}
}
else /* Normal behavior, windows are not zero-sized */
{
- stack[0] = X11DRV_WND_FindDesktopXWindow( insertPtr );
- stack[1] = X11DRV_WND_FindDesktopXWindow( winposPtr );
-
- TSXRestackWindows(display, stack, 2);
- changeMask &= ~CWStackMode;
+ X11DRV_WND_Restack(insertPtr, winposPtr);
+ changeMask &= ~CWStackMode;
}
WIN_ReleaseWndPtr(insertPtr);
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic