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

oldstable
Alexandre Julliard 2008-03-05 16:52:22 +01:00
parent 3b6f95c663
commit d0e14bf709
3 changed files with 26 additions and 20 deletions

View File

@ -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 ))
TRACE( "waiting for window %p/%lx to become %swithdrawn\n",
data->hwnd, data->whole_window, set ? "" : "not " );
while (data->whole_window && ((data->wm_state == WithdrawnState) == !set))
{
struct pollfd pfd;
int timeout = end - GetTickCount();
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)
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 );
}

View File

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

View File

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