This completely refactors the winex11 window state tracking, keeping track of the desired/pending/current window state and config in a fully asynchronous way, and avoiding duplicate requests. I believe this mitigates various race conditions that we're suffering from, solving most spurious event feedback loops when the X11 state is being applied while some win32 state change is being requested, and fixing the spurious d3d/ddraw/user32 test failures.
-- v8: winex11: Request window state updates asynchronously. winex11: Update the window client config on window state changes. winex11: Wait for pending ConfigureNotify before updating the client state. winex11: Wait for pending _NET_WM_STATE before updating the client state. winex11: Don't expect WM_STATE events on override-redirect windows. winex11: Listen to PropertyNotify events on the virtual desktop window.
From: Rémi Bernon rbernon@codeweavers.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=57423 --- dlls/winex11.drv/desktop.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/dlls/winex11.drv/desktop.c b/dlls/winex11.drv/desktop.c index dae0d652737..39e904dc7ee 100644 --- a/dlls/winex11.drv/desktop.c +++ b/dlls/winex11.drv/desktop.c @@ -73,7 +73,8 @@ BOOL X11DRV_CreateDesktop( const WCHAR *name, UINT width, UINT height )
/* Create window */ win_attr.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask | EnterWindowMask | - PointerMotionMask | ButtonPressMask | ButtonReleaseMask | FocusChangeMask; + PointerMotionMask | ButtonPressMask | ButtonReleaseMask | FocusChangeMask | + PropertyChangeMask; win_attr.cursor = XCreateFontCursor( display, XC_top_left_arrow );
if (default_visual.visual != DefaultVisual( display, DefaultScreen(display) ))
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/window.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index bd13761aff4..66a78e868ec 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -1438,6 +1438,9 @@ static void window_set_wm_state( struct x11drv_win_data *data, UINT new_state ) if (!data->embedded) XIconifyWindow( data->display, data->whole_window, data->vis.screen ); break; } + + /* override redirect windows won't receive WM_STATE property changes */ + if (!data->managed) data->wm_state_serial = 0; }
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/event.c | 10 +++++++++- dlls/winex11.drv/window.c | 3 +++ 2 files changed, 12 insertions(+), 1 deletion(-)
diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c index 82e82e6bc71..7a9626b4542 100644 --- a/dlls/winex11.drv/event.c +++ b/dlls/winex11.drv/event.c @@ -1247,12 +1247,20 @@ static void handle_xembed_info_notify( HWND hwnd, XPropertyEvent *event ) static void handle_net_wm_state_notify( HWND hwnd, XPropertyEvent *event ) { struct x11drv_win_data *data; - UINT value = 0; + UINT value = 0, state_cmd = 0;
if (!(data = get_win_data( hwnd ))) return; if (event->state == PropertyNewValue) value = get_window_net_wm_state( event->display, event->window ); window_net_wm_state_notify( data, event->serial, value ); + + state_cmd = window_update_client_state( data ); release_win_data( data ); + + if (state_cmd) + { + if (LOWORD(state_cmd) == SC_RESTORE && HIWORD(state_cmd)) NtUserSetActiveWindow( hwnd ); + send_message( hwnd, WM_SYSCOMMAND, LOWORD(state_cmd), 0 ); + } }
/*********************************************************************** diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index 66a78e868ec..53220120fb0 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -1503,6 +1503,9 @@ UINT window_update_client_state( struct x11drv_win_data *data ) if (!data->managed) return 0; /* unmanaged windows are managed by the Win32 side */ if (!data->mapped) return 0; /* ignore state changes on invisible windows */
+ if (data->wm_state_serial) return 0; /* another WM_STATE update is pending, wait for it to complete */ + if (data->net_wm_state_serial) return 0; /* another _NET_WM_STATE update is pending, wait for it to complete */ + if (data->iconic && data->current_state.wm_state == NormalState) /* restore window */ { data->iconic = FALSE;
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/event.c | 11 +++++++++-- dlls/winex11.drv/window.c | 1 + 2 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c index 7a9626b4542..70836a887f0 100644 --- a/dlls/winex11.drv/event.c +++ b/dlls/winex11.drv/event.c @@ -1104,7 +1104,7 @@ static BOOL X11DRV_ConfigureNotify( HWND hwnd, XEvent *xev ) struct x11drv_win_data *data; RECT rect; POINT pos = {event->x, event->y}; - UINT config_cmd; + UINT config_cmd, state_cmd;
if (!hwnd) return FALSE; if (!(data = get_win_data( hwnd ))) return FALSE; @@ -1123,17 +1123,24 @@ static BOOL X11DRV_ConfigureNotify( HWND hwnd, XEvent *xev ) SetRect( &rect, pos.x, pos.y, pos.x + event->width, pos.y + event->height ); window_configure_notify( data, event->serial, &rect );
+ state_cmd = window_update_client_state( data ); config_cmd = window_update_client_config( data ); rect = window_rect_from_visible( &data->rects, data->current_state.rect ); release_win_data( data );
+ if (state_cmd) + { + if (LOWORD(state_cmd) == SC_RESTORE && HIWORD(state_cmd)) NtUserSetActiveWindow( hwnd ); + send_message( hwnd, WM_SYSCOMMAND, LOWORD(state_cmd), 0 ); + } + if (config_cmd) { if (LOWORD(config_cmd) == SC_MOVE) NtUserSetRawWindowPos( hwnd, rect, HIWORD(config_cmd), FALSE ); else send_message( hwnd, WM_SYSCOMMAND, LOWORD(config_cmd), 0 ); }
- return !!config_cmd; + return config_cmd || state_cmd; }
diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index 53220120fb0..7d504aecbcd 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -1505,6 +1505,7 @@ UINT window_update_client_state( struct x11drv_win_data *data )
if (data->wm_state_serial) return 0; /* another WM_STATE update is pending, wait for it to complete */ if (data->net_wm_state_serial) return 0; /* another _NET_WM_STATE update is pending, wait for it to complete */ + if (data->configure_serial) return 0; /* another config update is pending, wait for it to complete */
if (data->iconic && data->current_state.wm_state == NormalState) /* restore window */ {
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/event.c | 28 +++++++++++++++++++++++++--- dlls/winex11.drv/window.c | 2 ++ 2 files changed, 27 insertions(+), 3 deletions(-)
diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c index 70836a887f0..cc4869c4666 100644 --- a/dlls/winex11.drv/event.c +++ b/dlls/winex11.drv/event.c @@ -1203,7 +1203,8 @@ static int get_window_xembed_info( Display *display, Window window ) static void handle_wm_state_notify( HWND hwnd, XPropertyEvent *event, BOOL update_window ) { struct x11drv_win_data *data; - UINT value = 0, state_cmd = 0; + UINT value = 0, state_cmd = 0, config_cmd = 0; + RECT rect;
if (!(data = get_win_data( hwnd ))) return; if (event->state == PropertyNewValue) value = get_window_wm_state( event->display, event->window ); @@ -1229,7 +1230,12 @@ static void handle_wm_state_notify( HWND hwnd, XPropertyEvent *event, BOOL updat break; }
- if (update_window) state_cmd = window_update_client_state( data ); + if (update_window) + { + state_cmd = window_update_client_state( data ); + config_cmd = window_update_client_config( data ); + rect = window_rect_from_visible( &data->rects, data->current_state.rect ); + }
release_win_data( data );
@@ -1238,6 +1244,12 @@ static void handle_wm_state_notify( HWND hwnd, XPropertyEvent *event, BOOL updat if (LOWORD(state_cmd) == SC_RESTORE && HIWORD(state_cmd)) NtUserSetActiveWindow( hwnd ); send_message( hwnd, WM_SYSCOMMAND, LOWORD(state_cmd), 0 ); } + + if (config_cmd) + { + if (LOWORD(config_cmd) == SC_MOVE) NtUserSetRawWindowPos( hwnd, rect, HIWORD(config_cmd), FALSE ); + else send_message( hwnd, WM_SYSCOMMAND, LOWORD(config_cmd), 0 ); + } }
static void handle_xembed_info_notify( HWND hwnd, XPropertyEvent *event ) @@ -1254,13 +1266,17 @@ static void handle_xembed_info_notify( HWND hwnd, XPropertyEvent *event ) static void handle_net_wm_state_notify( HWND hwnd, XPropertyEvent *event ) { struct x11drv_win_data *data; - UINT value = 0, state_cmd = 0; + UINT value = 0, state_cmd = 0, config_cmd = 0; + RECT rect;
if (!(data = get_win_data( hwnd ))) return; if (event->state == PropertyNewValue) value = get_window_net_wm_state( event->display, event->window ); window_net_wm_state_notify( data, event->serial, value );
state_cmd = window_update_client_state( data ); + config_cmd = window_update_client_config( data ); + rect = window_rect_from_visible( &data->rects, data->current_state.rect ); + release_win_data( data );
if (state_cmd) @@ -1268,6 +1284,12 @@ static void handle_net_wm_state_notify( HWND hwnd, XPropertyEvent *event ) if (LOWORD(state_cmd) == SC_RESTORE && HIWORD(state_cmd)) NtUserSetActiveWindow( hwnd ); send_message( hwnd, WM_SYSCOMMAND, LOWORD(state_cmd), 0 ); } + + if (config_cmd) + { + if (LOWORD(config_cmd) == SC_MOVE) NtUserSetRawWindowPos( hwnd, rect, HIWORD(config_cmd), FALSE ); + else send_message( hwnd, WM_SYSCOMMAND, LOWORD(config_cmd), 0 ); + } }
/*********************************************************************** diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index 7d504aecbcd..4bbf71b7780 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -1547,6 +1547,8 @@ UINT window_update_client_config( struct x11drv_win_data *data ) if (!data->mapped) return 0; /* ignore config changes on invisible windows */ if (data->iconic) return 0; /* ignore config changes on minimized windows */
+ if (data->wm_state_serial) return 0; /* another WM_STATE update is pending, wait for it to complete */ + if (data->net_wm_state_serial) return 0; /* another _NET_WM_STATE update is pending, wait for it to complete */ if (data->configure_serial) return 0; /* another config update is pending, wait for it to complete */
if ((old_style & WS_CAPTION) == WS_CAPTION || !data->is_fullscreen)
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/event.c | 101 +++----------------------------------- dlls/winex11.drv/window.c | 41 +++++++++++----- dlls/winex11.drv/x11drv.h | 3 +- 3 files changed, 35 insertions(+), 110 deletions(-)
diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c index cc4869c4666..0a91148acde 100644 --- a/dlls/winex11.drv/event.c +++ b/dlls/winex11.drv/event.c @@ -1200,7 +1200,7 @@ static int get_window_xembed_info( Display *display, Window window ) * * Handle a PropertyNotify for WM_STATE. */ -static void handle_wm_state_notify( HWND hwnd, XPropertyEvent *event, BOOL update_window ) +static void handle_wm_state_notify( HWND hwnd, XPropertyEvent *event ) { struct x11drv_win_data *data; UINT value = 0, state_cmd = 0, config_cmd = 0; @@ -1208,34 +1208,11 @@ static void handle_wm_state_notify( HWND hwnd, XPropertyEvent *event, BOOL updat
if (!(data = get_win_data( hwnd ))) return; if (event->state == PropertyNewValue) value = get_window_wm_state( event->display, event->window ); - if (update_window) window_wm_state_notify( data, event->serial, value ); + window_wm_state_notify( data, event->serial, value );
- switch(event->state) - { - case PropertyDelete: - TRACE( "%p/%lx: WM_STATE deleted from %d\n", data->hwnd, data->whole_window, data->wm_state ); - data->wm_state = WithdrawnState; - break; - case PropertyNewValue: - { - int old_state = data->wm_state; - int new_state = get_window_wm_state( event->display, data->whole_window ); - if (new_state != -1 && new_state != data->wm_state) - { - TRACE( "%p/%lx: new WM_STATE %d from %d\n", - data->hwnd, data->whole_window, new_state, old_state ); - data->wm_state = new_state; - } - } - break; - } - - if (update_window) - { - state_cmd = window_update_client_state( data ); - config_cmd = window_update_client_config( data ); - rect = window_rect_from_visible( &data->rects, data->current_state.rect ); - } + state_cmd = window_update_client_state( data ); + config_cmd = window_update_client_config( data ); + rect = window_rect_from_visible( &data->rects, data->current_state.rect );
release_win_data( data );
@@ -1300,79 +1277,13 @@ static BOOL X11DRV_PropertyNotify( HWND hwnd, XEvent *xev ) XPropertyEvent *event = &xev->xproperty;
if (!hwnd) return FALSE; - if (event->atom == x11drv_atom(WM_STATE)) handle_wm_state_notify( hwnd, event, TRUE ); + if (event->atom == x11drv_atom(WM_STATE)) handle_wm_state_notify( hwnd, event ); if (event->atom == x11drv_atom(_XEMBED_INFO)) handle_xembed_info_notify( hwnd, event ); if (event->atom == x11drv_atom(_NET_WM_STATE)) handle_net_wm_state_notify( hwnd, event ); return TRUE; }
-/* 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 ) -{ - 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( HWND hwnd, BOOL set ) -{ - Display *display = thread_display(); - struct x11drv_win_data *data; - DWORD end = NtGetTickCount() + 2000; - - TRACE( "waiting for window %p to become %swithdrawn\n", hwnd, set ? "" : "not " ); - - for (;;) - { - XEvent event; - Window window; - int count = 0; - - if (!(data = get_win_data( hwnd ))) break; - if (!data->managed || data->embedded || data->display != display) break; - if (!(window = data->whole_window)) break; - if (!data->mapped == !set) - { - TRACE( "window %p/%lx now %smapped\n", hwnd, window, data->mapped ? "" : "un" ); - break; - } - if ((data->wm_state == WithdrawnState) != !set) - { - TRACE( "window %p/%lx state now %d\n", hwnd, window, data->wm_state ); - break; - } - release_win_data( data ); - - while (XCheckIfEvent( display, &event, is_wm_state_notify, (char *)window )) - { - count++; - if (XFilterEvent( &event, None )) continue; /* filtered, ignore it */ - if (event.type == DestroyNotify) call_event_handler( display, &event ); - else handle_wm_state_notify( hwnd, &event.xproperty, FALSE ); - } - - if (!count) - { - struct pollfd pfd; - int timeout = end - NtGetTickCount(); - - pfd.fd = ConnectionNumber(display); - pfd.events = POLLIN; - if (timeout <= 0 || poll( &pfd, 1, timeout ) != 1) - { - FIXME( "window %p/%lx wait timed out\n", hwnd, window ); - return; - } - } - } - release_win_data( data ); -} - - /***************************************************************** * SetFocus (X11DRV.@) * diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index 4bbf71b7780..2beb0853c7d 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -1213,7 +1213,10 @@ static void window_set_net_wm_state( struct x11drv_win_data *data, UINT new_stat { UINT i, count, old_state = data->pending_state.net_wm_state;
+ data->desired_state.net_wm_state = new_state; if (!data->whole_window) return; /* no window, nothing to update */ + if (data->wm_state_serial) return; /* another WM_STATE update is pending, wait for it to complete */ + /* we ignore and override previous _NET_WM_STATE update requests */ if (old_state == new_state) return; /* states are the same, nothing to update */
if (data->pending_state.wm_state == IconicState) return; /* window is iconic, don't update its state now */ @@ -1267,6 +1270,8 @@ static void window_set_net_wm_state( struct x11drv_win_data *data, UINT new_stat SubstructureRedirectMask | SubstructureNotifyMask, &xev ); } } + + XFlush( data->display ); }
static void window_set_config( struct x11drv_win_data *data, const RECT *new_rect, BOOL above ) @@ -1275,6 +1280,7 @@ static void window_set_config( struct x11drv_win_data *data, const RECT *new_rec const RECT *old_rect = &data->pending_state.rect; XWindowChanges changes;
+ data->desired_state.rect = *new_rect; if (!data->whole_window) return; /* no window, nothing to update */ if (EqualRect( old_rect, new_rect )) return; /* rects are the same, nothing to update */
@@ -1328,7 +1334,7 @@ static void update_net_wm_states( struct x11drv_win_data *data )
style = NtUserGetWindowLongW( data->hwnd, GWL_STYLE ); if (style & WS_MINIMIZE) - new_state |= data->pending_state.net_wm_state & ((1 << NET_WM_STATE_FULLSCREEN)|(1 << NET_WM_STATE_MAXIMIZED)); + new_state |= data->desired_state.net_wm_state & ((1 << NET_WM_STATE_FULLSCREEN)|(1 << NET_WM_STATE_MAXIMIZED)); if (data->is_fullscreen) { if ((style & WS_MAXIMIZE) && (style & WS_CAPTION) == WS_CAPTION) @@ -1412,7 +1418,9 @@ static void window_set_wm_state( struct x11drv_win_data *data, UINT new_state ) { UINT old_state = data->pending_state.wm_state;
+ data->desired_state.wm_state = new_state; if (!data->whole_window) return; /* no window, nothing to update */ + if (data->wm_state_serial) return; /* another WM_STATE update is pending, wait for it to complete */ if (old_state == new_state) return; /* states are the same, nothing to update */
data->pending_state.wm_state = new_state; @@ -1441,6 +1449,8 @@ static void window_set_wm_state( struct x11drv_win_data *data, UINT new_state )
/* override redirect windows won't receive WM_STATE property changes */ if (!data->managed) data->wm_state_serial = 0; + + XFlush( data->display ); }
@@ -1452,7 +1462,6 @@ static void map_window( HWND hwnd, DWORD new_style ) struct x11drv_win_data *data;
make_owner_managed( hwnd ); - wait_for_withdrawn_state( hwnd, TRUE );
if (!(data = get_win_data( hwnd ))) return;
@@ -1466,7 +1475,6 @@ static void map_window( HWND hwnd, DWORD new_style ) sync_window_style( data );
window_set_wm_state( data, (new_style & WS_MINIMIZE) ? IconicState : NormalState ); - XFlush( data->display );
data->mapped = TRUE; data->iconic = (new_style & WS_MINIMIZE) != 0; @@ -1483,8 +1491,6 @@ static void unmap_window( HWND hwnd ) { struct x11drv_win_data *data;
- wait_for_withdrawn_state( hwnd, FALSE ); - if (!(data = get_win_data( hwnd ))) return;
if (data->mapped) @@ -1581,7 +1587,7 @@ UINT window_update_client_config( struct x11drv_win_data *data )
void window_wm_state_notify( struct x11drv_win_data *data, unsigned long serial, UINT value ) { - UINT *pending = &data->pending_state.wm_state, *current = &data->current_state.wm_state; + UINT *desired = &data->desired_state.wm_state, *pending = &data->pending_state.wm_state, *current = &data->current_state.wm_state; unsigned long *expect_serial = &data->wm_state_serial; const char *reason = NULL, *expected, *received;
@@ -1606,16 +1612,20 @@ void window_wm_state_notify( struct x11drv_win_data *data, unsigned long serial, else { WARN( "window %p/%lx, %s%s%s\n", data->hwnd, data->whole_window, reason, received, expected ); - *pending = value; /* avoid requesting the same state again */ + *desired = *pending = value; /* avoid requesting the same state again */ }
*current = value; *expect_serial = 0; + + /* send any pending changes from the desired state */ + window_set_wm_state( data, data->desired_state.wm_state ); + window_set_net_wm_state( data, data->desired_state.net_wm_state ); }
void window_net_wm_state_notify( struct x11drv_win_data *data, unsigned long serial, UINT value ) { - UINT *pending = &data->pending_state.net_wm_state, *current = &data->current_state.net_wm_state; + UINT *desired = &data->desired_state.net_wm_state, *pending = &data->pending_state.net_wm_state, *current = &data->current_state.net_wm_state; unsigned long *expect_serial = &data->net_wm_state_serial; const char *reason = NULL, *expected, *received;
@@ -1638,16 +1648,20 @@ void window_net_wm_state_notify( struct x11drv_win_data *data, unsigned long ser else { WARN( "window %p/%lx, %s%s%s\n", data->hwnd, data->whole_window, reason, received, expected ); - *pending = value; /* avoid requesting the same state again */ + *desired = *pending = value; /* avoid requesting the same state again */ }
*current = value; *expect_serial = 0; + + /* send any pending changes from the desired state */ + window_set_wm_state( data, data->desired_state.wm_state ); + window_set_net_wm_state( data, data->desired_state.net_wm_state ); }
void window_configure_notify( struct x11drv_win_data *data, unsigned long serial, const RECT *value ) { - RECT *pending = &data->pending_state.rect, *current = &data->current_state.rect; + RECT *desired = &data->desired_state.rect, *pending = &data->pending_state.rect, *current = &data->current_state.rect; unsigned long *expect_serial = &data->configure_serial; const char *reason = NULL, *expected, *received;
@@ -1670,7 +1684,7 @@ void window_configure_notify( struct x11drv_win_data *data, unsigned long serial else { WARN( "window %p/%lx, %s%s%s\n", data->hwnd, data->whole_window, reason, received, expected ); - *pending = *value; /* avoid requesting the same state again */ + *desired = *pending = *value; /* avoid requesting the same state again */ }
*current = *value; @@ -1683,7 +1697,7 @@ BOOL window_has_pending_wm_state( HWND hwnd, UINT state ) BOOL pending;
if (!(data = get_win_data( hwnd ))) return FALSE; - if (state != -1 && data->pending_state.wm_state != state) pending = FALSE; + if (state != -1 && data->desired_state.wm_state != state) pending = FALSE; else pending = !!data->wm_state_serial; release_win_data( data );
@@ -2053,6 +2067,7 @@ static void create_whole_window( struct x11drv_win_data *data ) if (!data->whole_window) goto done; SetRect( &data->current_state.rect, pos.x, pos.y, pos.x + cx, pos.y + cy ); data->pending_state.rect = data->current_state.rect; + data->desired_state.rect = data->current_state.rect;
x11drv_xinput2_enable( data->display, data->whole_window ); set_initial_wm_hints( data->display, data->whole_window ); @@ -2107,9 +2122,9 @@ static void destroy_whole_window( struct x11drv_win_data *data, BOOL already_des if (data->whole_colormap) XFreeColormap( data->display, data->whole_colormap ); data->whole_window = data->client_window = 0; data->whole_colormap = 0; - data->wm_state = WithdrawnState; data->mapped = FALSE;
+ memset( &data->desired_state, 0, sizeof(data->desired_state) ); memset( &data->pending_state, 0, sizeof(data->pending_state) ); memset( &data->current_state, 0, sizeof(data->current_state) ); data->wm_state_serial = 0; diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index fbaa416c617..38503667f23 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -633,13 +633,13 @@ struct x11drv_win_data UINT net_wm_fullscreen_monitors_set : 1; /* is _NET_WM_FULLSCREEN_MONITORS set */ UINT is_fullscreen : 1; /* is the window visible rect fullscreen */ UINT parent_invalid : 1; /* is the parent host window possibly invalid */ - int wm_state; /* current value of the WM_STATE property */ Window embedder; /* window id of embedder */ Pixmap icon_pixmap; Pixmap icon_mask; unsigned long *icon_bits; unsigned int icon_size;
+ struct window_state desired_state; /* window state tracking the desired / win32 state */ struct window_state pending_state; /* window state tracking the pending / requested state */ struct window_state current_state; /* window state tracking the current X11 state */ unsigned long wm_state_serial; /* serial of last pending WM_STATE request */ @@ -665,7 +665,6 @@ extern void window_configure_notify( struct x11drv_win_data *data, unsigned long extern UINT window_update_client_state( struct x11drv_win_data *data ); extern UINT window_update_client_config( struct x11drv_win_data *data );
-extern void wait_for_withdrawn_state( HWND hwnd, BOOL set ); extern Window init_clip_window(void); extern void update_user_time( Time time ); extern UINT get_window_net_wm_state( Display *display, Window window );