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

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);


Reply via email to