[PATCH 0/1] MR9807: winex11: Set net_active_window_serial when activating withdrawn windows.
The workaround to avoid breaking Cinnamon / Muffin caused some logic change, where GetWindowStateUpdates started returning the previously active window as foreground, as there's no _NET_ACTIVE_WINDOW pending request being recorded anymore. If GetWindowStateUpdates gets called after the window activation request but before its mapping is requested from WindowStateChanged, it would change the Win32 foreground window too, causing spurious focus loss. Fixes: c8422a619b46d25e55907fd5526b1d9fae8c3943 This was actually caught in the original MR with some ddraw tests, and it is more generally causing failures in the nightly test runs. We can alternatively revert the change, as this is arguably a Muffin bug that other WMs don't suffer from. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/9807
From: Rémi Bernon <rbernon@codeweavers.com> The workaround to avoid breaking Cinnamon / Muffin caused some logic change, where GetWindowStateUpdates started returning the previously active window as foreground, as there's no _NET_ACTIVE_WINDOW pending request being recorded anymore. If GetWindowStateUpdates gets called after the window activation request but before its mapping is requested from WindowStateChanged, it would change the Win32 foreground window too, causing spurious focus loss. Fixes: c8422a619b46d25e55907fd5526b1d9fae8c3943 --- dlls/winex11.drv/window.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index ed493389260..d06cd975c6d 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -2018,14 +2018,14 @@ void net_active_window_init( struct x11drv_thread_data *data ) data->current_state.net_active_window = window; } -static BOOL window_set_pending_activate( HWND hwnd ) +static BOOL window_set_pending_activate( HWND hwnd, BOOL *withdrawn ) { struct x11drv_win_data *data; BOOL pending; if (!(data = get_win_data( hwnd ))) return FALSE; if ((pending = !!data->wm_state_serial)) data->pending_state.activate = TRUE; - if (data->pending_state.wm_state == WithdrawnState) pending = TRUE; + *withdrawn = data->pending_state.wm_state == WithdrawnState; release_win_data( data ); return pending; @@ -2034,13 +2034,14 @@ static BOOL window_set_pending_activate( HWND hwnd ) void set_net_active_window( HWND hwnd, HWND previous ) { struct x11drv_thread_data *data = x11drv_thread_data(); + BOOL withdrawn = FALSE; Window window; XEvent xev; if (!is_net_supported( x11drv_atom(_NET_ACTIVE_WINDOW) )) return; if (!(window = X11DRV_get_whole_window( hwnd ))) return; if (data->pending_state.net_active_window == window) return; - if (window_set_pending_activate( hwnd )) return; + if (window_set_pending_activate( hwnd, &withdrawn )) return; xev.xclient.type = ClientMessage; xev.xclient.window = window; @@ -2055,6 +2056,15 @@ void set_net_active_window( HWND hwnd, HWND previous ) xev.xclient.data.l[3] = 0; xev.xclient.data.l[4] = 0; + if (withdrawn) + { + /* workaround requesting activation of withdrawn windows which breaks some WM, assume the window will soon be mapped */ + WARN( "skipping _NET_ACTIVE_WINDOW for withdrawn window %p/%lx\n", hwnd, window ); + data->pending_state.net_active_window = window; + data->net_active_window_serial = -1; + return; + } + data->pending_state.net_active_window = window; data->net_active_window_serial = NextRequest( data->display ); TRACE( "requesting _NET_ACTIVE_WINDOW %p/%lx serial %lu\n", hwnd, window, data->net_active_window_serial ); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9807
participants (2)
-
Rémi Bernon -
Rémi Bernon (@rbernon)