Alexandre Julliard : winex11: Wait for a window to move out of withdrawn state before withdrawing it again .

Alexandre Julliard julliard at winehq.org
Wed Mar 5 13:41:12 CST 2008


Module: wine
Branch: master
Commit: d0e14bf7092af65c1ff938d3c4fddd1259967f95
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=d0e14bf7092af65c1ff938d3c4fddd1259967f95

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Wed Mar  5 16:52:22 2008 +0100

winex11: Wait for a window to move out of withdrawn state before withdrawing it again.

---

 dlls/winex11.drv/event.c  |   37 +++++++++++++++++++++----------------
 dlls/winex11.drv/winpos.c |    7 ++++---
 dlls/winex11.drv/x11drv.h |    2 +-
 3 files changed, 26 insertions(+), 20 deletions(-)

diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c
index 3373cf7..cdd0853 100644
--- a/dlls/winex11.drv/event.c
+++ b/dlls/winex11.drv/event.c
@@ -654,35 +654,40 @@ static void EVENT_PropertyNotify( HWND hwnd, XEvent *xev )
 /* event filter to wait for a WM_STATE change notification on a window */
 static Bool is_wm_state_notify( Display *display, XEvent *event, XPointer arg )
 {
-    return (event->type == PropertyNotify &&
-            event->xproperty.window == (Window)arg &&
-            event->xproperty.atom == x11drv_atom(WM_STATE));
+    if (event->xany.window != (Window)arg) return 0;
+    return (event->type == DestroyNotify ||
+            (event->type == PropertyNotify && event->xproperty.atom == x11drv_atom(WM_STATE)));
 }
 
 /***********************************************************************
  *           wait_for_withdrawn_state
  */
-void wait_for_withdrawn_state( Display *display, struct x11drv_win_data *data )
+void wait_for_withdrawn_state( Display *display, struct x11drv_win_data *data, BOOL set )
 {
     DWORD end = GetTickCount() + 2000;
 
-    if (!data->whole_window || !data->managed) return;
+    if (!data->managed) return;
 
-    while (data->wm_state != WithdrawnState &&
-           !process_events( display, is_wm_state_notify, data->whole_window ))
-    {
-        struct pollfd pfd;
-        int timeout = end - GetTickCount();
+    TRACE( "waiting for window %p/%lx to become %swithdrawn\n",
+           data->hwnd, data->whole_window, set ? "" : "not " );
 
-        TRACE( "waiting for window %p/%lx to become withdrawn\n", data->hwnd, data->whole_window );
-        pfd.fd = ConnectionNumber(display);
-        pfd.events = POLLIN;
-        if (timeout <= 0 || poll( &pfd, 1, timeout ) != 1)
+    while (data->whole_window && ((data->wm_state == WithdrawnState) == !set))
+    {
+        if (!process_events( display, is_wm_state_notify, data->whole_window ))
         {
-            FIXME( "window %p/%lx wait timed out\n", data->hwnd, data->whole_window );
-            return;
+            struct pollfd pfd;
+            int timeout = end - GetTickCount();
+
+            pfd.fd = ConnectionNumber(display);
+            pfd.events = POLLIN;
+            if (timeout <= 0 || poll( &pfd, 1, timeout ) != 1)
+            {
+                FIXME( "window %p/%lx wait timed out\n", data->hwnd, data->whole_window );
+                break;
+            }
         }
     }
+    TRACE( "window %p/%lx state now %d\n", data->hwnd, data->whole_window, data->wm_state );
 }
 
 
diff --git a/dlls/winex11.drv/winpos.c b/dlls/winex11.drv/winpos.c
index b2f7a3f..e1e36dc 100644
--- a/dlls/winex11.drv/winpos.c
+++ b/dlls/winex11.drv/winpos.c
@@ -151,8 +151,8 @@ void X11DRV_SetWindowStyle( HWND hwnd, DWORD old_style )
             X11DRV_set_wm_hints( display, data );
             if (!data->mapped)
             {
-                TRACE( "mapping win %p\n", hwnd );
-                wait_for_withdrawn_state( display, data );
+                TRACE( "mapping win %p/%lx\n", hwnd, data->whole_window );
+                wait_for_withdrawn_state( display, data, TRUE );
                 X11DRV_sync_window_style( display, data );
                 wine_tsx11_lock();
                 XMapWindow( display, data->whole_window );
@@ -392,6 +392,7 @@ void X11DRV_SetWindowPos( HWND hwnd, HWND insert_after, UINT swp_flags,
     if (data->mapped && (!(new_style & WS_VISIBLE) || !X11DRV_is_window_rect_mapped( rectWindow )))
     {
         TRACE( "unmapping win %p/%lx\n", hwnd, data->whole_window );
+        wait_for_withdrawn_state( display, data, FALSE );
         wine_tsx11_lock();
         if (data->managed) XWithdrawWindow( display, data->whole_window, DefaultScreen(display) );
         else XUnmapWindow( display, data->whole_window );
@@ -413,7 +414,7 @@ void X11DRV_SetWindowPos( HWND hwnd, HWND insert_after, UINT swp_flags,
         if (!data->mapped)
         {
             TRACE( "mapping win %p/%lx\n", hwnd, data->whole_window );
-            wait_for_withdrawn_state( display, data );
+            wait_for_withdrawn_state( display, data, TRUE );
             X11DRV_sync_window_style( display, data );
             wine_tsx11_lock();
             XMapWindow( display, data->whole_window );
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index 59685e9..2ef2f1f 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -697,7 +697,7 @@ extern Drawable create_glxpixmap( Display *display, XVisualInfo *vis, Pixmap par
 extern void flush_gl_drawable( X11DRV_PDEVICE *physDev );
 
 extern int get_window_wm_state( Display *display, struct x11drv_win_data *data );
-extern void wait_for_withdrawn_state( Display *display, struct x11drv_win_data *data );
+extern void wait_for_withdrawn_state( Display *display, struct x11drv_win_data *data, BOOL set );
 
 /* X context to associate a hwnd to an X window */
 extern XContext winContext;




More information about the wine-cvs mailing list