From: Rémi Bernon rbernon@codeweavers.com
Or if a message needs to be sent to the window manager instead. The pending_state tracks the last state request, whereas data->mapped now matches the desired_state value, which may have been delayed. --- dlls/winex11.drv/window.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index 2beb0853c7d..6267e378deb 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -1187,7 +1187,7 @@ static void update_net_wm_fullscreen_monitors( struct x11drv_win_data *data ) && !data->net_wm_fullscreen_monitors_set) return;
- if (!data->mapped) + if (data->pending_state.wm_state == WithdrawnState) { XChangeProperty( data->display, data->whole_window, x11drv_atom(_NET_WM_FULLSCREEN_MONITORS), XA_CARDINAL, 32, PropModeReplace, (unsigned char *)monitors, 4 ); @@ -1220,7 +1220,7 @@ static void window_set_net_wm_state( struct x11drv_win_data *data, UINT new_stat 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 */ - if (!data->mapped) /* set the _NET_WM_STATE atom directly */ + if (data->pending_state.wm_state == WithdrawnState) /* set the _NET_WM_STATE atom directly */ { Atom atoms[NB_NET_WM_STATES + 1];
@@ -3371,7 +3371,7 @@ void X11DRV_FlashWindowEx( FLASHWINFO *pfinfo ) if (!data) return;
- if (data->mapped) + if (data->pending_state.wm_state != WithdrawnState) { xev.type = ClientMessage; xev.xclient.window = data->whole_window;
From: Rémi Bernon rbernon@codeweavers.com
The state is now requested asynchronously, and window_set_wm_state may delay the request if another is in flight. We need to wait until the state is actually requested before updating the other window properties. --- dlls/winex11.drv/window.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-)
diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index 6267e378deb..193fecb9847 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -1423,6 +1423,22 @@ static void window_set_wm_state( struct x11drv_win_data *data, UINT new_state ) 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 */
+ switch (MAKELONG(old_state, new_state)) + { + case MAKELONG(WithdrawnState, IconicState): + case MAKELONG(WithdrawnState, NormalState): + remove_startup_notification( data->display, data->whole_window ); + set_wm_hints( data ); + update_net_wm_states( data ); + sync_window_style( data ); + update_net_wm_fullscreen_monitors( data ); + break; + case MAKELONG(IconicState, NormalState): + case MAKELONG(NormalState, IconicState): + set_wm_hints( data ); + break; + } + data->pending_state.wm_state = new_state; data->wm_state_serial = NextRequest( data->display ); TRACE( "window %p/%lx, requesting WM_STATE %#x -> %#x serial %lu, foreground %p\n", data->hwnd, data->whole_window, @@ -1468,17 +1484,9 @@ static void map_window( HWND hwnd, DWORD new_style ) if (data->whole_window && !data->mapped) { TRACE( "win %p/%lx\n", data->hwnd, data->whole_window ); - - remove_startup_notification( data->display, data->whole_window ); - set_wm_hints( data ); - update_net_wm_states( data ); - sync_window_style( data ); - window_set_wm_state( data, (new_style & WS_MINIMIZE) ? IconicState : NormalState ); - data->mapped = TRUE; data->iconic = (new_style & WS_MINIMIZE) != 0; - update_net_wm_fullscreen_monitors( data ); } release_win_data( data ); } @@ -1713,7 +1721,6 @@ void make_window_embedded( struct x11drv_win_data *data ) window_set_wm_state( data, WithdrawnState ); data->embedded = TRUE; data->managed = TRUE; - sync_window_style( data ); window_set_wm_state( data, NormalState ); }
@@ -2975,7 +2982,6 @@ void X11DRV_WindowPosChanged( HWND hwnd, HWND insert_after, HWND owner_hint, UIN } else if ((swp_flags & SWP_STATECHANGED) && (!data->iconic != !(new_style & WS_MINIMIZE))) { - set_wm_hints( data ); data->iconic = (new_style & WS_MINIMIZE) != 0; window_set_wm_state( data, (new_style & WS_MINIMIZE) ? IconicState : NormalState ); update_net_wm_states( data );
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/window.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index 193fecb9847..baa053ef601 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -2526,17 +2526,19 @@ void X11DRV_SystrayDockClear( HWND hwnd ) BOOL X11DRV_SystrayDockRemove( HWND hwnd ) { struct x11drv_win_data *data; - BOOL ret; + BOOL ret = FALSE;
- /* make sure we don't try to unmap it, it confuses some systray docks */ if ((data = get_win_data( hwnd ))) { - if ((ret = data->embedded)) data->mapped = FALSE; + if ((ret = data->embedded)) + { + window_set_wm_state( data, WithdrawnState ); + data->mapped = FALSE; + } release_win_data( data ); - return ret; }
- return FALSE; + return ret; }
From: Rémi Bernon rbernon@codeweavers.com
The new state tracker desired_state.wm_state can now be used instead. --- dlls/winex11.drv/window.c | 29 +++++++++++++++-------------- dlls/winex11.drv/x11drv.h | 1 - 2 files changed, 15 insertions(+), 15 deletions(-)
diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index baa053ef601..837aaacb25f 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -1486,7 +1486,6 @@ static void map_window( HWND hwnd, DWORD new_style ) TRACE( "win %p/%lx\n", data->hwnd, data->whole_window ); window_set_wm_state( data, (new_style & WS_MINIMIZE) ? IconicState : NormalState ); data->mapped = TRUE; - data->iconic = (new_style & WS_MINIMIZE) != 0; } release_win_data( data ); } @@ -1521,9 +1520,9 @@ UINT window_update_client_state( struct x11drv_win_data *data ) 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 */ + switch (MAKELONG(data->desired_state.wm_state, data->current_state.wm_state)) { - data->iconic = FALSE; + case MAKELONG(IconicState, NormalState): if ((old_style & WS_CAPTION) == WS_CAPTION && (data->current_state.net_wm_state & (1 << NET_WM_STATE_MAXIMIZED))) { if ((old_style & WS_MAXIMIZEBOX) && !(old_style & WS_DISABLED)) @@ -1538,15 +1537,14 @@ UINT window_update_client_state( struct x11drv_win_data *data ) TRACE( "restoring win %p/%lx\n", data->hwnd, data->whole_window ); return MAKELONG(SC_RESTORE, activate); } - } - else if (!data->iconic && data->current_state.wm_state == IconicState) - { - data->iconic = TRUE; + break; + case MAKELONG(NormalState, IconicState): if ((old_style & WS_MINIMIZEBOX) && !(old_style & WS_DISABLED)) { TRACE( "minimizing win %p/%lx\n", data->hwnd, data->whole_window ); return SC_MINIMIZE; } + break; }
return 0; @@ -1558,8 +1556,7 @@ UINT window_update_client_config( struct x11drv_win_data *data ) RECT rect, old_rect = data->rects.window, new_rect;
if (!data->managed) return 0; /* unmanaged windows are managed by the Win32 side */ - if (!data->mapped) return 0; /* ignore config changes on invisible windows */ - if (data->iconic) return 0; /* ignore config changes on minimized windows */ + if (data->desired_state.wm_state != NormalState) return 0; /* ignore config changes on invisible/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 */ @@ -1736,7 +1733,7 @@ static void sync_window_position( struct x11drv_win_data *data, UINT swp_flags ) DWORD ex_style = NtUserGetWindowLongW( data->hwnd, GWL_EXSTYLE ); BOOL above = FALSE;
- if (data->managed && data->iconic) return; + if (data->managed && data->desired_state.wm_state == IconicState) return;
if (!(swp_flags & SWP_NOZORDER) || (swp_flags & SWP_SHOWWINDOW)) { @@ -2889,13 +2886,18 @@ void X11DRV_WindowPosChanged( HWND hwnd, HWND insert_after, HWND owner_hint, UIN { struct x11drv_thread_data *thread_data; struct x11drv_win_data *data; - UINT new_style = NtUserGetWindowLongW( hwnd, GWL_STYLE ); + UINT new_style = NtUserGetWindowLongW( hwnd, GWL_STYLE ), old_style; struct window_rects old_rects; BOOL was_fullscreen; int event_type;
if (!(data = get_win_data( hwnd ))) return;
+ old_style = new_style & ~(WS_VISIBLE | WS_MINIMIZE | WS_MAXIMIZE); + if (data->desired_state.wm_state != WithdrawnState) old_style |= WS_VISIBLE; + if (data->desired_state.wm_state == IconicState) old_style |= WS_MINIMIZE; + if (data->desired_state.net_wm_state & (1 << NET_WM_STATE_MAXIMIZED)) old_style |= WS_MAXIMIZE; + thread_data = x11drv_thread_data();
old_rects = data->rects; @@ -2982,9 +2984,8 @@ void X11DRV_WindowPosChanged( HWND hwnd, HWND insert_after, HWND owner_hint, UIN if (needs_map) map_window( hwnd, new_style ); return; } - else if ((swp_flags & SWP_STATECHANGED) && (!data->iconic != !(new_style & WS_MINIMIZE))) + else if ((swp_flags & SWP_STATECHANGED) && ((old_style ^ new_style) & WS_MINIMIZE)) { - data->iconic = (new_style & WS_MINIMIZE) != 0; window_set_wm_state( data, (new_style & WS_MINIMIZE) ? IconicState : NormalState ); update_net_wm_states( data ); } @@ -3034,7 +3035,7 @@ UINT X11DRV_ShowWindow( HWND hwnd, INT cmd, RECT *rect, UINT swp ) } goto done; } - if (!data->managed || !data->mapped || data->iconic) goto done; + if (!data->managed || data->desired_state.wm_state != NormalState) goto done;
/* only fetch the new rectangle if the ShowWindow was a result of a window manager event */
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index 38503667f23..20f7e76bfe4 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -623,7 +623,6 @@ struct x11drv_win_data XIC xic; /* X input context */ UINT managed : 1; /* is window managed? */ UINT mapped : 1; /* is window mapped? (in either normal or iconic state) */ - UINT iconic : 1; /* is window in iconic state? */ UINT embedded : 1; /* is window an XEMBED client? */ UINT shaped : 1; /* is window using a custom region shape? */ UINT layered : 1; /* is window layered and with valid attributes? */
From: Rémi Bernon rbernon@codeweavers.com
The new state tracker desired_state.wm_state can now be used instead. --- dlls/winex11.drv/event.c | 2 +- dlls/winex11.drv/window.c | 37 +++++++++++-------------------------- dlls/winex11.drv/x11drv.h | 1 - 3 files changed, 12 insertions(+), 28 deletions(-)
diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c index 0a91148acde..7aaa1284164 100644 --- a/dlls/winex11.drv/event.c +++ b/dlls/winex11.drv/event.c @@ -1040,7 +1040,7 @@ static BOOL X11DRV_MapNotify( HWND hwnd, XEvent *event )
if (!(data = get_win_data( hwnd ))) return FALSE;
- if (!data->managed && !data->embedded && data->mapped) + if (!data->managed && !data->embedded && data->desired_state.wm_state != WithdrawnState) { HWND hwndFocus = get_focus(); if (hwndFocus && NtUserIsChild( hwnd, hwndFocus )) diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index 837aaacb25f..9e8164f873a 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -1480,13 +1480,8 @@ static void map_window( HWND hwnd, DWORD new_style ) make_owner_managed( hwnd );
if (!(data = get_win_data( hwnd ))) return; - - if (data->whole_window && !data->mapped) - { - TRACE( "win %p/%lx\n", data->hwnd, data->whole_window ); - window_set_wm_state( data, (new_style & WS_MINIMIZE) ? IconicState : NormalState ); - data->mapped = TRUE; - } + TRACE( "win %p/%lx\n", data->hwnd, data->whole_window ); + window_set_wm_state( data, (new_style & WS_MINIMIZE) ? IconicState : NormalState ); release_win_data( data ); }
@@ -1499,13 +1494,8 @@ static void unmap_window( HWND hwnd ) struct x11drv_win_data *data;
if (!(data = get_win_data( hwnd ))) return; - - if (data->mapped) - { - TRACE( "win %p/%lx\n", data->hwnd, data->whole_window ); - window_set_wm_state( data, WithdrawnState ); - data->mapped = FALSE; - } + TRACE( "win %p/%lx\n", data->hwnd, data->whole_window ); + window_set_wm_state( data, WithdrawnState ); release_win_data( data ); }
@@ -1514,7 +1504,7 @@ UINT window_update_client_state( struct x11drv_win_data *data ) UINT old_style = NtUserGetWindowLongW( data->hwnd, GWL_STYLE );
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->desired_state.wm_state == WithdrawnState) 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 */ @@ -2126,7 +2116,6 @@ 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->mapped = FALSE;
memset( &data->desired_state, 0, sizeof(data->desired_state) ); memset( &data->pending_state, 0, sizeof(data->pending_state) ); @@ -2527,11 +2516,7 @@ BOOL X11DRV_SystrayDockRemove( HWND hwnd )
if ((data = get_win_data( hwnd ))) { - if ((ret = data->embedded)) - { - window_set_wm_state( data, WithdrawnState ); - data->mapped = FALSE; - } + if ((ret = data->embedded)) window_set_wm_state( data, WithdrawnState ); release_win_data( data ); }
@@ -2934,7 +2919,7 @@ void X11DRV_WindowPosChanged( HWND hwnd, HWND insert_after, HWND owner_hint, UIN event_type = 0; /* ignore other events */ }
- if (data->mapped && event_type != ReparentNotify) + if ((old_style & WS_VISIBLE) && event_type != ReparentNotify) { if (((swp_flags & SWP_HIDEWINDOW) && !(new_style & WS_VISIBLE)) || (!event_type && !(new_style & WS_MINIMIZE) && @@ -2971,7 +2956,7 @@ void X11DRV_WindowPosChanged( HWND hwnd, HWND insert_after, HWND owner_hint, UIN if ((new_style & WS_VISIBLE) && ((new_style & WS_MINIMIZE) || is_window_rect_mapped( &new_rects->window ))) { - if (!data->mapped) + if (!(old_style & WS_VISIBLE)) { BOOL needs_icon = !data->icon_pixmap; BOOL needs_map = TRUE; @@ -3126,7 +3111,7 @@ void X11DRV_SetLayeredWindowAttributes( HWND hwnd, COLORREF key, BYTE alpha, DWO sync_window_opacity( data->display, data->whole_window, alpha, flags );
data->layered = TRUE; - if (!data->mapped) /* mapping is delayed until attributes are set */ + if (data->desired_state.wm_state == WithdrawnState) /* mapping is delayed until attributes are set */ { DWORD style = NtUserGetWindowLongW( data->hwnd, GWL_STYLE );
@@ -3162,7 +3147,7 @@ void X11DRV_UpdateLayeredWindow( HWND hwnd, UINT flags ) BOOL mapped;
if (!(data = get_win_data( hwnd ))) return; - mapped = data->mapped; + mapped = data->desired_state.wm_state != WithdrawnState; release_win_data( data );
/* layered windows are mapped only once their attributes are set */ @@ -3314,7 +3299,7 @@ LRESULT X11DRV_SysCommand( HWND hwnd, WPARAM wparam, LPARAM lparam ) if (wparam == SC_SCREENSAVE && hwnd == NtUserGetDesktopWindow()) return start_screensaver(); return -1; } - if (!data->whole_window || !data->managed || !data->mapped) goto failed; + if (!data->whole_window || !data->managed || data->desired_state.wm_state == WithdrawnState) goto failed;
switch (wparam & 0xfff0) { diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index 20f7e76bfe4..85cb4071866 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -622,7 +622,6 @@ struct x11drv_win_data struct host_window *parent; /* the host window parent, frame or embedder, NULL if root_window */ XIC xic; /* X input context */ UINT managed : 1; /* is window managed? */ - UINT mapped : 1; /* is window mapped? (in either normal or iconic state) */ UINT embedded : 1; /* is window an XEMBED client? */ UINT shaped : 1; /* is window using a custom region shape? */ UINT layered : 1; /* is window layered and with valid attributes? */