X11: Problems with ConfigureNotify events that are received/processed too late

Michael Kaufmann hallo at michael-kaufmann.ch
Tue Aug 16 09:00:39 CDT 2005


Hi all,

I'm trying to get the dialog boxes of Word 95 working. They often appear 
with the minimal window size (about 70x50 pixels), so they're unusable. 
With KDE's window manager (KWin) this happens very often. With 
Enlightenment and GNOME's window manager (Metacity), it only happens 
from time to time.

I've looked for the reason, and I think it's very closely related to 
WINE bug 1265 which Duane Clark has tried to fix here: 
http://www.winehq.com/hypermail/wine-patches/2003/02/0095.html

That's what's going on (CVS version of WINE, managed window mode):

1. Word creates a dialog with an initial position of (0,0) and size 0x0 
(using CreateWindowEx)
2. Word calls SetWindowPos to set the correct dialog position and size
3. Word calls SetWindowPos to show the dialog (SWP_SHOWWINDOW)
4. The dialog gets the focus, the main window is being deactivated
5. In the WM_NCACTIVATE procedure of the main window, Word calls 
GetQueueStatus. WINE will process X events.
6. WINE receives a ConfigureEvent for the initial dialog position and 
size (0x0) and saves this to data->whole_rect in X11DRV_sync_window_position
(7. If you're lucky, WINE also receives a ConfigureEvent for the correct 
dialog position)
8. Wine shows the dialog and maps it. It calls X11DRV_set_wm_hints, 
which calls set_size_hints. This procedure uses data->whole_rect as the 
dialog's rectangle. But this stored rectangle is completely wrong 
because WINE has not yet received all ConfigureEvents.
9. The window manager has to resize the dialog to the wrong size.


The best solution would be to process all X events before setting the 
window position in SetWindowPos, but I don't know if that's possible.

I've tried another approach: WINE should not set the window size hints 
when mapping a window (step 8.). I've attached a patch, but it's not 
100% correct, because the style of a window (e.g. the WS_THICKFRAME 
style) may be changed by an application using SetWindowLong and 
SetWindowPos (with the SWP_FRAMECHANGED flag).

WINE doesn't look for the SWP_FRAMECHANGED flag and updates the X11 
window every time if it's visible or gets visible. So if an application 
calls SetWindowPos with the SWP_SHOWWINDOW flag, WINE needs to set the 
size hints because the window has been hidden and its style may have 
been changed.

What would be the correct fix for this problem? Any ideas?

Thanks,
Michael

-------------- next part --------------
Index: window.c
===================================================================
RCS file: /home/wine/wine/dlls/x11drv/window.c,v
retrieving revision 1.115
diff -u -r1.115 window.c
--- window.c	27 Jul 2005 15:22:58 -0000	1.115
+++ window.c	15 Aug 2005 21:32:54 -0000
@@ -353,9 +353,9 @@
 /***********************************************************************
  *              X11DRV_set_wm_hints
  *
- * Set the window manager hints for a newly-created window
+ * Set the window manager hints for a window
  */
-void X11DRV_set_wm_hints( Display *display, struct x11drv_win_data *data )
+void X11DRV_set_wm_hints( Display *display, struct x11drv_win_data *data, BOOL update_size_hints )
 {
     Window group_leader;
     XClassHint *class_hints;
@@ -400,7 +400,7 @@
     }
 
     /* size hints */
-    set_size_hints( display, data, style );
+    if (update_size_hints) set_size_hints( display, data, style );
 
     /* systray properties (KDE only for now) */
     if (ex_style & WS_EX_TRAYWINDOW)
@@ -692,7 +692,7 @@
     xim = x11drv_thread_data()->xim;
     if (xim) data->xic = X11DRV_CreateIC( xim, display, data->whole_window );
 
-    X11DRV_set_wm_hints( display, data );
+    X11DRV_set_wm_hints( display, data, TRUE );
 
     SetPropA( data->hwnd, whole_window_prop, (HANDLE)data->whole_window );
     return data->whole_window;
Index: winpos.c
===================================================================
RCS file: /home/wine/wine/dlls/x11drv/winpos.c,v
retrieving revision 1.136
diff -u -r1.136 winpos.c
--- winpos.c	15 Aug 2005 09:33:39 -0000	1.136
+++ winpos.c	15 Aug 2005 21:32:56 -0000
@@ -489,7 +489,7 @@
             {
                 TRACE( "mapping win %p\n", hwnd );
                 X11DRV_sync_window_style( display, data );
-                X11DRV_set_wm_hints( display, data );
+                X11DRV_set_wm_hints( display, data, FALSE );
                 wine_tsx11_lock();
                 XMapWindow( display, data->whole_window );
                 wine_tsx11_unlock();
@@ -650,7 +650,7 @@
                 {
                     TRACE( "mapping win %p\n", hwnd );
                     X11DRV_sync_window_style( display, data );
-                    X11DRV_set_wm_hints( display, data );
+                    X11DRV_set_wm_hints( display, data, FALSE );
                     wine_tsx11_lock();
                     XMapWindow( display, data->whole_window );
                     wine_tsx11_unlock();
Index: x11drv.h
===================================================================
RCS file: /home/wine/wine/dlls/x11drv/x11drv.h,v
retrieving revision 1.76
diff -u -r1.76 x11drv.h
--- x11drv.h	29 Jun 2005 19:28:06 -0000	1.76
+++ x11drv.h	15 Aug 2005 21:32:58 -0000
@@ -686,7 +686,7 @@
                                          const RECT *new_whole_rect );
 extern BOOL X11DRV_set_window_pos( HWND hwnd, HWND insert_after, const RECT *rectWindow,
                                    const RECT *rectClient, UINT swp_flags, const RECT *validRects );
-extern void X11DRV_set_wm_hints( Display *display, struct x11drv_win_data *data );
+extern void X11DRV_set_wm_hints( Display *display, struct x11drv_win_data *data, BOOL update_size_hints );
 
 extern void X11DRV_handle_desktop_resize(unsigned int width, unsigned int height);
 extern void X11DRV_Settings_AddDepthModes(void);




More information about the wine-devel mailing list