mirror of
https://codeberg.org/dwl/dwl.git
synced 2026-11-03 20:02:23 +00:00
fix focustop(): prefer a visible fullscreen client
Problem (reproducible on vanilla 0.9, unrelated to any local patch): 1. fullscreen client A on tag 3 (MOD+e); 2. MOD+0 to view all tags; 3. MOD+1 to switch to tag 1, focus lands on client B; 4. MOD+0 again: client A is displayed fullscreen, covering everything, but the focused client is the invisible B; 5. so MOD+e / MOD+q act on B behind A and the user thinks MOD+e does not work on A until A is clicked with the mouse. Root cause: focustop() returns the first VISIBLEON() client on the fstack, but VISIBLEON() only checks whether the client is on a currently visible tag; it does not check whether the client is covered by a fullscreen client. When switching back to tag 0, the last focused client B is first on the fstack, so B gets the focus while A is still displayed fullscreen. Fix: focustop() first looks for a visible fullscreen client on the fstack (at most one fullscreen client per monitor is actually shown, and it always sits on top, covering the whole monitor), and only falls back to the previous "first visible client" if there is none. As a result: - after a tag switch the focus goes back to the fullscreen client that actually occupies the screen, so MOD+e / MOD+q behave as expected; - the fullscreen_bg decision in arrange() is fixed as a side effect (it used to be turned off when the focus was not on the fullscreen client, so a non-opaque fullscreen surface could reveal other clients behind it, which violates the protocol); - focusstack() already returns early when the focused client is fullscreen, so MOD+j/k and the arrow keys no longer move the focus to a covered client either. Verified with headless dwl, two foot clients and keys injected through zwp_virtual_keyboard_v1: before the fix the last step gives focal = winB / fullscreen 0; after the fix focal = winA / fullscreen 1, and MOD+e then restores A as expected. ta: 20261031_022753
This commit is contained in:
@@ -1700,10 +1700,14 @@ Client *
|
|||||||
focustop(Monitor *m)
|
focustop(Monitor *m)
|
||||||
{
|
{
|
||||||
Client *c;
|
Client *c;
|
||||||
wl_list_for_each(c, &fstack, flink) {
|
|
||||||
|
wl_list_for_each(c, &fstack, flink)
|
||||||
|
if (VISIBLEON(c, m) && c->isfullscreen)
|
||||||
|
return c;
|
||||||
|
|
||||||
|
wl_list_for_each(c, &fstack, flink)
|
||||||
if (VISIBLEON(c, m))
|
if (VISIBLEON(c, m))
|
||||||
return c;
|
return c;
|
||||||
}
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user