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 was added 4 years in ago in 8cdb997. New users won't understand
what "old behavior" refers to, so this line is confusing. And it is
self-evident that you should change the alpha value if you want
transparency.
Some monitors disconnect when they are turned off and reconnect shortly
after, and createmon() enabled them again. Remember the names of
the outputs turned off through output_power_management or
output_management and don't enable them in createmon().
Fixes https://codeberg.org/dwl/dwl/issues/719
While making them tiled on the first commit was needed to fix Firefox
starting with rounded corners, if you don't set them tiled again on map
resizing mpv after starting it with a rule that makes it floating
behaves wrong.
Fixes d1ebf3c.
Fixes https://codeberg.org/dwl/dwl/issues/1247.
This is not needed because focusclient() already calls
toplevel_from_wlr_surface(seat->keyboard_state.focused_surface) and can
check if that should have exclusive focus.
When it was added there was no function to get the focused layer shell
surface in this way.
Focusing a layer surface only set the keyboard focus, not the text-input
focus, so layer-shell clients (launchers, menus, ...) never received a
text-input enter event and IME input didn't work. Pass the layer surface
to focusclient() and set the input method focus there, like we already do
for regular clients.
It is the offset of the visible bounds inside the surface, which is not
zero for clients that pad their surface or place subsurfaces outside it,
so floating windows were mapped offset by their client side decorations.
Unmanaged clients spawned by a parent window, like menus, would not
close if the user changed workspace or focused another client while the
menu was selected, because the parent was never told that it lost the
focus. This remembers the last managed client and deactivates it on a
focus change, so that it closes the menu itself.
This also fixes a regression introduced by f6e3a28, where menus would
close immediately after being opened.
The dialogs opened by clicking items in Xwyland applications' toolbars
are unmanaged clients, so placing them in LyrFloat drew them below their
source client in LyrFS when it is fullscreened.
Add a new dedicated layer for unamanged clients to fix it. Don't put
them in LyrFS to prevent the regular fullscreen client from hiding
unmanaged ones, e.g. by opening dmenu and then clicking the regular
client.
Fixes https://codeberg.org/dwl/dwl/issues/556
Prevent a use-after-free when closing a nested dwl with Ctrl+c.
It happened because cleanup() → input_method_relay_finish() frees
input_method_relay, and then closemon() → focusclient() →
input_method_relay_set_focus() uses relay->surface.
When focusing an unmanaged client (like dmenu) or a layer shell surface
(like wmenu) keep the focused border color of the regular client, but
still deactivate it. This is consistent with dwm and sway.
This was already done for unmanaged clients but not for layer shell
surfaces.
This is not perfect because you can press MODKEY+j/k or move the cursor
while a program like dmenu is focused and have 2 clients with focused
border color after closing dmenu. But this doesn't work well even in
sway where if you change focus while dmenu is open you can longer focus
it, and after closing a layer shell surface with on-demand keyboard
interactivity all toplevels have the focused border color, so this will
do for now.