Closed Plagman closed 3 years ago
Probably shouldn't focus any of these things as primary if there's an alternative: _NET_WM_STATE_ABOVE, _NET_WM_STATE_SKIP_PAGER, _NET_WM_STATE_SKIP_TASKBAR
I think a good first step would just be a commit that tracks the three states above from _NET_WM_STATE and keeps them as Bools in the window structures.
wlroots code deciding whether an override-redirect window wants focus:
https://github.com/swaywm/wlroots/blob/b0144c7ded2b655085eb8e7e9b64908dc9420d60/xwayland/xwm.c#L1942
Hmm. Looks like we completely overwrite _NET_WM_STATE
: https://github.com/Plagman/gamescope/blob/cd31090733c0517ce786bcb32574d42daa81130f/src/steamcompmgr.cpp#L552
Ah whoops - probably wasn't a problem before we started wanting to care about it. This was more definitely intended to OR the hidden bit into the current window state.
This line might be responsible for the focus stealing:
All of this probably happens because the Windows client sets WS_EX_NOACTIVATE
:
if (ex_style & (WS_EX_TOOLWINDOW | WS_EX_NOACTIVATE))
new_state |= (1 << NET_WM_STATE_SKIP_TASKBAR) | (1 << NET_WM_STATE_SKIP_PAGER);
Wine will try to re-focus the parent window (then falling back to the currently active window, then falling back to the last focused window) when a WS_EX_NOACTIVATE
window gets focus:
/* try to find some other window to give the focus to */
hwnd = GetFocus();
if (hwnd) hwnd = GetAncestor( hwnd, GA_ROOT );
if (!hwnd) hwnd = GetActiveWindow();
if (!hwnd) hwnd = last_focus;
if (hwnd && can_activate_window(hwnd)) set_focus( event->display, hwnd, event_time );
Trying to summarize offline discussion: should winex11 set an 'extension' property for the WM indicating WS_EX_NOACTIVATE, given there's no strict equivalent on the Linux side? I'm guessing other WMs could actually make use of it too. That would let us to 'the right thing' and ignore it for input focus when it comes in, and not try to do a heuristic based on other attributes it might have.
Okay, I just had another idea: maybe we should listen to focus changes requested by the client and bump the focus priority based on that? So basically, if the client manually focuses a window, set a requestFocus
field and use this in determine_and_apply_focus
.
Hmm. Actually Wine should just change the focus behind the XWM's back when getting FocusIn for the achievement popup. gamescope doesn't listen to FocusIn events, so shouldn't interfere with the focus change. So I'm not sure why this bug happens.
Some WINEDEBUG=trace+x11drv,trace+event
(plus gamescope -F
) logs would be helpful.
Output when running focus debug mode: