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