[PATCH v2 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 WindowPosChanged, 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. -- v2: winex11: Set net_active_window_serial when activating withdrawn windows. 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..1b069ca9cbe 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; @@ -2057,6 +2058,15 @@ void set_net_active_window( HWND hwnd, HWND previous ) data->pending_state.net_active_window = window; data->net_active_window_serial = NextRequest( data->display ); + + 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 serial %lu\n", hwnd, window, data->net_active_window_serial ); + XNoOp( data->display ); + return; + } + TRACE( "requesting _NET_ACTIVE_WINDOW %p/%lx serial %lu\n", hwnd, window, data->net_active_window_serial ); XSendEvent( data->display, DefaultRootWindow( data->display ), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev ); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9807
Fwiw after thinking about this, I think that there might be a muffin / marco bug in that the window doesn't get raised if it was previously requested to activate while it was withdrawn, but looking at mutter source (which the two are forked from, but which doesn't exhibit that bug), there's still no specific handling of withdrawn window right when _NET_ACTIVE_WINDOW request is received, so I think we should still avoid requesting activation of withdrawn windows in the first place. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/9807#note_125995
participants (2)
-
Rémi Bernon -
Rémi Bernon (@rbernon)