Commit Graph
1426 Commits
Author SHA1 Message Date
Guido Cella ab62e274ab Merge branch 'main' into wlroots-next 2026-11-11 11:18:41 +01:00
Guido Cella efbe686e63 remove LISTEN_STATIC
It's only used in createidleinhibitor().
2026-11-11 11:13:53 +01:00
Guido Cella 3732d4cea1 Merge branch 'main' into wlroots-next 2026-11-11 11:10:32 +01:00
dvh 568d047595 don't keep outputs unplugged while off in offmons
When an output was unplugged while turned off (e.g. by swayidle), only the
remaining ones were turned on again, and the unplugged one stayed in
offmons, so it stayed off when plugged in again. Forget the outputs that
are no longer connected whenever one is turned on.
2026-11-11 10:54:13 +01:00
dvh 8df3f1f96f focus the dialogs of a fullscreen client
Since a6e2c15 focustop() returns the fullscreen client even when one of
its children is shown above it, so a dialog opened by a fullscreen client
(a file chooser, say) was shown on top but didn't get focus. Let focustop()
return the fullscreen client's children too, and keep fullscreen_bg on
while one of them is focused.
2026-11-11 10:54:13 +01:00
dvh d1f58218b3 fix a crash in focusmon() when no monitor is enabled
closemon() sets selmon to NULL when every output is disabled (e.g. turned
off with wlr-randr), and dirtomon() dereferences it.
2026-11-11 10:54:13 +01:00
dvh 8fde769b78 don't give the keyboard back to a lock surface being destroyed
wlroots still lists the lock surface being destroyed, and inserts new ones
at the head, so when the focused surface was the newest one,
destroylocksurface() gave the focus back to it and then nothing had it:
the password could not be typed until an output changed. Happens e.g.
when unplugging a monitor while locked with waylock.
2026-11-11 10:54:13 +01:00
dvh 1f5b30aeb3 don't return a freed client for a surface whose toplevel is gone
A client can destroy its xdg_toplevel and keep the xdg_surface. wlroots
keeps the role but sets toplevel to NULL, and xdg_surface->data still
points to the Client freed by destroynotify(), so e.g. a popup created on
that surface made toplevel_from_wlr_surface() read freed memory.
2026-11-11 10:54:13 +01:00
dvh 0b053233c2 remove the popup commit listener when the popup is destroyed
The listener was only removed after the popup's initial commit was handled.
If the popup went away before that (closed before its first commit, no
parent, or destroyed by commitpopup() because its client has no monitor),
it stayed on the surface: wlroots then asserts when the surface is
destroyed, and a commit in between dereferences a NULL popup.
2026-11-11 10:54:13 +01:00
dvh 1f783b71a3 fix a buffer leak in outputmgrapplyortest()
wlr_swapchain_acquire() returns a locked buffer and
wlr_output_state_set_buffer() takes its own lock, so every output enabled
through output management (wlr-randr, kanshi) leaked a buffer. Unlock it
once the state holds it, as wlr_output_swapchain_manager does.
2026-11-11 10:54:13 +01:00
dvh 13086cb898 quit when the backend is destroyed
When the session goes away, e.g. seatd being stopped at shutdown, wlroots
destroys the backend by itself (wlr_auto_backend_monitor), and
wlr_backend_finish() aborts since dwl's new_output and new_input listeners
are still attached:

  Assertion failed: wl_list_empty(&backend->events.new_input.listener_list)

Detach them and quit instead.
2026-11-11 10:54:13 +01:00
Diego Viola 387bc1b53f Fix typo 2026-11-11 10:12:35 +01:00
Diego Viola 637842ce4b fix black screen on QEMU modeset/resize
When running dwl inside a QEMU VM and toggling fullscreen in and out,
the output can stay as a black screen until a new client (such as foot)
forces a redraw. Calling wlr_output_schedule_frame() ensures the frame
loop stays active and resolves the issue.
2026-11-11 04:56:51 -03:00
save196 86a30c4af2 fix out-of-bounds access to consumed[] 2026-11-09 22:25:17 +02:00
save196 8ab0c16f3c fix the size of fullscreen clients on hidden tags when outputs change
Clients moved by closemon() get a stale geometry, and updatemons() only
corrected the visible fullscreen client, not those on hidden tags.
2026-11-08 17:00:30 +02:00
Guido Cella 0996407e3d fix integer underflow in tile()
When clients don't fit, my or ty can exceed m->w.height, and since they
were unsigned, m->w.height - my wrapped around to huge heights, hanging
dwl. With signed ints the height can become negative instead, which
applybounds() raises to the minimum size.

Fixes: https://codeberg.org/dwl/dwl/issues/1254
2026-11-06 08:11:52 +01:00
Guido Cella 15bff401c4 refocus after unsetting fullscreen in mapnotify()
Since a6e2c15 focustop() prefers fullscreen clients, so the
focusclient(focustop(selmon)) in setmon() focuses the fullscreen client
before mapnotify() unsets its fullscreen state, and focus never moves to
the new client.
2026-11-05 20:21:05 +01:00
Guido Cella 4b76704af7 Revert "also make clients tiled on map"
This reverts commit d9ddaba762.

mpv fixed this upstream in
https://github.com/mpv-player/mpv/commit/b2c255c13e8e37952dbac6c34da56a690560378b,
and mpv 0.42 has been released, so our workaround can be removed.
2026-11-05 07:37:20 +01:00
guyuming a6e2c155de 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
2026-11-02 15:34:33 +08:00
Guido Cella be2bd72314 remove old comment
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.
2026-10-29 17:51:48 +01:00
Guido Cella 2d16962424 pass the object to LISTEN_STATIC handlers
wlroots 482d6e53 stopped passing the surface to the idle inhibitor
destroy and surface commit signals, which made destroyidleinhibitor()
and commitpopup() dereference NULL. Store the object in the listener
instead.
2026-10-27 23:33:14 +01:00
Guido Cella 7622bd3187 Merge branch 'main' into wlroots-next 2026-10-27 23:33:05 +01:00
Guido Cella 12a5856427 don't allocate memory for drag_icon_destroy
Not needed since dwl supports only one drag icon at a time.
2026-10-27 23:14:43 +01:00
save196 4ecb2a9df5 fix the focused border color after leaving an unmanaged client
Clients focused after an unmanaged client that wants focus didn't get
the focused border color. Regression from 87029e2.
2026-10-26 15:49:23 +02:00
Guido Cella 4953b7ea0c keep outputs off when they reconnect
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
2026-10-22 23:35:06 +02:00
Guido Cella 9dfaea2f79 call updatemons() when createmon() leaves an output disabled
This lets you enable it later.

Fixes afbafd5.
2026-10-22 13:31:04 +02:00
Guido Cella afbafd53ab don't crash when initializing more monitors than supported
Fixes https://codeberg.org/dwl/dwl/issues/726
2026-10-21 19:02:00 +02:00
Guido Cella 4ff9db2c40 Revert "remove zero flickering lie"
This reverts commit b1c101515a.

Fixed by d3fa329.
2026-10-20 21:26:05 +02:00
Guido Cella d3fa32993c fix flicker when arranging tiled windows
Fixes https://codeberg.org/dwl/dwl/issues/552
Fixes https://codeberg.org/dwl/dwl/issues/705

Also, floating children of fullscreen windows in floating layout now go
in LyrFS instead of LyrTile.
2026-10-20 21:23:49 +02:00
Guido Cella f08d8b3913 fix segfault when XWayland fails to initialize
Fixes https://codeberg.org/dwl/dwl/issues/1202
2026-10-19 22:57:02 +02:00
Guido Cella 90e7c722e9 remove client_is_rendered_on_mon() and client_is_stopped()
Unused since 70c33c0.
2026-10-19 21:17:43 +02:00
Guido CellaandDanD e2038450f2 fix popup positioning
Related: https://codeberg.org/dwl/dwl/pulls/1244

Co-authored-by: DanD <dandgg.ftw@gmail.com>
2026-09-29 13:54:59 +02:00
save196 4fd683cc84 fix X11 clients shifting by the border width on map
c->geom includes the border, but client_get_geometry() returns the
content position. Subtract the border, clamped to the layout edges.
2026-09-29 00:18:49 +03:00
Guido Cella d29259c26a refactor focusclient() 2026-09-28 13:18:49 +02:00
Guido Cella fccce97448 remove obsolete comment
No longer accurate since a514a92.
2026-09-28 12:19:24 +02:00
Guido Cella d9ddaba762 also make clients tiled on map
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.
2026-09-26 19:31:15 +02:00
Guido Cella 5af5dd5e7e update wlroots to 0.21 2026-09-25 13:43:13 +02:00
Guido Cella d3d4da3bd2 Merge branch 'main' into wlroots-next 2026-09-25 13:36:59 +02:00
Guido Cella f1675a4800 Revert "client: do not drop configure events based on current committed size"
This reverts commit 242ffd7a75.

Removing this conditon can cause a xdg_toplevel.configure ↔
wl_surface.commit loop that uses 100% CPU.

Fixes https://codeberg.org/dwl/dwl/issues/1245
Fixes https://codeberg.org/dwl/dwl/issues/1246
2026-09-23 09:03:08 +02:00
Guido Cella a75ca79630 add missing void
Needed to compile on OpenBSD.
2026-09-22 20:42:48 +02:00
Guido Cella 87029e21c0 remove exclusive_focus variable
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.
2026-09-22 14:53:00 +02:00
aloires a514a928e4 focusclient: set input method focus for layer surfaces
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.
2026-09-22 16:25:29 +08:00
André Desgualdo Pereira 242ffd7a75 client: do not drop configure events based on current committed size 2026-09-21 14:35:09 -03:00
save196 f22c223cbf don't run keybindings on keyrepeat while locked 2026-09-21 17:07:38 +03:00
save196 b83881f881 don't send pointer events to clients while locked 2026-09-21 12:37:19 +03:00
save196 fa400c5d3d don't run axis bindings when locked 2026-09-21 01:06:08 +03:00
save196 40b0ae76ae bind axis to nothing by default 2026-09-21 00:07:22 +03:00
save196 2a567195e6 don't use the xdg window geometry offset as a position
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.
2026-09-20 19:53:12 +03:00
Guido Cella cc23250527 bump version to 0.10-dev 2026-09-20 12:20:09 +02:00
Guido Cella 98bea2c27f add version 0.9 to the changelog v0.9 2026-09-20 11:58:38 +02:00