From 2553111aa39445f0d5e50963ab689ef677a3ad81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Sun, 14 Jul 2024 21:34:44 -0600 Subject: [PATCH 01/75] bump wlroots version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 3358bae..f955e7b 100644 --- a/Makefile +++ b/Makefile @@ -12,7 +12,7 @@ DWLDEVCFLAGS = -g -pedantic -Wall -Wextra -Wdeclaration-after-statement \ -Wfloat-conversion # CFLAGS / LDFLAGS -PKGS = wlroots-0.18 wayland-server xkbcommon libinput $(XLIBS) +PKGS = wlroots-0.19 wayland-server xkbcommon libinput $(XLIBS) DWLCFLAGS = `$(PKG_CONFIG) --cflags $(PKGS)` $(DWLCPPFLAGS) $(DWLDEVCFLAGS) $(CFLAGS) LDLIBS = `$(PKG_CONFIG) --libs $(PKGS)` -lm $(LIBS) From da6de7c4d7a2858d463945dc185abc5ae7796960 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Sun, 14 Jul 2024 21:37:03 -0600 Subject: [PATCH 02/75] update wlr_xwayland_surface names (wlroots!2434) References: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/2434 --- client.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client.h b/client.h index 42f225f..c43dbfd 100644 --- a/client.h +++ b/client.h @@ -391,8 +391,8 @@ client_wants_focus(Client *c) { #ifdef XWAYLAND return client_is_unmanaged(c) - && wlr_xwayland_or_surface_wants_focus(c->surface.xwayland) - && wlr_xwayland_icccm_input_model(c->surface.xwayland) != WLR_ICCCM_INPUT_MODEL_NONE; + && wlr_xwayland_surface_override_redirect_wants_focus(c->surface.xwayland) + && wlr_xwayland_surface_icccm_input_model(c->surface.xwayland) != WLR_ICCCM_INPUT_MODEL_NONE; #endif return 0; } From 452a314faa18573fe100a03a154fdd0a0ad54ba2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Sun, 14 Jul 2024 21:55:58 -0600 Subject: [PATCH 03/75] update README.md to mention the main branch now requires wlroots-git Closes: https://codeberg.org/dwl/dwl/issues/646 --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 9d91923..6161a53 100644 --- a/README.md +++ b/README.md @@ -73,8 +73,9 @@ Xwayland (runtime only) ``` Simply install these (and their `-devel` versions if your distro has separate -development packages) and run `make`. If you wish to build against a Git -version of wlroots, check out the [wlroots-next branch]. +development packages) and run `make`. You need to use the Git version of +wlroots to build the `main` branch. If you wish to build against a released +version of wlroots, use a release or a [0.x branch]. To enable XWayland, you should uncomment its flags in `config.mk`. @@ -168,7 +169,7 @@ inspiration, and to the various contributors to the project, including: [#dwl on Libera Chat]: https://web.libera.chat/?channels=#dwl [Wayland]: https://wayland.freedesktop.org/ [wlroots]: https://gitlab.freedesktop.org/wlroots/wlroots/ -[wlroots-next branch]: https://codeberg.org/dwl/dwl/src/branch/wlroots-next +[0.x branch]: https://codeberg.org/dwl/dwl/branches [patches repository]: https://codeberg.org/dwl/dwl-patches [s6]: https://skarnet.org/software/s6/ [anopa]: https://jjacky.com/anopa/ From ad30ca910b9da45835523af5c24ac353b7d13e9f Mon Sep 17 00:00:00 2001 From: A Frederick Christensen Date: Tue, 16 Jul 2024 23:02:22 -0500 Subject: [PATCH 04/75] Documentation restructuring Modified documentation to make clear the change in development (main) branch versus releases. --- README.md | 236 +++++++++++++++++++++++++++++------------------------- 1 file changed, 125 insertions(+), 111 deletions(-) diff --git a/README.md b/README.md index 6161a53..cec84f5 100644 --- a/README.md +++ b/README.md @@ -5,21 +5,132 @@ Or on our [Discord server]. dwl is a compact, hackable compositor for [Wayland] based on [wlroots]. It is intended to fill the same space in the Wayland world that dwm does in X11, -primarily in terms of functionality, and secondarily in terms of philosophy. -Like dwm, dwl is: +primarily in terms of functionality, and secondarily in terms of +philosophy. Like dwm, dwl is: - Easy to understand, hack on, and extend with patches - One C source file (or a very small number) configurable via `config.h` - Tied to as few external dependencies as possible +## Getting Started: + +### Latest semi-stable [release] +This is probably where you want to start. This builds against the dependent +packages' versions currently shipping in major distributions. If your +distribution's wlroots version is older, use an earlier dwl [release] or [0.x +branch]. + +### Development branch [main] +Active development progresses on the `main` branch. The `main` branch is built +against a late (and often changing) git commit of wlroots. While the adventurous +are welcome to use `main`, it is a rocky road. Using `main` requires that the +user be willing to chase git commits of wlroots. Testing development pull +requests may involve merging unmerged pull requests in [wlroots]' git repository +and/or git commits of wayland. + +### Building dwl +dwl has the following dependencies: +- libinput +- wayland +- wlroots (compiled with the libinput backend) +- xkbcommon +- wayland-protocols (compile-time only) +- pkg-config (compile-time only) + +dwl has the following additional dependencies if XWayland support is enabled: +- libxcb +- libxcb-wm +- wlroots (compiled with X11 support) +- Xwayland (runtime only) + +Install these (and their `-devel` versions if your distro has separate +development packages) and run `make`. If you wish to build against a released +version of wlroots (*you probably do*), use a [release] or a [0.x branch]. If +you want to use the unstable development `main` branch, you need to use the git +version of [wlroots]. + +To enable XWayland, you should uncomment its flags in `config.mk`. + +## Configuration + +All configuration is done by editing `config.h` and recompiling, in the same +manner as dwm. There is no way to separately restart the window manager in +Wayland without restarting the entire display server, so any changes will take +effect the next time dwl is executed. + +As in the dwm community, we encourage users to share patches they have +created. Check out the [dwl-patches] repository! + +## Running dwl + +dwl can be run on any of the backends supported by wlroots. This means you can +run it as a separate window inside either an X11 or Wayland session, as well as +directly from a VT console. Depending on your distro's setup, you may need to +add your user to the `video` and `input` groups before you can run dwl on a +VT. If you are using `elogind` or `systemd-logind` you need to install polkit; +otherwise you need to add yourself in the `seat` group and enable/start the +seatd daemon. + +When dwl is run with no arguments, it will launch the server and begin handling +any shortcuts configured in `config.h`. There is no status bar or other +decoration initially; these are instead clients that can be run within the +Wayland session. Do note that the default background color is black. This can be +modified in `config.h`. + +If you would like to run a script or command automatically at startup, you can +specify the command using the `-s` option. This command will be executed as a +shell command using `/bin/sh -c`. It serves a similar function to `.xinitrc`, +but differs in that the display server will not shut down when this process +terminates. Instead, dwl will send this process a SIGTERM at shutdown and wait +for it to terminate (if it hasn't already). This makes it ideal for execing into +a user service manager like [s6], [anopa], [runit], [dinit], or [`systemd +--user`]. + +Note: The `-s` command is run as a *child process* of dwl, which means that it +does not have the ability to affect the environment of dwl or of any processes +that it spawns. If you need to set environment variables that affect the entire +dwl session, these must be set prior to running dwl. For example, Wayland +requires a valid `XDG_RUNTIME_DIR`, which is usually set up by a session manager +such as `elogind` or `systemd-logind`. If your system doesn't do this +automatically, you will need to configure it prior to launching `dwl`, e.g.: + + export XDG_RUNTIME_DIR=/tmp/xdg-runtime-$(id -u) + mkdir -p $XDG_RUNTIME_DIR + dwl + +### Status information + +Information about selected layouts, current window title, app-id, and +selected/occupied/urgent tags is written to the stdin of the `-s` command (see +the `printstatus()` function for details). This information can be used to +populate an external status bar with a script that parses the +information. Failing to read this information will cause dwl to block, so if you +do want to run a startup command that does not consume the status information, +you can close standard input with the `<&-` shell redirection, for example: + + dwl -s 'foot --server <&-' + +If your startup command is a shell script, you can achieve the same inside the +script with the line + + exec <&- + +To get a list of status bars that work with dwl consult our [wiki]. + +## Replacements for X applications + +You can find a [list of useful resources on our wiki]. + +## Background + dwl is not meant to provide every feature under the sun. Instead, like dwm, it sticks to features which are necessary, simple, and straightforward to implement given the base on which it is built. Implemented default features are: - Any features provided by dwm/Xlib: simple window borders, tags, keybindings, client rules, mouse move/resize. Providing a built-in status bar is an - exception to this goal, to avoid dependencies on font rendering and/or - drawing libraries when an external bar could work well. + exception to this goal, to avoid dependencies on font rendering and/or drawing + libraries when an external bar could work well. - Configurable multi-monitor layout support, including position and rotation - Configurable HiDPI/multi-DPI support - Idle-inhibit protocol which lets applications such as mpv disable idle @@ -53,101 +164,6 @@ Feature *non-goals* for the main codebase include: be done through the compositor - Animations and visual effects -## Building dwl - -dwl has the following dependencies: -``` -libinput -wayland -wlroots (compiled with the libinput backend) -xkbcommon -wayland-protocols (compile-time only) -pkg-config (compile-time only) -``` -If you enable X11 support: -``` -libxcb -libxcb-wm -wlroots (compiled with X11 support) -Xwayland (runtime only) -``` - -Simply install these (and their `-devel` versions if your distro has separate -development packages) and run `make`. You need to use the Git version of -wlroots to build the `main` branch. If you wish to build against a released -version of wlroots, use a release or a [0.x branch]. - -To enable XWayland, you should uncomment its flags in `config.mk`. - -## Configuration - -All configuration is done by editing `config.h` and recompiling, in the same -manner as dwm. There is no way to separately restart the window manager in -Wayland without restarting the entire display server, so any changes will take -effect the next time dwl is executed. - -As in the dwm community, we encourage users to share patches they have created. -Check out the dwl [patches repository]! - -## Running dwl - -dwl can be run on any of the backends supported by wlroots. This means you can -run it as a separate window inside either an X11 or Wayland session, as well -as directly from a VT console. Depending on your distro's setup, you may need -to add your user to the `video` and `input` groups before you can run dwl on -a VT. If you are using `elogind` or `systemd-logind` you need to install -polkit; otherwise you need to add yourself in the `seat` group and -enable/start the seatd daemon. - -When dwl is run with no arguments, it will launch the server and begin handling -any shortcuts configured in `config.h`. There is no status bar or other -decoration initially; these are instead clients that can be run within -the Wayland session. -Do note that the background color is black. - -If you would like to run a script or command automatically at startup, you can -specify the command using the `-s` option. This command will be executed as a -shell command using `/bin/sh -c`. It serves a similar function to `.xinitrc`, -but differs in that the display server will not shut down when this process -terminates. Instead, dwl will send this process a SIGTERM at shutdown and wait -for it to terminate (if it hasn't already). This makes it ideal for execing into -a user service manager like [s6], [anopa], [runit], [dinit], or [`systemd --user`]. - -Note: The `-s` command is run as a *child process* of dwl, which means that it -does not have the ability to affect the environment of dwl or of any processes -that it spawns. If you need to set environment variables that affect the entire -dwl session, these must be set prior to running dwl. For example, Wayland -requires a valid `XDG_RUNTIME_DIR`, which is usually set up by a session manager -such as `elogind` or `systemd-logind`. If your system doesn't do this -automatically, you will need to configure it prior to launching `dwl`, e.g.: - - export XDG_RUNTIME_DIR=/tmp/xdg-runtime-$(id -u) - mkdir -p $XDG_RUNTIME_DIR - dwl - -### Status information - -Information about selected layouts, current window title, app-id, and -selected/occupied/urgent tags is written to the stdin of the `-s` command (see -the `printstatus()` function for details). This information can be used to -populate an external status bar with a script that parses the information. -Failing to read this information will cause dwl to block, so if you do want to -run a startup command that does not consume the status information, you can -close standard input with the `<&-` shell redirection, for example: - - dwl -s 'foot --server <&-' - -If your startup command is a shell script, you can achieve the same inside the -script with the line - - exec <&- - -To get a list of status bars that work with dwl consult our [wiki]. - -## Replacements for X applications - -You can find a [list of useful resources on our wiki]. - ## Acknowledgements dwl began by extending the TinyWL example provided (CC0) by the sway/wlroots @@ -165,17 +181,15 @@ inspiration, and to the various contributors to the project, including: - Stivvo for output management and fullscreen support, and patch maintenance -[Discord server]: https://discord.gg/jJxZnrGPWN -[#dwl on Libera Chat]: https://web.libera.chat/?channels=#dwl -[Wayland]: https://wayland.freedesktop.org/ -[wlroots]: https://gitlab.freedesktop.org/wlroots/wlroots/ -[0.x branch]: https://codeberg.org/dwl/dwl/branches -[patches repository]: https://codeberg.org/dwl/dwl-patches -[s6]: https://skarnet.org/software/s6/ +[`systemd --user`]: https://wiki.archlinux.org/title/Systemd/User [#dwl on Libera Chat]: https://web.libera.chat/?channels=#dwl +[0.7-rc1]: https://codeberg.org/dwl/dwl/releases/tag/v0.7-rc1 [0.x branch]: https://codeberg.org/dwl/dwl/branches [anopa]: https://jjacky.com/anopa/ -[runit]: http://smarden.org/runit/faq.html#userservices [dinit]: https://davmac.org/projects/dinit/ -[`systemd --user`]: https://wiki.archlinux.org/title/Systemd/User -[wiki]: https://codeberg.org/dwl/dwl/wiki/Home#compatible-status-bars -[list of useful resources on our wiki]: - https://codeberg.org/dwl/dwl/wiki/Home#migrating-from-x +[dwl-patches]: https://codeberg.org/dwl/dwl-patches [list of useful resources on our wiki]: https://codeberg.org/dwl/dwl/wiki/Home#migrating-from-x +[main]: https://codeberg.org/dwl/dwl/src/branch/main +[release]: https://codeberg.org/dwl/dwl/releases +[runit]: http://smarden.org/runit/faq.html#userservices +[s6]: https://skarnet.org/software/s6/ +[wlroots]: https://gitlab.freedesktop.org/wlroots/wlroots/ +[wiki]: https://codeberg.org/dwl/dwl/wiki/Home#compatible-status-bars [Discord server]: https://discord.gg/jJxZnrGPWN +[Wayland]: https://wayland.freedesktop.org/ From ea6a4501213e73119c4f17c05d7122fcbb9bfd0d Mon Sep 17 00:00:00 2001 From: A Frederick Christensen Date: Sun, 21 Jul 2024 14:28:08 -0500 Subject: [PATCH 05/75] README.md Fix links formatting issue after re-flow text to 80 columns --- README.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index cec84f5..90222e6 100644 --- a/README.md +++ b/README.md @@ -181,15 +181,19 @@ inspiration, and to the various contributors to the project, including: - Stivvo for output management and fullscreen support, and patch maintenance -[`systemd --user`]: https://wiki.archlinux.org/title/Systemd/User [#dwl on Libera Chat]: https://web.libera.chat/?channels=#dwl -[0.7-rc1]: https://codeberg.org/dwl/dwl/releases/tag/v0.7-rc1 [0.x branch]: https://codeberg.org/dwl/dwl/branches +[`systemd --user`]: https://wiki.archlinux.org/title/Systemd/User +[#dwl on Libera Chat]: https://web.libera.chat/?channels=#dwl +[0.7-rc1]: https://codeberg.org/dwl/dwl/releases/tag/v0.7-rc1 +[0.x branch]: https://codeberg.org/dwl/dwl/branches [anopa]: https://jjacky.com/anopa/ [dinit]: https://davmac.org/projects/dinit/ -[dwl-patches]: https://codeberg.org/dwl/dwl-patches [list of useful resources on our wiki]: https://codeberg.org/dwl/dwl/wiki/Home#migrating-from-x +[dwl-patches]: https://codeberg.org/dwl/dwl-patches +[list of useful resources on our wiki]: https://codeberg.org/dwl/dwl/wiki/Home#migrating-from-x [main]: https://codeberg.org/dwl/dwl/src/branch/main [release]: https://codeberg.org/dwl/dwl/releases [runit]: http://smarden.org/runit/faq.html#userservices [s6]: https://skarnet.org/software/s6/ [wlroots]: https://gitlab.freedesktop.org/wlroots/wlroots/ -[wiki]: https://codeberg.org/dwl/dwl/wiki/Home#compatible-status-bars [Discord server]: https://discord.gg/jJxZnrGPWN +[wiki]: https://codeberg.org/dwl/dwl/wiki/Home#compatible-status-bars +[Discord server]: https://discord.gg/jJxZnrGPWN [Wayland]: https://wayland.freedesktop.org/ From 4bbbb4907ec3e239353aa6ba8685ab1aa4a5fea5 Mon Sep 17 00:00:00 2001 From: Lennart Jablonka Date: Tue, 23 Jul 2024 20:12:00 +0200 Subject: [PATCH 06/75] add myself to .mailmap --- .mailmap | 1 + 1 file changed, 1 insertion(+) create mode 100644 .mailmap diff --git a/.mailmap b/.mailmap new file mode 100644 index 0000000..911248c --- /dev/null +++ b/.mailmap @@ -0,0 +1 @@ +Lennart Jablonka From f2c5023a3a6b9abd45c81e7547b111fb5ab119bf Mon Sep 17 00:00:00 2001 From: Lennart Jablonka Date: Tue, 23 Jul 2024 20:14:51 +0200 Subject: [PATCH 07/75] dwl(1): use correct special characters for - and ' The hyphen-minus <-> and apostrophe-quote <'> are interpreted by troff as hyphen and right single quotation mark. See groff_char(7). Fixes: 0db6f3c5b5f9 ("add dwl(1)") --- dwl.1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dwl.1 b/dwl.1 index 387bcc9..780c78f 100644 --- a/dwl.1 +++ b/dwl.1 @@ -140,7 +140,7 @@ server. Start .Nm with s6 in the background: -.Dl dwl -s 's6-svscan <&-' +.Dl dwl \-s \(aqs6\-svscan <&\-\(aq .Sh SEE ALSO .Xr foot 1 , .Xr wmenu 1 , From cd216908a7c26f547b7e10a389aea6b754afb6d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Tue, 23 Jul 2024 16:16:19 -0600 Subject: [PATCH 08/75] send scale on initial commit to layer surfaces MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Leonardo Hernández Hernández --- dwl.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/dwl.c b/dwl.c index 5bf995e..5f9491b 100644 --- a/dwl.c +++ b/dwl.c @@ -763,6 +763,9 @@ commitlayersurfacenotify(struct wl_listener *listener, void *data) struct wlr_layer_surface_v1_state old_state; if (l->layer_surface->initial_commit) { + wlr_fractional_scale_v1_notify_scale(layer_surface->surface, l->mon->wlr_output->scale); + wlr_surface_set_preferred_buffer_scale(layer_surface->surface, (int32_t)ceilf(l->mon->wlr_output->scale)); + /* Temporarily set the layer's current state to pending * so that we can easily arrange it */ old_state = l->layer_surface->current; @@ -945,8 +948,6 @@ createlayersurface(struct wl_listener *listener, void *data) wl_list_insert(&l->mon->layers[layer_surface->pending.layer],&l->link); wlr_surface_send_enter(surface, layer_surface->output); - wlr_fractional_scale_v1_notify_scale(surface, l->mon->wlr_output->scale); - wlr_surface_set_preferred_buffer_scale(surface, (int32_t)ceilf(l->mon->wlr_output->scale)); } void From 487abc28ba6879bf3a2492ef766f0420ae6f904b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Wed, 24 Jul 2024 15:51:49 -0600 Subject: [PATCH 09/75] add myself to .mailmap --- .mailmap | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.mailmap b/.mailmap index 911248c..1778cb9 100644 --- a/.mailmap +++ b/.mailmap @@ -1 +1,3 @@ Lennart Jablonka +Leonardo Hernández Hernández +Leonardo Hernández Hernández From 986beef5be32a2bead22ca85d19f4d6d7e5c0ce1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Sat, 27 Jul 2024 00:40:24 -0600 Subject: [PATCH 10/75] replace spaces with tabs Fixes: 71f11e6cf63289d51f152469a0da81a85fe2608c --- util.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/util.c b/util.c index 51130af..b925987 100644 --- a/util.c +++ b/util.c @@ -38,14 +38,14 @@ ecalloc(size_t nmemb, size_t size) int fd_set_nonblock(int fd) { int flags = fcntl(fd, F_GETFL); - if (flags < 0) { + if (flags < 0) { perror("fcntl(F_GETFL):"); - return -1; - } - if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0) { + return -1; + } + if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0) { perror("fcntl(F_SETFL):"); return -1; - } + } return 0; } From b5abbc37d8161c7ac8d05010e0effbc6af81718b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Sat, 27 Jul 2024 21:34:18 -0600 Subject: [PATCH 11/75] fix crash when re-mapping a client Fixes: ab5c554d096ebca8446b7b1354c49be014b8b747 --- dwl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dwl.c b/dwl.c index 5f9491b..2db3c15 100644 --- a/dwl.c +++ b/dwl.c @@ -2183,7 +2183,7 @@ resize(Client *c, struct wlr_box geo, int interact) struct wlr_box *bbox; struct wlr_box clip; - if (!c->mon || !c->scene) + if (!c->mon || !client_surface(c)->mapped) return; bbox = interact ? &sgeom : &c->mon->w; From 672b4c405d5207cadc572190affbe41e653e7a8c Mon Sep 17 00:00:00 2001 From: Sivecano Date: Sat, 27 Jul 2024 14:46:54 +0200 Subject: [PATCH 12/75] fix maximize callback not getting deregisterd --- dwl.c | 1 + 1 file changed, 1 insertion(+) diff --git a/dwl.c b/dwl.c index 2db3c15..ac9c36b 100644 --- a/dwl.c +++ b/dwl.c @@ -1276,6 +1276,7 @@ destroynotify(struct wl_listener *listener, void *data) wl_list_remove(&c->commit.link); wl_list_remove(&c->map.link); wl_list_remove(&c->unmap.link); + wl_list_remove(&c->maximize.link); } free(c); } From d136dadf456250f9a4cef23abd1fdf21518a31ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Thu, 1 Aug 2024 20:38:57 -0600 Subject: [PATCH 13/75] `-pedantic` -> `-Wpedantic` Bug: https://codeberg.org/dwl/dwl/issues/584 --- Makefile | 2 +- config.mk | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index f955e7b..f3e1f10 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ include config.mk # flags for compiling DWLCPPFLAGS = -I. -DWLR_USE_UNSTABLE -D_POSIX_C_SOURCE=200809L \ -DVERSION=\"$(VERSION)\" $(XWAYLAND) -DWLDEVCFLAGS = -g -pedantic -Wall -Wextra -Wdeclaration-after-statement \ +DWLDEVCFLAGS = -g -Wpedantic -Wall -Wextra -Wdeclaration-after-statement \ -Wno-unused-parameter -Wshadow -Wunused-macros -Werror=strict-prototypes \ -Werror=implicit -Werror=return-type -Werror=incompatible-pointer-types \ -Wfloat-conversion diff --git a/config.mk b/config.mk index 1d5ac38..99ccc63 100644 --- a/config.mk +++ b/config.mk @@ -14,4 +14,7 @@ XLIBS = #XWAYLAND = -DXWAYLAND #XLIBS = xcb xcb-icccm -CC = gcc +# dwl itself only uses C99 features, but wlroots' headers use anonymous unions (C11). +# To avoid warnings about them, we do not use -std=c99 and instead of using the +# gmake default 'CC=c99', we use cc. +CC = cc From a634e3f527001cd2e2b7bc21bb14c1b7351f60bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Mon, 5 Aug 2024 12:11:42 -0600 Subject: [PATCH 14/75] fix crash when a virtual pointer is destroyed Fixes: https://codeberg.org/dwl/dwl/issues/680 --- dwl.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dwl.c b/dwl.c index ac9c36b..8e0d28b 100644 --- a/dwl.c +++ b/dwl.c @@ -2977,11 +2977,11 @@ void virtualpointer(struct wl_listener *listener, void *data) { struct wlr_virtual_pointer_v1_new_pointer_event *event = data; - struct wlr_pointer pointer = event->new_pointer->pointer; + struct wlr_input_device *device = &event->new_pointer->pointer.base; - wlr_cursor_attach_input_device(cursor, &pointer.base); + wlr_cursor_attach_input_device(cursor, device); if (event->suggested_output) - wlr_cursor_map_input_to_output(cursor, &pointer.base, event->suggested_output); + wlr_cursor_map_input_to_output(cursor, device, event->suggested_output); } Monitor * From 35951a8d7eb3bcf2c7d618e156fd7b163e64d976 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Tue, 11 Jun 2024 11:32:50 -0600 Subject: [PATCH 15/75] add support for linux-drm-syncobj-v1 (wlroots!4715) References: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4262 References: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4715 --- CHANGELOG.md | 7 +++++++ dwl.c | 6 +++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3aefd6f..b7d67dc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,13 @@ ## Unreleased ### Added + +* Support for the linux-drm-syncobj-v1 protocol ([wlroots!4715][wlroots!4715], [#685][685]) + +[wlroots!4715]: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4715 +[685]: https://codeberg.org/dwl/dwl/pulls/685 + + ### Changed ### Deprecated ### Removed diff --git a/dwl.c b/dwl.c index 8e0d28b..72892d9 100644 --- a/dwl.c +++ b/dwl.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -2430,7 +2431,7 @@ setsel(struct wl_listener *listener, void *data) void setup(void) { - int i, sig[] = {SIGCHLD, SIGINT, SIGTERM, SIGPIPE}; + int drm_fd, i, sig[] = {SIGCHLD, SIGINT, SIGTERM, SIGPIPE}; struct sigaction sa = {.sa_flags = SA_RESTART, .sa_handler = handlesig}; sigemptyset(&sa.sa_mask); @@ -2480,6 +2481,9 @@ setup(void) wlr_linux_dmabuf_v1_create_with_renderer(dpy, 5, drw)); } + if ((drm_fd = wlr_renderer_get_drm_fd(drw)) >= 0 && drw->features.timeline) + wlr_linux_drm_syncobj_manager_v1_create(dpy, 1, drm_fd); + /* Autocreates an allocator for us. * The allocator is the bridge between the renderer and the backend. It * handles the buffer creation, allowing wlroots to render onto the From a4fa9546166c9af277616dd6dcd80e61ee024eb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Sat, 3 Aug 2024 12:09:18 -0600 Subject: [PATCH 16/75] do not restack xwayland surfaces (wlroots!4756) References: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4756 --- client.h | 11 ----------- dwl.c | 1 - 2 files changed, 12 deletions(-) diff --git a/client.h b/client.h index c43dbfd..3dc1050 100644 --- a/client.h +++ b/client.h @@ -301,17 +301,6 @@ client_notify_enter(struct wlr_surface *s, struct wlr_keyboard *kb) wlr_seat_keyboard_notify_enter(seat, s, NULL, 0, NULL); } -static inline void -client_restack_surface(Client *c) -{ -#ifdef XWAYLAND - if (client_is_x11(c)) - wlr_xwayland_surface_restack(c->surface.xwayland, NULL, - XCB_STACK_MODE_ABOVE); -#endif - return; -} - static inline void client_send_close(Client *c) { diff --git a/dwl.c b/dwl.c index 72892d9..7e2d510 100644 --- a/dwl.c +++ b/dwl.c @@ -1368,7 +1368,6 @@ focusclient(Client *c, int lift) wl_list_insert(&fstack, &c->flink); selmon = c->mon; c->isurgent = 0; - client_restack_surface(c); /* Don't change border color if there is an exclusive focus or we are * handling a drag operation */ From b25717c9396d2fc040b8c3df75288b3de72971ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Thu, 8 Aug 2024 14:19:39 -0600 Subject: [PATCH 17/75] drop a useless check in configurex11() --- dwl.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/dwl.c b/dwl.c index 7e2d510..3a3188c 100644 --- a/dwl.c +++ b/dwl.c @@ -3083,13 +3083,14 @@ configurex11(struct wl_listener *listener, void *data) { Client *c = wl_container_of(listener, c, configure); struct wlr_xwayland_surface_configure_event *event = data; - /* TODO: figure out if there is another way to do this */ + /* This also handles "unmanaged" clients (because we do not assign + * them a monitor) */ if (!c->mon) { wlr_xwayland_surface_configure(c->surface.xwayland, event->x, event->y, event->width, event->height); return; } - if (c->isfloating || client_is_unmanaged(c)) + if (c->isfloating) resize(c, (struct wlr_box){.x = event->x, .y = event->y, .width = event->width + c->bw * 2, .height = event->height + c->bw * 2}, 0); else From bb21ecda30e041fb957eca42947e093758cdf75a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Thu, 8 Aug 2024 14:33:03 -0600 Subject: [PATCH 18/75] improve checking in configurex11() this avoids a client resizing itself when the user is interactively resizing the client --- dwl.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dwl.c b/dwl.c index 3a3188c..1500ceb 100644 --- a/dwl.c +++ b/dwl.c @@ -638,6 +638,7 @@ buttonpress(struct wl_listener *listener, void *data) /* Drop the window off on its new monitor */ selmon = xytomon(cursor->x, cursor->y); setmon(grabc, selmon, 0); + grabc = NULL; return; } else { cursor_mode = CurNormal; @@ -3090,7 +3091,7 @@ configurex11(struct wl_listener *listener, void *data) event->x, event->y, event->width, event->height); return; } - if (c->isfloating) + if ((c->isfloating && c != grabc) || !c->mon->lt[c->mon->sellt]->arrange) resize(c, (struct wlr_box){.x = event->x, .y = event->y, .width = event->width + c->bw * 2, .height = event->height + c->bw * 2}, 0); else From 94f4ead7dad89433e6087dc19950738c64bbed05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Thu, 8 Aug 2024 14:38:43 -0600 Subject: [PATCH 19/75] actually move unmanaged clients in configurex11() only calling wlr_xwayland_surface_configure() may be not enough because we also need to move the scene node in order to make effective the configure --- dwl.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/dwl.c b/dwl.c index 1500ceb..f1ab64b 100644 --- a/dwl.c +++ b/dwl.c @@ -3084,14 +3084,13 @@ configurex11(struct wl_listener *listener, void *data) { Client *c = wl_container_of(listener, c, configure); struct wlr_xwayland_surface_configure_event *event = data; - /* This also handles "unmanaged" clients (because we do not assign - * them a monitor) */ - if (!c->mon) { + if (!client_surface(c) || !client_surface(c)->mapped) { wlr_xwayland_surface_configure(c->surface.xwayland, event->x, event->y, event->width, event->height); return; } - if ((c->isfloating && c != grabc) || !c->mon->lt[c->mon->sellt]->arrange) + if ((c->isfloating && c != grabc) + || client_is_unmanaged(c) || !c->mon->lt[c->mon->sellt]->arrange) resize(c, (struct wlr_box){.x = event->x, .y = event->y, .width = event->width + c->bw * 2, .height = event->height + c->bw * 2}, 0); else From 1b805ddd38aeb03dbf64886fb9a153f76f4eb8e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Thu, 8 Aug 2024 14:42:16 -0600 Subject: [PATCH 20/75] account border width in configurex11() Fixes: 13925eb1da8af2c1d23ee9d01efd03c3626081b2 --- dwl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dwl.c b/dwl.c index f1ab64b..82a01d8 100644 --- a/dwl.c +++ b/dwl.c @@ -3091,7 +3091,7 @@ configurex11(struct wl_listener *listener, void *data) } if ((c->isfloating && c != grabc) || client_is_unmanaged(c) || !c->mon->lt[c->mon->sellt]->arrange) - resize(c, (struct wlr_box){.x = event->x, .y = event->y, + resize(c, (struct wlr_box){.x = event->x - c->bw, .y = event->y - c->bw, .width = event->width + c->bw * 2, .height = event->height + c->bw * 2}, 0); else arrange(c->mon); From 334bbe6f0f5e4f77789b42ac9e5607d5076aef1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Sat, 10 Aug 2024 10:39:25 -0600 Subject: [PATCH 21/75] fix potential crash in configurex11() We can't call resize() on unmanaged clients because they don't have borders and resize() requires them. Fixes: 94f4ead7dad89433e6087dc19950738c64bbed05 --- dwl.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/dwl.c b/dwl.c index 82a01d8..d28e9f1 100644 --- a/dwl.c +++ b/dwl.c @@ -3089,8 +3089,13 @@ configurex11(struct wl_listener *listener, void *data) event->x, event->y, event->width, event->height); return; } - if ((c->isfloating && c != grabc) - || client_is_unmanaged(c) || !c->mon->lt[c->mon->sellt]->arrange) + if (client_is_unmanaged(c)) { + wlr_scene_node_set_position(&c->scene->node, event->x, event->y); + wlr_xwayland_surface_configure(c->surface.xwayland, + event->x, event->y, event->width, event->height); + return; + } + if ((c->isfloating && c != grabc) || !c->mon->lt[c->mon->sellt]->arrange) resize(c, (struct wlr_box){.x = event->x - c->bw, .y = event->y - c->bw, .width = event->width + c->bw * 2, .height = event->height + c->bw * 2}, 0); else From e454f7ae812ca5ceac372223d42ffea252ff012a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Thu, 20 Jun 2024 12:36:56 -0600 Subject: [PATCH 22/75] allow the use of non-system wlroots library References: https://codeberg.org/dwl/dwl/issues/646#issuecomment-2032644 --- Makefile | 6 +++--- config.mk | 16 ++++++++++++++++ 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index f3e1f10..8db7409 100644 --- a/Makefile +++ b/Makefile @@ -12,9 +12,9 @@ DWLDEVCFLAGS = -g -Wpedantic -Wall -Wextra -Wdeclaration-after-statement \ -Wfloat-conversion # CFLAGS / LDFLAGS -PKGS = wlroots-0.19 wayland-server xkbcommon libinput $(XLIBS) -DWLCFLAGS = `$(PKG_CONFIG) --cflags $(PKGS)` $(DWLCPPFLAGS) $(DWLDEVCFLAGS) $(CFLAGS) -LDLIBS = `$(PKG_CONFIG) --libs $(PKGS)` -lm $(LIBS) +PKGS = wayland-server xkbcommon libinput $(XLIBS) +DWLCFLAGS = `$(PKG_CONFIG) --cflags $(PKGS)` $(WLR_INCS) $(DWLCPPFLAGS) $(DWLDEVCFLAGS) $(CFLAGS) +LDLIBS = `$(PKG_CONFIG) --libs $(PKGS)` $(WLR_LIBS) -lm $(LIBS) all: dwl dwl: dwl.o util.o diff --git a/config.mk b/config.mk index 99ccc63..e374ccb 100644 --- a/config.mk +++ b/config.mk @@ -8,6 +8,22 @@ PREFIX = /usr/local MANDIR = $(PREFIX)/share/man DATADIR = $(PREFIX)/share +# Allow using an alternative wlroots installations +# This has to have all the includes required by wlroots, e.g: +# Assuming wlroots git repo is "${PWD}/wlroots" and you only ran "meson setup build && ninja -C build" +#WLR_INCS = -I/usr/include/pixman-1 -I/usr/include/elogind -I/usr/include/libdrm \ +# -I$(PWD)/wlroots/include +# Set -rpath to avoid using the wrong library. +#WLR_LIBS = -Wl,-rpath,$(PWD)/wlroots/build -L$(PWD)/wlroots/build -lwlroots-0.19 + +# Assuming you ran "meson setup --prefix ${PWD}/0.19 build && ninja -C build install" +#WLR_INCS = -I/usr/include/pixman-1 -I/usr/include/elogind -I/usr/include/libdrm \ +# -I$(PWD)/wlroots/0.19/include/wlroots-0.19 +#WLR_LIBS = -Wl,-rpath,$(PWD)/wlroots/0.19/lib64 -L$(PWD)/wlroots/0.19/lib64 -lwlroots-0.19 + +WLR_INCS = `$(PKG_CONFIG) --cflags wlroots-0.19` +WLR_LIBS = `$(PKG_CONFIG) --libs wlroots-0.19` + XWAYLAND = XLIBS = # Uncomment to build XWayland support From 07aeef1f7ee2e5c48846fcdbd651fc8162c02c57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Fri, 9 Aug 2024 21:34:02 -0600 Subject: [PATCH 23/75] guarantee client_get_{title,appid} never return NULL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ΔSLOC: -6 --- client.h | 8 ++++---- dwl.c | 14 ++++---------- 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/client.h b/client.h index 3dc1050..e0c45fd 100644 --- a/client.h +++ b/client.h @@ -126,9 +126,9 @@ client_get_appid(Client *c) { #ifdef XWAYLAND if (client_is_x11(c)) - return c->surface.xwayland->class; + return c->surface.xwayland->class ? c->surface.xwayland->class : "broken"; #endif - return c->surface.xdg->toplevel->app_id; + return c->surface.xdg->toplevel->app_id ? c->surface.xdg->toplevel->app_id : "broken"; } static inline void @@ -200,9 +200,9 @@ client_get_title(Client *c) { #ifdef XWAYLAND if (client_is_x11(c)) - return c->surface.xwayland->title; + return c->surface.xwayland->title ? c->surface.xwayland->title : "broken"; #endif - return c->surface.xdg->toplevel->title; + return c->surface.xdg->toplevel->title ? c->surface.xdg->toplevel->title : "broken"; } static inline int diff --git a/dwl.c b/dwl.c index d28e9f1..b88d7b1 100644 --- a/dwl.c +++ b/dwl.c @@ -358,7 +358,6 @@ static void xytonode(double x, double y, struct wlr_surface **psurface, static void zoom(const Arg *arg); /* variables */ -static const char broken[] = "broken"; static pid_t child_pid = -1; static int locked; static void *exclusive_focus; @@ -462,10 +461,8 @@ applyrules(Client *c) Monitor *mon = selmon, *m; c->isfloating = client_is_float_type(c); - if (!(appid = client_get_appid(c))) - appid = broken; - if (!(title = client_get_title(c))) - title = broken; + appid = client_get_appid(c); + title = client_get_title(c); for (r = rules; r < END(rules); r++) { if ((!r->title || strstr(title, r->title)) @@ -2040,7 +2037,6 @@ printstatus(void) Monitor *m = NULL; Client *c; uint32_t occ, urg, sel; - const char *appid, *title; wl_list_for_each(m, &mons, link) { occ = urg = 0; @@ -2052,10 +2048,8 @@ printstatus(void) urg |= c->tags; } if ((c = focustop(m))) { - title = client_get_title(c); - appid = client_get_appid(c); - printf("%s title %s\n", m->wlr_output->name, title ? title : broken); - printf("%s appid %s\n", m->wlr_output->name, appid ? appid : broken); + printf("%s title %s\n", m->wlr_output->name, client_get_title(c)); + printf("%s appid %s\n", m->wlr_output->name, client_get_appid(c)); printf("%s fullscreen %d\n", m->wlr_output->name, c->isfullscreen); printf("%s floating %d\n", m->wlr_output->name, c->isfloating); sel = c->tags; From 0caa6582765492cff5a6470626137adaebaa575e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Wed, 14 Aug 2024 11:47:29 -0600 Subject: [PATCH 24/75] use wlr_scene_set_gamma_control_manager_v1() (wlroots!4192) References: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4192 --- dwl.c | 44 ++------------------------------------------ 1 file changed, 2 insertions(+), 42 deletions(-) diff --git a/dwl.c b/dwl.c index b88d7b1..8a587d1 100644 --- a/dwl.c +++ b/dwl.c @@ -327,7 +327,6 @@ static void setcursor(struct wl_listener *listener, void *data); static void setcursorshape(struct wl_listener *listener, void *data); static void setfloating(Client *c, int floating); static void setfullscreen(Client *c, int fullscreen); -static void setgamma(struct wl_listener *listener, void *data); static void setlayout(const Arg *arg); static void setmfact(const Arg *arg); static void setmon(Client *c, Monitor *m, uint32_t newtags); @@ -383,7 +382,6 @@ static struct wlr_idle_notifier_v1 *idle_notifier; static struct wlr_idle_inhibit_manager_v1 *idle_inhibit_mgr; static struct wlr_layer_shell_v1 *layer_shell; static struct wlr_output_manager_v1 *output_mgr; -static struct wlr_gamma_control_manager_v1 *gamma_control_mgr; static struct wlr_virtual_keyboard_manager_v1 *virtual_keyboard_mgr; static struct wlr_virtual_pointer_manager_v1 *virtual_pointer_mgr; static struct wlr_cursor_shape_manager_v1 *cursor_shape_mgr; @@ -2100,7 +2098,6 @@ rendermon(struct wl_listener *listener, void *data) Monitor *m = wl_container_of(listener, m, frame); Client *c; struct wlr_output_state pending = {0}; - struct wlr_gamma_control_v1 *gamma_control; struct timespec now; /* Render if no XDG clients have an outstanding resize and are visible on @@ -2110,32 +2107,7 @@ rendermon(struct wl_listener *listener, void *data) goto skip; } - /* - * HACK: The "correct" way to set the gamma is to commit it together with - * the rest of the state in one go, but to do that we would need to rewrite - * wlr_scene_output_commit() in order to add the gamma to the pending - * state before committing, instead try to commit the gamma in one frame, - * and commit the rest of the state in the next one (or in the same frame if - * the gamma can not be committed). - */ - if (m->gamma_lut_changed) { - gamma_control - = wlr_gamma_control_manager_v1_get_control(gamma_control_mgr, m->wlr_output); - m->gamma_lut_changed = 0; - - if (!wlr_gamma_control_v1_apply(gamma_control, &pending)) - goto commit; - - if (!wlr_output_test_state(m->wlr_output, &pending)) { - wlr_gamma_control_v1_send_failed_and_destroy(gamma_control); - goto commit; - } - wlr_output_commit_state(m->wlr_output, &pending); - wlr_output_schedule_frame(m->wlr_output); - } else { -commit: - wlr_scene_output_commit(m->scene_output, NULL); - } + wlr_scene_output_commit(m->scene_output, NULL); skip: /* Let clients know a frame has been rendered */ @@ -2337,17 +2309,6 @@ setfullscreen(Client *c, int fullscreen) printstatus(); } -void -setgamma(struct wl_listener *listener, void *data) -{ - struct wlr_gamma_control_manager_v1_set_gamma_event *event = data; - Monitor *m = event->output->data; - if (!m) - return; - m->gamma_lut_changed = 1; - wlr_output_schedule_frame(m->wlr_output); -} - void setlayout(const Arg *arg) { @@ -2508,8 +2469,7 @@ setup(void) activation = wlr_xdg_activation_v1_create(dpy); LISTEN_STATIC(&activation->events.request_activate, urgent); - gamma_control_mgr = wlr_gamma_control_manager_v1_create(dpy); - LISTEN_STATIC(&gamma_control_mgr->events.set_gamma, setgamma); + wlr_scene_set_gamma_control_manager_v1(scene, wlr_gamma_control_manager_v1_create(dpy)); power_mgr = wlr_output_power_manager_v1_create(dpy); LISTEN_STATIC(&power_mgr->events.set_mode, powermgrsetmode); From 554754c9a2c03a263ac7d14092d6f67f3a211cdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Wed, 14 Aug 2024 13:37:14 -0600 Subject: [PATCH 25/75] chase xdg_surface geometry changes (wlroots!4788) References: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4788 --- client.h | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/client.h b/client.h index e0c45fd..81946db 100644 --- a/client.h +++ b/client.h @@ -134,7 +134,6 @@ client_get_appid(Client *c) static inline void client_get_clip(Client *c, struct wlr_box *clip) { - struct wlr_box xdg_geom = {0}; *clip = (struct wlr_box){ .x = 0, .y = 0, @@ -147,9 +146,8 @@ client_get_clip(Client *c, struct wlr_box *clip) return; #endif - wlr_xdg_surface_get_geometry(c->surface.xdg, &xdg_geom); - clip->x = xdg_geom.x; - clip->y = xdg_geom.y; + clip->x = c->surface.xdg->geometry.x; + clip->y = c->surface.xdg->geometry.y; } static inline void @@ -164,7 +162,7 @@ client_get_geometry(Client *c, struct wlr_box *geom) return; } #endif - wlr_xdg_surface_get_geometry(c->surface.xdg, geom); + *geom = c->surface.xdg->geometry; } static inline Client * From 2c0b889f86bec0bb43a53bea8835b0418fa887ed Mon Sep 17 00:00:00 2001 From: A Frederick Christensen Date: Sat, 17 Aug 2024 09:46:20 -0500 Subject: [PATCH 26/75] Update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b7d67dc..f59ba5b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,9 +10,11 @@ ### Added * Support for the linux-drm-syncobj-v1 protocol ([wlroots!4715][wlroots!4715], [#685][685]) +* Allow the use of non-system wlroots library ([#646][646]) [wlroots!4715]: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4715 [685]: https://codeberg.org/dwl/dwl/pulls/685 +[646]: https://codeberg.org/dwl/dwl/pulls/646 ### Changed From c5275ca571b0824d81f49c156b33217deceb9eed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Sat, 17 Aug 2024 21:15:17 -0600 Subject: [PATCH 27/75] state that the Discord server is community-maintained Previously I regularly checked the server but it has been quite a long time since I was able to do it. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 90222e6..1bcc36e 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # dwl - dwm for Wayland Join us on our IRC channel: [#dwl on Libera Chat] -Or on our [Discord server]. +Or on the community-maintained [Discord server]. dwl is a compact, hackable compositor for [Wayland] based on [wlroots]. It is intended to fill the same space in the Wayland world that dwm does in X11, From 8ec5e52e061cfefab0bfed354a8b98ea2f4fb775 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Sun, 25 Aug 2024 11:33:54 -0600 Subject: [PATCH 28/75] fix crash when a client is created while all outputs are disabled --- CHANGELOG.md | 3 +++ dwl.c | 6 ++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f59ba5b..07c9ee4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,9 @@ ### Deprecated ### Removed ### Fixed + +* Crash when a client is created while all outputs are disabled. + ### Security ### Contributors diff --git a/dwl.c b/dwl.c index 8a587d1..3171123 100644 --- a/dwl.c +++ b/dwl.c @@ -800,8 +800,10 @@ commitnotify(struct wl_listener *listener, void *data) * a wrong monitor. */ applyrules(c); - wlr_surface_set_preferred_buffer_scale(client_surface(c), (int)ceilf(c->mon->wlr_output->scale)); - wlr_fractional_scale_v1_notify_scale(client_surface(c), c->mon->wlr_output->scale); + if (c->mon) { + wlr_surface_set_preferred_buffer_scale(client_surface(c), (int)ceilf(c->mon->wlr_output->scale)); + wlr_fractional_scale_v1_notify_scale(client_surface(c), c->mon->wlr_output->scale); + } setmon(c, NULL, 0); /* Make sure to reapply rules in mapnotify() */ wlr_xdg_toplevel_set_wm_capabilities(c->surface.xdg->toplevel, WLR_XDG_TOPLEVEL_WM_CAPABILITIES_FULLSCREEN); From 5db05e82bd7d1f6bf3cb0ce1ddd07952f06e57f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Fri, 9 Aug 2024 20:51:33 -0600 Subject: [PATCH 29/75] fix style in configurex11() --- dwl.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/dwl.c b/dwl.c index 3171123..78cf341 100644 --- a/dwl.c +++ b/dwl.c @@ -3051,11 +3051,13 @@ configurex11(struct wl_listener *listener, void *data) event->x, event->y, event->width, event->height); return; } - if ((c->isfloating && c != grabc) || !c->mon->lt[c->mon->sellt]->arrange) - resize(c, (struct wlr_box){.x = event->x - c->bw, .y = event->y - c->bw, - .width = event->width + c->bw * 2, .height = event->height + c->bw * 2}, 0); - else + if ((c->isfloating && c != grabc) || !c->mon->lt[c->mon->sellt]->arrange) { + resize(c, (struct wlr_box){.x = event->x - c->bw, + .y = event->y - c->bw, .width = event->width + c->bw * 2, + .height = event->height + c->bw * 2}, 0); + } else { arrange(c->mon); + } } void From d4ad37354e9ae8d475f8de9300903f8dd19e0f9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Fri, 9 Aug 2024 21:35:21 -0600 Subject: [PATCH 30/75] update comment about first fields of Client and LayerSurface order --- dwl.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/dwl.c b/dwl.c index 78cf341..bef92e2 100644 --- a/dwl.c +++ b/dwl.c @@ -106,15 +106,18 @@ typedef struct { typedef struct Monitor Monitor; typedef struct { - /* Must keep these three elements in this order */ + /* Must keep this field first */ unsigned int type; /* XDGShell or X11* */ - struct wlr_box geom; /* layout-relative, includes border */ + Monitor *mon; struct wlr_scene_tree *scene; struct wlr_scene_rect *border[4]; /* top, bottom, left, right */ struct wlr_scene_tree *scene_surface; struct wl_list link; struct wl_list flink; + struct wlr_box geom; /* layout-relative, includes border */ + struct wlr_box prev; /* layout-relative, includes border */ + struct wlr_box bounds; /* only width and height are used */ union { struct wlr_xdg_surface *xdg; struct wlr_xwayland_surface *xwayland; @@ -129,8 +132,6 @@ typedef struct { struct wl_listener fullscreen; struct wl_listener set_decoration_mode; struct wl_listener destroy_decoration; - struct wlr_box prev; /* layout-relative, includes border */ - struct wlr_box bounds; #ifdef XWAYLAND struct wl_listener activate; struct wl_listener associate; @@ -166,10 +167,11 @@ typedef struct { } KeyboardGroup; typedef struct { - /* Must keep these three elements in this order */ + /* Must keep this field first */ unsigned int type; /* LayerShell */ - struct wlr_box geom; + Monitor *mon; + struct wlr_box geom; struct wlr_scene_tree *scene; struct wlr_scene_tree *popups; struct wlr_scene_layer_surface_v1 *scene_layer; From b616476c856d893e0d7bd1e35b74cc996ec7f4b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Wed, 14 Aug 2024 13:09:09 -0600 Subject: [PATCH 31/75] remove unnecessary LayerShell.geom We only used geom.x and geom.y. We can access those variables directly from the scene node. --- dwl.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/dwl.c b/dwl.c index bef92e2..1aec267 100644 --- a/dwl.c +++ b/dwl.c @@ -171,7 +171,6 @@ typedef struct { unsigned int type; /* LayerShell */ Monitor *mon; - struct wlr_box geom; struct wlr_scene_tree *scene; struct wlr_scene_tree *popups; struct wlr_scene_layer_surface_v1 *scene_layer; @@ -533,8 +532,6 @@ arrangelayer(Monitor *m, struct wl_list *list, struct wlr_box *usable_area, int wlr_scene_layer_surface_v1_configure(l->scene_layer, &full_area, usable_area); wlr_scene_node_set_position(&l->popups->node, l->scene->node.x, l->scene->node.y); - l->geom.x = l->scene->node.x; - l->geom.y = l->scene->node.y; } } @@ -844,8 +841,8 @@ commitpopup(struct wl_listener *listener, void *data) if ((l && !l->mon) || (c && !c->mon)) return; box = type == LayerShell ? l->mon->m : c->mon->w; - box.x -= (type == LayerShell ? l->geom.x : c->geom.x); - box.y -= (type == LayerShell ? l->geom.y : c->geom.y); + box.x -= (type == LayerShell ? l->scene->node.x : c->geom.x); + box.y -= (type == LayerShell ? l->scene->node.y : c->geom.y); wlr_xdg_popup_unconstrain_from_box(popup, &box); wl_list_remove(&listener->link); } @@ -1824,8 +1821,8 @@ motionnotify(uint32_t time, struct wlr_input_device *device, double dx, double d && toplevel_from_wlr_surface(seat->pointer_state.focused_surface, &w, &l) >= 0) { c = w; surface = seat->pointer_state.focused_surface; - sx = cursor->x - (l ? l->geom.x : w->geom.x); - sy = cursor->y - (l ? l->geom.y : w->geom.y); + sx = cursor->x - (l ? l->scene->node.x : w->geom.x); + sy = cursor->y - (l ? l->scene->node.y : w->geom.y); } /* time is 0 in internal calls meant to restore pointer focus. */ From 43016bdad80fcd2efe557a43e8db2345ead9b5f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Fri, 9 Aug 2024 22:05:04 -0600 Subject: [PATCH 32/75] introduce client_set_scale() --- client.h | 6 ++++++ dwl.c | 6 ++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/client.h b/client.h index 81946db..9c2cff3 100644 --- a/client.h +++ b/client.h @@ -331,6 +331,12 @@ client_set_fullscreen(Client *c, int fullscreen) wlr_xdg_toplevel_set_fullscreen(c->surface.xdg->toplevel, fullscreen); } +static inline void +client_set_scale(struct wlr_surface *s, float scale) { + wlr_fractional_scale_v1_notify_scale(s, scale); + wlr_surface_set_preferred_buffer_scale(s, (int32_t)ceilf(scale)); +} + static inline uint32_t client_set_size(Client *c, uint32_t width, uint32_t height) { diff --git a/dwl.c b/dwl.c index 1aec267..457bea7 100644 --- a/dwl.c +++ b/dwl.c @@ -759,8 +759,7 @@ commitlayersurfacenotify(struct wl_listener *listener, void *data) struct wlr_layer_surface_v1_state old_state; if (l->layer_surface->initial_commit) { - wlr_fractional_scale_v1_notify_scale(layer_surface->surface, l->mon->wlr_output->scale); - wlr_surface_set_preferred_buffer_scale(layer_surface->surface, (int32_t)ceilf(l->mon->wlr_output->scale)); + client_set_scale(layer_surface->surface, l->mon->wlr_output->scale); /* Temporarily set the layer's current state to pending * so that we can easily arrange it */ @@ -800,8 +799,7 @@ commitnotify(struct wl_listener *listener, void *data) */ applyrules(c); if (c->mon) { - wlr_surface_set_preferred_buffer_scale(client_surface(c), (int)ceilf(c->mon->wlr_output->scale)); - wlr_fractional_scale_v1_notify_scale(client_surface(c), c->mon->wlr_output->scale); + client_set_scale(client_surface(c), c->mon->wlr_output->scale); } setmon(c, NULL, 0); /* Make sure to reapply rules in mapnotify() */ From 54b546121b3221e02d31a2af0bb0ce859376ab93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Fri, 9 Aug 2024 22:27:51 -0600 Subject: [PATCH 33/75] avoid using a else block --- dwl.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/dwl.c b/dwl.c index 457bea7..76d3fca 100644 --- a/dwl.c +++ b/dwl.c @@ -625,7 +625,7 @@ buttonpress(struct wl_listener *listener, void *data) break; case WL_POINTER_BUTTON_STATE_RELEASED: /* If you released any buttons, we exit interactive move/resize mode. */ - /* TODO should reset to the pointer focus's current setcursor */ + /* TODO: should reset to the pointer focus's current setcursor */ if (!locked && cursor_mode != CurNormal && cursor_mode != CurPressed) { wlr_cursor_set_xcursor(cursor, cursor_mgr, "default"); cursor_mode = CurNormal; @@ -634,9 +634,8 @@ buttonpress(struct wl_listener *listener, void *data) setmon(grabc, selmon, 0); grabc = NULL; return; - } else { - cursor_mode = CurNormal; } + cursor_mode = CurNormal; break; } /* If the event wasn't handled by the compositor, notify the client with From bbc00d88a45df249009c9946dfd88285eecac0c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Wed, 14 Aug 2024 13:10:14 -0600 Subject: [PATCH 34/75] remove a redundant check resize() now does the same check --- dwl.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dwl.c b/dwl.c index 76d3fca..4a11657 100644 --- a/dwl.c +++ b/dwl.c @@ -809,8 +809,7 @@ commitnotify(struct wl_listener *listener, void *data) return; } - if (client_surface(c)->mapped && c->mon) - resize(c, c->geom, (c->isfloating && !c->isfullscreen)); + resize(c, c->geom, (c->isfloating && !c->isfullscreen)); /* mark a pending resize as completed */ if (c->resize && c->resize <= c->surface.xdg->current.configure_serial) From 6de87121e2cf05119ddbfb501c87766912aa4d0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Wed, 14 Aug 2024 13:10:58 -0600 Subject: [PATCH 35/75] destroy popups when we can't get it's parent or they don't have monitor --- dwl.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dwl.c b/dwl.c index 4a11657..94e01b0 100644 --- a/dwl.c +++ b/dwl.c @@ -834,8 +834,10 @@ commitpopup(struct wl_listener *listener, void *data) return; popup->base->surface->data = wlr_scene_xdg_surface_create( popup->parent->data, popup->base); - if ((l && !l->mon) || (c && !c->mon)) + if ((l && !l->mon) || (c && !c->mon)) { + wlr_xdg_popup_destroy(popup); return; + } box = type == LayerShell ? l->mon->m : c->mon->w; box.x -= (type == LayerShell ? l->scene->node.x : c->geom.x); box.y -= (type == LayerShell ? l->scene->node.y : c->geom.y); From 0312720ae8599904e847eed377cc5ee222905835 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Wed, 14 Aug 2024 13:12:09 -0600 Subject: [PATCH 36/75] remove a space before parenthesis in function calls --- dwl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dwl.c b/dwl.c index 94e01b0..85e7f36 100644 --- a/dwl.c +++ b/dwl.c @@ -1094,10 +1094,10 @@ createpointer(struct wlr_pointer *pointer) libinput_device_config_middle_emulation_set_enabled(device, middle_button_emulation); if (libinput_device_config_scroll_get_methods(device) != LIBINPUT_CONFIG_SCROLL_NO_SCROLL) - libinput_device_config_scroll_set_method (device, scroll_method); + libinput_device_config_scroll_set_method(device, scroll_method); if (libinput_device_config_click_get_methods(device) != LIBINPUT_CONFIG_CLICK_METHOD_NONE) - libinput_device_config_click_set_method (device, click_method); + libinput_device_config_click_set_method(device, click_method); if (libinput_device_config_send_events_get_modes(device)) libinput_device_config_send_events_set_mode(device, send_events_mode); From cc72df11d690346ed1924593d283a7453986deab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Wed, 14 Aug 2024 13:14:15 -0600 Subject: [PATCH 37/75] configure xdg_toplevels after configuring it's decoration --- dwl.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/dwl.c b/dwl.c index 85e7f36..dd9bd7d 100644 --- a/dwl.c +++ b/dwl.c @@ -802,10 +802,11 @@ commitnotify(struct wl_listener *listener, void *data) } setmon(c, NULL, 0); /* Make sure to reapply rules in mapnotify() */ - wlr_xdg_toplevel_set_wm_capabilities(c->surface.xdg->toplevel, WLR_XDG_TOPLEVEL_WM_CAPABILITIES_FULLSCREEN); - wlr_xdg_toplevel_set_size(c->surface.xdg->toplevel, 0, 0); + wlr_xdg_toplevel_set_wm_capabilities(c->surface.xdg->toplevel, + WLR_XDG_TOPLEVEL_WM_CAPABILITIES_FULLSCREEN); if (c->decoration) requestdecorationmode(&c->set_decoration_mode, c->decoration); + wlr_xdg_toplevel_set_size(c->surface.xdg->toplevel, 0, 0); return; } From f89906096537b1ec69a1db3216268ef7b4a1b7b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Wed, 14 Aug 2024 13:15:48 -0600 Subject: [PATCH 38/75] send a configure to unmanaged clients when mapping --- dwl.c | 1 + 1 file changed, 1 insertion(+) diff --git a/dwl.c b/dwl.c index dd9bd7d..e6bbf04 100644 --- a/dwl.c +++ b/dwl.c @@ -1703,6 +1703,7 @@ mapnotify(struct wl_listener *listener, void *data) /* Unmanaged clients always are floating */ wlr_scene_node_reparent(&c->scene->node, layers[LyrFloat]); wlr_scene_node_set_position(&c->scene->node, c->geom.x, c->geom.y); + client_set_size(c, c->geom.width, c->geom.height); if (client_wants_focus(c)) { focusclient(c, 1); exclusive_focus = c; From c49312f0841aaa11e9354d9cc239953b7c50ae83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Wed, 14 Aug 2024 13:18:04 -0600 Subject: [PATCH 39/75] disable scene node unless it is unmanaged --- dwl.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dwl.c b/dwl.c index e6bbf04..1f8df42 100644 --- a/dwl.c +++ b/dwl.c @@ -1690,7 +1690,8 @@ mapnotify(struct wl_listener *listener, void *data) /* Create scene tree for this client and its border */ c->scene = client_surface(c)->data = wlr_scene_tree_create(layers[LyrTile]); - wlr_scene_node_set_enabled(&c->scene->node, c->type != XDGShell); + /* Enabled later by a call to arrange() */ + wlr_scene_node_set_enabled(&c->scene->node, client_is_unmanaged(c)); c->scene_surface = c->type == XDGShell ? wlr_scene_xdg_surface_create(c->scene, c->surface.xdg) : wlr_scene_subsurface_tree_create(c->scene, client_surface(c)); From d34be5d545f598bb4f07f9a07c4618e480705ca6 Mon Sep 17 00:00:00 2001 From: choc Date: Mon, 26 Aug 2024 21:40:27 +0800 Subject: [PATCH 40/75] remove unused link member from KeyboardGroup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit unnecessary since grouping Keyboard wl_list to use wlr_keyboard_group in 023efce ΔSLOC: -1 --- dwl.c | 1 - 1 file changed, 1 deletion(-) diff --git a/dwl.c b/dwl.c index 1f8df42..9021e44 100644 --- a/dwl.c +++ b/dwl.c @@ -153,7 +153,6 @@ typedef struct { } Key; typedef struct { - struct wl_list link; struct wlr_keyboard_group *wlr_group; int nsyms; From 9c05b9622c7aa3a0874c49231249cf1859e2d031 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Fri, 30 Aug 2024 18:19:18 -0600 Subject: [PATCH 41/75] fix style for client_set_scale() --- client.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client.h b/client.h index 9c2cff3..dabea35 100644 --- a/client.h +++ b/client.h @@ -332,7 +332,8 @@ client_set_fullscreen(Client *c, int fullscreen) } static inline void -client_set_scale(struct wlr_surface *s, float scale) { +client_set_scale(struct wlr_surface *s, float scale) +{ wlr_fractional_scale_v1_notify_scale(s, scale); wlr_surface_set_preferred_buffer_scale(s, (int32_t)ceilf(scale)); } From 54f207839f686a44918cfc581b15ff153215ee9c Mon Sep 17 00:00:00 2001 From: Guido Cella Date: Sun, 8 Sep 2024 20:51:41 +0200 Subject: [PATCH 42/75] reorder config.mk variables By placing the default WLR_INCS and WLR_LIBS before the ones for an alternative wlroots, they don't need to be commented to enable the alternative ones. --- config.mk | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/config.mk b/config.mk index e374ccb..e2f1816 100644 --- a/config.mk +++ b/config.mk @@ -8,6 +8,9 @@ PREFIX = /usr/local MANDIR = $(PREFIX)/share/man DATADIR = $(PREFIX)/share +WLR_INCS = `$(PKG_CONFIG) --cflags wlroots-0.19` +WLR_LIBS = `$(PKG_CONFIG) --libs wlroots-0.19` + # Allow using an alternative wlroots installations # This has to have all the includes required by wlroots, e.g: # Assuming wlroots git repo is "${PWD}/wlroots" and you only ran "meson setup build && ninja -C build" @@ -21,9 +24,6 @@ DATADIR = $(PREFIX)/share # -I$(PWD)/wlroots/0.19/include/wlroots-0.19 #WLR_LIBS = -Wl,-rpath,$(PWD)/wlroots/0.19/lib64 -L$(PWD)/wlroots/0.19/lib64 -lwlroots-0.19 -WLR_INCS = `$(PKG_CONFIG) --cflags wlroots-0.19` -WLR_LIBS = `$(PKG_CONFIG) --libs wlroots-0.19` - XWAYLAND = XLIBS = # Uncomment to build XWayland support From 8206cc8889994b3e9ce3c50abefc19367cf49a8e Mon Sep 17 00:00:00 2001 From: Guido Cella Date: Sat, 7 Sep 2024 21:22:40 +0200 Subject: [PATCH 43/75] fix a use after free This line makes dwl crash after closing mpv with the switchtotag patch. --- dwl.c | 1 - 1 file changed, 1 deletion(-) diff --git a/dwl.c b/dwl.c index 9021e44..dc0c861 100644 --- a/dwl.c +++ b/dwl.c @@ -1171,7 +1171,6 @@ void destroydecoration(struct wl_listener *listener, void *data) { Client *c = wl_container_of(listener, c, destroy_decoration); - c->decoration = NULL; wl_list_remove(&c->destroy_decoration.link); wl_list_remove(&c->set_decoration_mode.link); From 002c7d22043da56a54511b5d234c2e3bd997d119 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Sun, 25 Aug 2024 13:02:34 -0600 Subject: [PATCH 44/75] tell xwayland clients they're maximized like we do to xdg clients when tiled state is not supported. --- client.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/client.h b/client.h index dabea35..389b4f0 100644 --- a/client.h +++ b/client.h @@ -358,8 +358,11 @@ static inline void client_set_tiled(Client *c, uint32_t edges) { #ifdef XWAYLAND - if (client_is_x11(c)) + if (client_is_x11(c)) { + wlr_xwayland_surface_set_maximized(c->surface.xwayland, + edges != WLR_EDGE_NONE, edges != WLR_EDGE_NONE); return; + } #endif if (wl_resource_get_version(c->surface.xdg->toplevel->resource) >= XDG_TOPLEVEL_STATE_TILED_RIGHT_SINCE_VERSION) { From 6ca87210d49424b457a319ae037d8a0658346af9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Sun, 27 Oct 2024 20:26:55 -0600 Subject: [PATCH 45/75] check if the backend supports explicit sync before creating the object (wlroots!4848) References: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4848 --- dwl.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dwl.c b/dwl.c index dc0c861..19eaf71 100644 --- a/dwl.c +++ b/dwl.c @@ -2436,7 +2436,8 @@ setup(void) wlr_linux_dmabuf_v1_create_with_renderer(dpy, 5, drw)); } - if ((drm_fd = wlr_renderer_get_drm_fd(drw)) >= 0 && drw->features.timeline) + if ((drm_fd = wlr_renderer_get_drm_fd(drw)) >= 0 && drw->features.timeline + && backend->features.timeline) wlr_linux_drm_syncobj_manager_v1_create(dpy, 1, drm_fd); /* Autocreates an allocator for us. From 84245764e28e6c841946ef706c704139e97d1bd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Sun, 27 Oct 2024 20:08:02 -0600 Subject: [PATCH 46/75] specify version for presentation-time (wlroots!4858) References: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4858 --- dwl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dwl.c b/dwl.c index 19eaf71..9acb898 100644 --- a/dwl.c +++ b/dwl.c @@ -2463,7 +2463,7 @@ setup(void) wlr_viewporter_create(dpy); wlr_single_pixel_buffer_manager_v1_create(dpy); wlr_fractional_scale_manager_v1_create(dpy, 1); - wlr_presentation_create(dpy, backend); + wlr_presentation_create(dpy, backend, 2); wlr_alpha_modifier_v1_create(dpy); /* Initializes the interface used to implement urgency hints */ From 1d08ade13225343890e3476f7c4003ab87dc266c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Fri, 15 Nov 2024 00:17:43 -0600 Subject: [PATCH 47/75] remove binary before copying to destination Since Linux 6.11 is possible overwrite a running executable, possibly making it crash. Thanks to: movq42rax Fixes: https://codeberg.org/dwl/dwl/issues/709 References: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=2a010c412853 References: https://lore.kernel.org/stable/CACKH++YAtEMYu2nTLUyfmxZoGO37fqogKMDkBpddmNaz5HE6ng@mail.gmail.com/T/#u --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index 8db7409..578194f 100644 --- a/Makefile +++ b/Makefile @@ -61,6 +61,7 @@ dist: clean install: dwl mkdir -p $(DESTDIR)$(PREFIX)/bin + rm -f $(DESTDIR)$(PREFIX)/bin/dwl cp -f dwl $(DESTDIR)$(PREFIX)/bin chmod 755 $(DESTDIR)$(PREFIX)/bin/dwl mkdir -p $(DESTDIR)$(MANDIR)/man1 From 30f5063474a70835d0178ffc12521a3e0fb1ef8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Tue, 10 Dec 2024 22:32:21 -0600 Subject: [PATCH 48/75] manually call updatemons in powermgrsetmode() Fixes: https://codeberg.org/dwl/dwl/issues/713 --- dwl.c | 1 + 1 file changed, 1 insertion(+) diff --git a/dwl.c b/dwl.c index 9acb898..0eba3e9 100644 --- a/dwl.c +++ b/dwl.c @@ -2082,6 +2082,7 @@ powermgrsetmode(struct wl_listener *listener, void *data) wlr_output_commit_state(m->wlr_output, &state); m->asleep = !event->mode; + updatemons(NULL, NULL); } void From 6f34a6d3a6f6604af2c4c257343a31064983651f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Sat, 10 Aug 2024 11:25:41 -0600 Subject: [PATCH 49/75] use wlr_xwayland_surface_has_window_type() (wlroots!4553) References: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4553 --- client.h | 13 ++++++------- dwl.c | 34 ---------------------------------- 2 files changed, 6 insertions(+), 41 deletions(-) diff --git a/client.h b/client.h index 389b4f0..f1e2ab5 100644 --- a/client.h +++ b/client.h @@ -213,16 +213,15 @@ client_is_float_type(Client *c) if (client_is_x11(c)) { struct wlr_xwayland_surface *surface = c->surface.xwayland; xcb_size_hints_t *size_hints = surface->size_hints; - size_t i; if (surface->modal) return 1; - for (i = 0; i < surface->window_type_len; i++) - if (surface->window_type[i] == netatom[NetWMWindowTypeDialog] - || surface->window_type[i] == netatom[NetWMWindowTypeSplash] - || surface->window_type[i] == netatom[NetWMWindowTypeToolbar] - || surface->window_type[i] == netatom[NetWMWindowTypeUtility]) - return 1; + if (wlr_xwayland_surface_has_window_type(surface, WLR_XWAYLAND_NET_WM_WINDOW_TYPE_DIALOG) + || wlr_xwayland_surface_has_window_type(surface, WLR_XWAYLAND_NET_WM_WINDOW_TYPE_SPLASH) + || wlr_xwayland_surface_has_window_type(surface, WLR_XWAYLAND_NET_WM_WINDOW_TYPE_TOOLBAR) + || wlr_xwayland_surface_has_window_type(surface, WLR_XWAYLAND_NET_WM_WINDOW_TYPE_UTILITY)) { + return 1; + } return size_hints && size_hints->min_width > 0 && size_hints->min_height > 0 && (size_hints->max_width == size_hints->min_width diff --git a/dwl.c b/dwl.c index 0eba3e9..05e1975 100644 --- a/dwl.c +++ b/dwl.c @@ -85,10 +85,6 @@ enum { CurNormal, CurPressed, CurMove, CurResize }; /* cursor */ enum { XDGShell, LayerShell, X11 }; /* client types */ enum { LyrBg, LyrBottom, LyrTile, LyrFloat, LyrTop, LyrFS, LyrOverlay, LyrBlock, NUM_LAYERS }; /* scene layers */ -#ifdef XWAYLAND -enum { NetWMWindowTypeDialog, NetWMWindowTypeSplash, NetWMWindowTypeToolbar, - NetWMWindowTypeUtility, NetLast }; /* EWMH atoms */ -#endif typedef union { int i; @@ -417,11 +413,9 @@ static void associatex11(struct wl_listener *listener, void *data); static void configurex11(struct wl_listener *listener, void *data); static void createnotifyx11(struct wl_listener *listener, void *data); static void dissociatex11(struct wl_listener *listener, void *data); -static xcb_atom_t getatom(xcb_connection_t *xc, const char *name); static void sethints(struct wl_listener *listener, void *data); static void xwaylandready(struct wl_listener *listener, void *data); static struct wlr_xwayland *xwayland; -static xcb_atom_t netatom[NetLast]; #endif /* configuration, allows nested code to access above variables */ @@ -3091,19 +3085,6 @@ dissociatex11(struct wl_listener *listener, void *data) wl_list_remove(&c->unmap.link); } -xcb_atom_t -getatom(xcb_connection_t *xc, const char *name) -{ - xcb_atom_t atom = 0; - xcb_intern_atom_reply_t *reply; - xcb_intern_atom_cookie_t cookie = xcb_intern_atom(xc, 0, strlen(name), name); - if ((reply = xcb_intern_atom_reply(xc, cookie, NULL))) - atom = reply->atom; - free(reply); - - return atom; -} - void sethints(struct wl_listener *listener, void *data) { @@ -3123,19 +3104,6 @@ void xwaylandready(struct wl_listener *listener, void *data) { struct wlr_xcursor *xcursor; - xcb_connection_t *xc = xcb_connect(xwayland->display_name, NULL); - int err = xcb_connection_has_error(xc); - if (err) { - fprintf(stderr, "xcb_connect to X server failed with code %d\n. Continuing with degraded functionality.\n", err); - return; - } - - /* Collect atoms we are interested in. If getatom returns 0, we will - * not detect that window type. */ - netatom[NetWMWindowTypeDialog] = getatom(xc, "_NET_WM_WINDOW_TYPE_DIALOG"); - netatom[NetWMWindowTypeSplash] = getatom(xc, "_NET_WM_WINDOW_TYPE_SPLASH"); - netatom[NetWMWindowTypeToolbar] = getatom(xc, "_NET_WM_WINDOW_TYPE_TOOLBAR"); - netatom[NetWMWindowTypeUtility] = getatom(xc, "_NET_WM_WINDOW_TYPE_UTILITY"); /* assign the one and only seat */ wlr_xwayland_set_seat(xwayland, seat); @@ -3146,8 +3114,6 @@ xwaylandready(struct wl_listener *listener, void *data) xcursor->images[0]->buffer, xcursor->images[0]->width * 4, xcursor->images[0]->width, xcursor->images[0]->height, xcursor->images[0]->hotspot_x, xcursor->images[0]->hotspot_y); - - xcb_disconnect(xc); } #endif From 26504f9a6f93e5b14819d5ed84dd27d3fbb41f3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Thu, 26 Dec 2024 20:18:51 -0600 Subject: [PATCH 50/75] do not call waitid(2) in the signal handler when Xwayland is enabled waitid(2) is not a async-signal-safe function acording to signal-safety(7) We can stop doing this because wlroots!4926 allows compositors to install signal handlers for SIGCHLD. References: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4926 --- dwl.c | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/dwl.c b/dwl.c index 05e1975..ea66483 100644 --- a/dwl.c +++ b/dwl.c @@ -1486,22 +1486,10 @@ gpureset(struct wl_listener *listener, void *data) void handlesig(int signo) { - if (signo == SIGCHLD) { -#ifdef XWAYLAND - siginfo_t in; - /* wlroots expects to reap the XWayland process itself, so we - * use WNOWAIT to keep the child waitable until we know it's not - * XWayland. - */ - while (!waitid(P_ALL, 0, &in, WEXITED|WNOHANG|WNOWAIT) && in.si_pid - && (!xwayland || in.si_pid != xwayland->server->pid)) - waitpid(in.si_pid, NULL, 0); -#else + if (signo == SIGCHLD) while (waitpid(-1, NULL, WNOHANG) > 0); -#endif - } else if (signo == SIGINT || signo == SIGTERM) { + else if (signo == SIGINT || signo == SIGTERM) quit(NULL); - } } void From 0925fe956aeddb983875f0fd892e9049e2d8cb76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Thu, 16 Jan 2025 19:02:02 -0600 Subject: [PATCH 51/75] unlink some destroy listeners Recently wlroots was updated to assert that signals do not have listeners attached on destroy. This is just a preliminar work to fix dwl. At the moment dwl will trigger the assertions at exit. References: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4918 --- dwl.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dwl.c b/dwl.c index ea66483..d9d9f95 100644 --- a/dwl.c +++ b/dwl.c @@ -1176,6 +1176,7 @@ destroydragicon(struct wl_listener *listener, void *data) /* Focus enter isn't sent during drag, so refocus the focused node. */ focusclient(focustop(selmon), 1); motionnotify(0, NULL, 0, 0, 0, 0); + wl_list_remove(&listener->link); } void @@ -1184,6 +1185,7 @@ destroyidleinhibitor(struct wl_listener *listener, void *data) /* `data` is the wlr_surface of the idle inhibitor being destroyed, * at this point the idle inhibitor is still in the list of the manager */ checkidleinhibitor(wlr_surface_get_root_surface(data)); + wl_list_remove(&listener->link); } void From 4e7e2999d42fdb6d4796d88e355138fa6ae61252 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Sun, 19 Jan 2025 13:43:51 -0600 Subject: [PATCH 52/75] Partially revert "Line saver: LISTEN_STATIC macro" This reverts commit 33bcd2e4ca892bb0b558660c99ed63a3dfdd9011. We keep LISTEN_STATIC for three instances where we use it. We use simple listeners for the rest of signals. This is the continuation of 0925fe956aeddb983875f0fd892e9049e2d8cb76 --- dwl.c | 108 ++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 72 insertions(+), 36 deletions(-) diff --git a/dwl.c b/dwl.c index d9d9f95..cfe7772 100644 --- a/dwl.c +++ b/dwl.c @@ -394,7 +394,6 @@ static struct wlr_scene_rect *root_bg; static struct wlr_session_lock_manager_v1 *session_lock_mgr; static struct wlr_scene_rect *locked_bg; static struct wlr_session_lock_v1 *cur_lock; -static struct wl_listener lock_listener = {.notify = locksession}; static struct wlr_seat *seat; static KeyboardGroup *kb_group; @@ -407,6 +406,37 @@ static struct wlr_box sgeom; static struct wl_list mons; static Monitor *selmon; +/* global event handlers */ +static struct wl_listener cursor_axis = {.notify = axisnotify}; +static struct wl_listener cursor_button = {.notify = buttonpress}; +static struct wl_listener cursor_frame = {.notify = cursorframe}; +static struct wl_listener cursor_motion = {.notify = motionrelative}; +static struct wl_listener cursor_motion_absolute = {.notify = motionabsolute}; +static struct wl_listener gpu_reset = {.notify = gpureset}; +static struct wl_listener idle_inhibitor_create = {.notify = createidleinhibitor}; +static struct wl_listener layout_change = {.notify = updatemons}; +static struct wl_listener new_input = {.notify = inputdevice}; +static struct wl_listener new_virtual_keyboard = {.notify = virtualkeyboard}; +static struct wl_listener new_virtual_pointer = {.notify = virtualpointer}; +static struct wl_listener new_pointer_constraint = {.notify = createpointerconstraint}; +static struct wl_listener new_output = {.notify = createmon}; +static struct wl_listener new_xdg_surface = {.notify = createnotify}; +static struct wl_listener new_xdg_popup = {.notify = createpopup}; +static struct wl_listener new_xdg_decoration = {.notify = createdecoration}; +static struct wl_listener new_layer_shell_surface = {.notify = createlayersurface}; +static struct wl_listener output_mgr_apply = {.notify = outputmgrapply}; +static struct wl_listener output_mgr_test = {.notify = outputmgrtest}; +static struct wl_listener output_power_mgr_set_mode = {.notify = powermgrsetmode}; +static struct wl_listener request_activate = {.notify = urgent}; +static struct wl_listener request_cursor = {.notify = setcursor}; +static struct wl_listener request_set_psel = {.notify = setpsel}; +static struct wl_listener request_set_sel = {.notify = setsel}; +static struct wl_listener request_set_shape = {.notify = setcursorshape}; +static struct wl_listener request_start_drag = {.notify = requeststartdrag}; +static struct wl_listener start_drag = {.notify = startdrag}; +static struct wl_listener session_lock_create_lock = {.notify = locksession}; +static struct wl_listener session_lock_mgr_destroy = {.notify = destroysessionmgr}; + #ifdef XWAYLAND static void activatex11(struct wl_listener *listener, void *data); static void associatex11(struct wl_listener *listener, void *data); @@ -415,6 +445,8 @@ static void createnotifyx11(struct wl_listener *listener, void *data); static void dissociatex11(struct wl_listener *listener, void *data); static void sethints(struct wl_listener *listener, void *data); static void xwaylandready(struct wl_listener *listener, void *data); +static struct wl_listener new_xwayland_surface = {.notify = createnotifyx11}; +static struct wl_listener xwayland_ready = {.notify = xwaylandready}; static struct wlr_xwayland *xwayland; #endif @@ -1296,8 +1328,8 @@ destroysessionlock(struct wl_listener *listener, void *data) void destroysessionmgr(struct wl_listener *listener, void *data) { - wl_list_remove(&lock_listener.link); - wl_list_remove(&listener->link); + wl_list_remove(&session_lock_create_lock.link); + wl_list_remove(&session_lock_mgr_destroy.link); } void @@ -1473,7 +1505,8 @@ gpureset(struct wl_listener *listener, void *data) if (!(alloc = wlr_allocator_autocreate(backend, drw))) die("couldn't recreate allocator"); - LISTEN_STATIC(&drw->events.lost, gpureset); + wl_list_remove(&gpu_reset.link); + wl_signal_add(&drw->events.lost, &gpu_reset); wlr_compositor_set_renderer(compositor, drw); @@ -2406,7 +2439,7 @@ setup(void) * supports for shared memory, this configures that for clients. */ if (!(drw = wlr_renderer_autocreate(backend))) die("couldn't create renderer"); - LISTEN_STATIC(&drw->events.lost, gpureset); + wl_signal_add(&drw->events.lost, &gpu_reset); /* Create shm, drm and linux_dmabuf interfaces by ourselves. * The simplest way is call: @@ -2453,23 +2486,24 @@ setup(void) /* Initializes the interface used to implement urgency hints */ activation = wlr_xdg_activation_v1_create(dpy); - LISTEN_STATIC(&activation->events.request_activate, urgent); + wl_signal_add(&activation->events.request_activate, &request_activate); wlr_scene_set_gamma_control_manager_v1(scene, wlr_gamma_control_manager_v1_create(dpy)); power_mgr = wlr_output_power_manager_v1_create(dpy); - LISTEN_STATIC(&power_mgr->events.set_mode, powermgrsetmode); + wl_signal_add(&power_mgr->events.set_mode, &output_power_mgr_set_mode); /* Creates an output layout, which a wlroots utility for working with an * arrangement of screens in a physical layout. */ output_layout = wlr_output_layout_create(dpy); - LISTEN_STATIC(&output_layout->events.change, updatemons); - wlr_xdg_output_manager_v1_create(dpy, output_layout); + wl_signal_add(&output_layout->events.change, &layout_change); + + wlr_xdg_output_manager_v1_create(dpy, output_layout); /* Configure a listener to be notified when new outputs are available on the * backend. */ wl_list_init(&mons); - LISTEN_STATIC(&backend->events.new_output, createmon); + wl_signal_add(&backend->events.new_output, &new_output); /* Set up our client lists, the xdg-shell and the layer-shell. The xdg-shell is a * Wayland protocol which is used for application windows. For more @@ -2481,20 +2515,20 @@ setup(void) wl_list_init(&fstack); xdg_shell = wlr_xdg_shell_create(dpy, 6); - LISTEN_STATIC(&xdg_shell->events.new_toplevel, createnotify); - LISTEN_STATIC(&xdg_shell->events.new_popup, createpopup); + wl_signal_add(&xdg_shell->events.new_toplevel, &new_xdg_surface); + wl_signal_add(&xdg_shell->events.new_popup, &new_xdg_popup); layer_shell = wlr_layer_shell_v1_create(dpy, 3); - LISTEN_STATIC(&layer_shell->events.new_surface, createlayersurface); + wl_signal_add(&layer_shell->events.new_surface, &new_layer_shell_surface); idle_notifier = wlr_idle_notifier_v1_create(dpy); idle_inhibit_mgr = wlr_idle_inhibit_v1_create(dpy); - LISTEN_STATIC(&idle_inhibit_mgr->events.new_inhibitor, createidleinhibitor); + wl_signal_add(&idle_inhibit_mgr->events.new_inhibitor, &idle_inhibitor_create); session_lock_mgr = wlr_session_lock_manager_v1_create(dpy); - wl_signal_add(&session_lock_mgr->events.new_lock, &lock_listener); - LISTEN_STATIC(&session_lock_mgr->events.destroy, destroysessionmgr); + wl_signal_add(&session_lock_mgr->events.new_lock, &session_lock_create_lock); + wl_signal_add(&session_lock_mgr->events.destroy, &session_lock_mgr_destroy); locked_bg = wlr_scene_rect_create(layers[LyrBlock], sgeom.width, sgeom.height, (float [4]){0.1f, 0.1f, 0.1f, 1.0f}); wlr_scene_node_set_enabled(&locked_bg->node, 0); @@ -2504,10 +2538,10 @@ setup(void) wlr_server_decoration_manager_create(dpy), WLR_SERVER_DECORATION_MANAGER_MODE_SERVER); xdg_decoration_mgr = wlr_xdg_decoration_manager_v1_create(dpy); - LISTEN_STATIC(&xdg_decoration_mgr->events.new_toplevel_decoration, createdecoration); + wl_signal_add(&xdg_decoration_mgr->events.new_toplevel_decoration, &new_xdg_decoration); pointer_constraints = wlr_pointer_constraints_v1_create(dpy); - LISTEN_STATIC(&pointer_constraints->events.new_constraint, createpointerconstraint); + wl_signal_add(&pointer_constraints->events.new_constraint, &new_pointer_constraint); relative_pointer_mgr = wlr_relative_pointer_manager_v1_create(dpy); @@ -2535,14 +2569,14 @@ setup(void) * * And more comments are sprinkled throughout the notify functions above. */ - LISTEN_STATIC(&cursor->events.motion, motionrelative); - LISTEN_STATIC(&cursor->events.motion_absolute, motionabsolute); - LISTEN_STATIC(&cursor->events.button, buttonpress); - LISTEN_STATIC(&cursor->events.axis, axisnotify); - LISTEN_STATIC(&cursor->events.frame, cursorframe); + wl_signal_add(&cursor->events.motion, &cursor_motion); + wl_signal_add(&cursor->events.motion_absolute, &cursor_motion_absolute); + wl_signal_add(&cursor->events.button, &cursor_button); + wl_signal_add(&cursor->events.axis, &cursor_axis); + wl_signal_add(&cursor->events.frame, &cursor_frame); cursor_shape_mgr = wlr_cursor_shape_manager_v1_create(dpy, 1); - LISTEN_STATIC(&cursor_shape_mgr->events.request_set_shape, setcursorshape); + wl_signal_add(&cursor_shape_mgr->events.request_set_shape, &request_set_shape); /* * Configures a seat, which is a single "seat" at which a user sits and @@ -2550,25 +2584,27 @@ setup(void) * pointer, touch, and drawing tablet device. We also rig up a listener to * let us know when new input devices are available on the backend. */ - LISTEN_STATIC(&backend->events.new_input, inputdevice); + wl_signal_add(&backend->events.new_input, &new_input); virtual_keyboard_mgr = wlr_virtual_keyboard_manager_v1_create(dpy); - LISTEN_STATIC(&virtual_keyboard_mgr->events.new_virtual_keyboard, virtualkeyboard); + wl_signal_add(&virtual_keyboard_mgr->events.new_virtual_keyboard, + &new_virtual_keyboard); virtual_pointer_mgr = wlr_virtual_pointer_manager_v1_create(dpy); - LISTEN_STATIC(&virtual_pointer_mgr->events.new_virtual_pointer, virtualpointer); + wl_signal_add(&virtual_pointer_mgr->events.new_virtual_pointer, + &new_virtual_pointer); seat = wlr_seat_create(dpy, "seat0"); - LISTEN_STATIC(&seat->events.request_set_cursor, setcursor); - LISTEN_STATIC(&seat->events.request_set_selection, setsel); - LISTEN_STATIC(&seat->events.request_set_primary_selection, setpsel); - LISTEN_STATIC(&seat->events.request_start_drag, requeststartdrag); - LISTEN_STATIC(&seat->events.start_drag, startdrag); + wl_signal_add(&seat->events.request_set_cursor, &request_cursor); + wl_signal_add(&seat->events.request_set_selection, &request_set_sel); + wl_signal_add(&seat->events.request_set_primary_selection, &request_set_psel); + wl_signal_add(&seat->events.request_start_drag, &request_start_drag); + wl_signal_add(&seat->events.start_drag, &start_drag); kb_group = createkeyboardgroup(); wl_list_init(&kb_group->destroy.link); output_mgr = wlr_output_manager_v1_create(dpy); - LISTEN_STATIC(&output_mgr->events.apply, outputmgrapply); - LISTEN_STATIC(&output_mgr->events.test, outputmgrtest); + wl_signal_add(&output_mgr->events.apply, &output_mgr_apply); + wl_signal_add(&output_mgr->events.test, &output_mgr_test); /* Make sure XWayland clients don't connect to the parent X server, * e.g when running in the x11 backend or the wayland backend and the @@ -2580,8 +2616,8 @@ setup(void) * It will be started when the first X client is started. */ if ((xwayland = wlr_xwayland_create(dpy, compositor, 1))) { - LISTEN_STATIC(&xwayland->events.ready, xwaylandready); - LISTEN_STATIC(&xwayland->events.new_surface, createnotifyx11); + wl_signal_add(&xwayland->events.ready, &xwayland_ready); + wl_signal_add(&xwayland->events.new_surface, &new_xwayland_surface); setenv("DISPLAY", xwayland->display_name, 1); } else { From 9a9f67db1c9a1b05d4edbaa310d78a76f3831b54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Sun, 19 Jan 2025 14:04:03 -0600 Subject: [PATCH 53/75] unlink global listeners on destroy Continuation of 0925fe956aeddb983875f0fd892e9049e2d8cb76 --- dwl.c | 49 +++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 39 insertions(+), 10 deletions(-) diff --git a/dwl.c b/dwl.c index cfe7772..f7ae6fb 100644 --- a/dwl.c +++ b/dwl.c @@ -252,6 +252,7 @@ static void chvt(const Arg *arg); static void checkidleinhibitor(struct wlr_surface *exclude); static void cleanup(void); static void cleanupmon(struct wl_listener *listener, void *data); +static void cleanuplisteners(void); static void closemon(Monitor *m); static void commitlayersurfacenotify(struct wl_listener *listener, void *data); static void commitnotify(struct wl_listener *listener, void *data); @@ -279,7 +280,6 @@ static void destroylocksurface(struct wl_listener *listener, void *data); static void destroynotify(struct wl_listener *listener, void *data); static void destroypointerconstraint(struct wl_listener *listener, void *data); static void destroysessionlock(struct wl_listener *listener, void *data); -static void destroysessionmgr(struct wl_listener *listener, void *data); static void destroykeyboardgroup(struct wl_listener *listener, void *data); static Monitor *dirtomon(enum wlr_direction dir); static void focusclient(Client *c, int lift); @@ -435,7 +435,6 @@ static struct wl_listener request_set_shape = {.notify = setcursorshape}; static struct wl_listener request_start_drag = {.notify = requeststartdrag}; static struct wl_listener start_drag = {.notify = startdrag}; static struct wl_listener session_lock_create_lock = {.notify = locksession}; -static struct wl_listener session_lock_mgr_destroy = {.notify = destroysessionmgr}; #ifdef XWAYLAND static void activatex11(struct wl_listener *listener, void *data); @@ -696,6 +695,7 @@ checkidleinhibitor(struct wlr_surface *exclude) void cleanup(void) { + cleanuplisteners(); #ifdef XWAYLAND wlr_xwayland_destroy(xwayland); xwayland = NULL; @@ -745,6 +745,43 @@ cleanupmon(struct wl_listener *listener, void *data) free(m); } +void +cleanuplisteners(void) +{ + wl_list_remove(&cursor_axis.link); + wl_list_remove(&cursor_button.link); + wl_list_remove(&cursor_frame.link); + wl_list_remove(&cursor_motion.link); + wl_list_remove(&cursor_motion_absolute.link); + wl_list_remove(&gpu_reset.link); + wl_list_remove(&idle_inhibitor_create.link); + wl_list_remove(&layout_change.link); + wl_list_remove(&new_input.link); + wl_list_remove(&new_virtual_keyboard.link); + wl_list_remove(&new_virtual_pointer.link); + wl_list_remove(&new_pointer_constraint.link); + wl_list_remove(&new_output.link); + wl_list_remove(&new_xdg_surface.link); + wl_list_remove(&new_xdg_decoration.link); + wl_list_remove(&new_xdg_popup.link); + wl_list_remove(&new_layer_shell_surface.link); + wl_list_remove(&output_mgr_apply.link); + wl_list_remove(&output_mgr_test.link); + wl_list_remove(&output_power_mgr_set_mode.link); + wl_list_remove(&request_activate.link); + wl_list_remove(&request_cursor.link); + wl_list_remove(&request_set_psel.link); + wl_list_remove(&request_set_sel.link); + wl_list_remove(&request_set_shape.link); + wl_list_remove(&request_start_drag.link); + wl_list_remove(&start_drag.link); + wl_list_remove(&session_lock_create_lock.link); +#ifdef XWAYLAND + wl_list_remove(&new_xwayland_surface.link); + wl_list_remove(&xwayland_ready.link); +#endif +} + void closemon(Monitor *m) { @@ -1325,13 +1362,6 @@ destroysessionlock(struct wl_listener *listener, void *data) destroylock(lock, 0); } -void -destroysessionmgr(struct wl_listener *listener, void *data) -{ - wl_list_remove(&session_lock_create_lock.link); - wl_list_remove(&session_lock_mgr_destroy.link); -} - void destroykeyboardgroup(struct wl_listener *listener, void *data) { @@ -2528,7 +2558,6 @@ setup(void) session_lock_mgr = wlr_session_lock_manager_v1_create(dpy); wl_signal_add(&session_lock_mgr->events.new_lock, &session_lock_create_lock); - wl_signal_add(&session_lock_mgr->events.destroy, &session_lock_mgr_destroy); locked_bg = wlr_scene_rect_create(layers[LyrBlock], sgeom.width, sgeom.height, (float [4]){0.1f, 0.1f, 0.1f, 1.0f}); wlr_scene_node_set_enabled(&locked_bg->node, 0); From da13a9568312ccfdb1c5e527abf773d7512f3f14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Sun, 19 Jan 2025 14:05:54 -0600 Subject: [PATCH 54/75] destroy keyboard group after unlinking listeners Last commit addressing the issue mentioned in 0925fe956aeddb983875f0fd892e9049e2d8cb76 --- dwl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dwl.c b/dwl.c index f7ae6fb..1ff1167 100644 --- a/dwl.c +++ b/dwl.c @@ -1367,10 +1367,10 @@ destroykeyboardgroup(struct wl_listener *listener, void *data) { KeyboardGroup *group = wl_container_of(listener, group, destroy); wl_event_source_remove(group->key_repeat_source); - wlr_keyboard_group_destroy(group->wlr_group); wl_list_remove(&group->key.link); wl_list_remove(&group->modifiers.link); wl_list_remove(&group->destroy.link); + wlr_keyboard_group_destroy(group->wlr_group); free(group); } From d1c2f434983562bd7d2ace15ab0c05155be603bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Sun, 19 Jan 2025 17:24:01 -0600 Subject: [PATCH 55/75] rename some listeners To keep consistency with the rest of listeners --- dwl.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/dwl.c b/dwl.c index 1ff1167..ad21e1b 100644 --- a/dwl.c +++ b/dwl.c @@ -413,17 +413,17 @@ static struct wl_listener cursor_frame = {.notify = cursorframe}; static struct wl_listener cursor_motion = {.notify = motionrelative}; static struct wl_listener cursor_motion_absolute = {.notify = motionabsolute}; static struct wl_listener gpu_reset = {.notify = gpureset}; -static struct wl_listener idle_inhibitor_create = {.notify = createidleinhibitor}; static struct wl_listener layout_change = {.notify = updatemons}; -static struct wl_listener new_input = {.notify = inputdevice}; +static struct wl_listener new_idle_inhibitor = {.notify = createidleinhibitor}; +static struct wl_listener new_input_device = {.notify = inputdevice}; static struct wl_listener new_virtual_keyboard = {.notify = virtualkeyboard}; static struct wl_listener new_virtual_pointer = {.notify = virtualpointer}; static struct wl_listener new_pointer_constraint = {.notify = createpointerconstraint}; static struct wl_listener new_output = {.notify = createmon}; -static struct wl_listener new_xdg_surface = {.notify = createnotify}; +static struct wl_listener new_xdg_toplevel = {.notify = createnotify}; static struct wl_listener new_xdg_popup = {.notify = createpopup}; static struct wl_listener new_xdg_decoration = {.notify = createdecoration}; -static struct wl_listener new_layer_shell_surface = {.notify = createlayersurface}; +static struct wl_listener new_layer_surface = {.notify = createlayersurface}; static struct wl_listener output_mgr_apply = {.notify = outputmgrapply}; static struct wl_listener output_mgr_test = {.notify = outputmgrtest}; static struct wl_listener output_power_mgr_set_mode = {.notify = powermgrsetmode}; @@ -431,10 +431,10 @@ static struct wl_listener request_activate = {.notify = urgent}; static struct wl_listener request_cursor = {.notify = setcursor}; static struct wl_listener request_set_psel = {.notify = setpsel}; static struct wl_listener request_set_sel = {.notify = setsel}; -static struct wl_listener request_set_shape = {.notify = setcursorshape}; +static struct wl_listener request_set_cursor_shape = {.notify = setcursorshape}; static struct wl_listener request_start_drag = {.notify = requeststartdrag}; static struct wl_listener start_drag = {.notify = startdrag}; -static struct wl_listener session_lock_create_lock = {.notify = locksession}; +static struct wl_listener new_session_lock = {.notify = locksession}; #ifdef XWAYLAND static void activatex11(struct wl_listener *listener, void *data); @@ -754,17 +754,17 @@ cleanuplisteners(void) wl_list_remove(&cursor_motion.link); wl_list_remove(&cursor_motion_absolute.link); wl_list_remove(&gpu_reset.link); - wl_list_remove(&idle_inhibitor_create.link); + wl_list_remove(&new_idle_inhibitor.link); wl_list_remove(&layout_change.link); - wl_list_remove(&new_input.link); + wl_list_remove(&new_input_device.link); wl_list_remove(&new_virtual_keyboard.link); wl_list_remove(&new_virtual_pointer.link); wl_list_remove(&new_pointer_constraint.link); wl_list_remove(&new_output.link); - wl_list_remove(&new_xdg_surface.link); + wl_list_remove(&new_xdg_toplevel.link); wl_list_remove(&new_xdg_decoration.link); wl_list_remove(&new_xdg_popup.link); - wl_list_remove(&new_layer_shell_surface.link); + wl_list_remove(&new_layer_surface.link); wl_list_remove(&output_mgr_apply.link); wl_list_remove(&output_mgr_test.link); wl_list_remove(&output_power_mgr_set_mode.link); @@ -772,10 +772,10 @@ cleanuplisteners(void) wl_list_remove(&request_cursor.link); wl_list_remove(&request_set_psel.link); wl_list_remove(&request_set_sel.link); - wl_list_remove(&request_set_shape.link); + wl_list_remove(&request_set_cursor_shape.link); wl_list_remove(&request_start_drag.link); wl_list_remove(&start_drag.link); - wl_list_remove(&session_lock_create_lock.link); + wl_list_remove(&new_session_lock.link); #ifdef XWAYLAND wl_list_remove(&new_xwayland_surface.link); wl_list_remove(&xwayland_ready.link); @@ -2545,19 +2545,19 @@ setup(void) wl_list_init(&fstack); xdg_shell = wlr_xdg_shell_create(dpy, 6); - wl_signal_add(&xdg_shell->events.new_toplevel, &new_xdg_surface); + wl_signal_add(&xdg_shell->events.new_toplevel, &new_xdg_toplevel); wl_signal_add(&xdg_shell->events.new_popup, &new_xdg_popup); layer_shell = wlr_layer_shell_v1_create(dpy, 3); - wl_signal_add(&layer_shell->events.new_surface, &new_layer_shell_surface); + wl_signal_add(&layer_shell->events.new_surface, &new_layer_surface); idle_notifier = wlr_idle_notifier_v1_create(dpy); idle_inhibit_mgr = wlr_idle_inhibit_v1_create(dpy); - wl_signal_add(&idle_inhibit_mgr->events.new_inhibitor, &idle_inhibitor_create); + wl_signal_add(&idle_inhibit_mgr->events.new_inhibitor, &new_idle_inhibitor); session_lock_mgr = wlr_session_lock_manager_v1_create(dpy); - wl_signal_add(&session_lock_mgr->events.new_lock, &session_lock_create_lock); + wl_signal_add(&session_lock_mgr->events.new_lock, &new_session_lock); locked_bg = wlr_scene_rect_create(layers[LyrBlock], sgeom.width, sgeom.height, (float [4]){0.1f, 0.1f, 0.1f, 1.0f}); wlr_scene_node_set_enabled(&locked_bg->node, 0); @@ -2605,7 +2605,7 @@ setup(void) wl_signal_add(&cursor->events.frame, &cursor_frame); cursor_shape_mgr = wlr_cursor_shape_manager_v1_create(dpy, 1); - wl_signal_add(&cursor_shape_mgr->events.request_set_shape, &request_set_shape); + wl_signal_add(&cursor_shape_mgr->events.request_set_shape, &request_set_cursor_shape); /* * Configures a seat, which is a single "seat" at which a user sits and @@ -2613,7 +2613,7 @@ setup(void) * pointer, touch, and drawing tablet device. We also rig up a listener to * let us know when new input devices are available on the backend. */ - wl_signal_add(&backend->events.new_input, &new_input); + wl_signal_add(&backend->events.new_input, &new_input_device); virtual_keyboard_mgr = wlr_virtual_keyboard_manager_v1_create(dpy); wl_signal_add(&virtual_keyboard_mgr->events.new_virtual_keyboard, &new_virtual_keyboard); From aa69ed81b558f74e470e69cdcd442f9048ee624c Mon Sep 17 00:00:00 2001 From: korei999 Date: Sun, 2 Feb 2025 01:38:47 +0200 Subject: [PATCH 56/75] allocate with LISTEN_STATIC Fixes: https://codeberg.org/dwl/dwl/issues/723 Supersedes: https://codeberg.org/dwl/dwl/pulls/724 --- dwl.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/dwl.c b/dwl.c index ad21e1b..ec4ca86 100644 --- a/dwl.c +++ b/dwl.c @@ -79,7 +79,7 @@ #define END(A) ((A) + LENGTH(A)) #define TAGMASK ((1u << TAGCOUNT) - 1) #define LISTEN(E, L, H) wl_signal_add((E), ((L)->notify = (H), (L))) -#define LISTEN_STATIC(E, H) do { static struct wl_listener _l = {.notify = (H)}; wl_signal_add((E), &_l); } while (0) +#define LISTEN_STATIC(E, H) do { struct wl_listener *_l = ecalloc(1, sizeof(*_l)); _l->notify = (H); wl_signal_add((E), _l); } while (0) /* enums */ enum { CurNormal, CurPressed, CurMove, CurResize }; /* cursor */ @@ -906,6 +906,7 @@ commitpopup(struct wl_listener *listener, void *data) box.y -= (type == LayerShell ? l->scene->node.y : c->geom.y); wlr_xdg_popup_unconstrain_from_box(popup, &box); wl_list_remove(&listener->link); + free(listener); } void @@ -1246,6 +1247,7 @@ destroydragicon(struct wl_listener *listener, void *data) focusclient(focustop(selmon), 1); motionnotify(0, NULL, 0, 0, 0, 0); wl_list_remove(&listener->link); + free(listener); } void @@ -1255,6 +1257,7 @@ destroyidleinhibitor(struct wl_listener *listener, void *data) * at this point the idle inhibitor is still in the list of the manager */ checkidleinhibitor(wlr_surface_get_root_surface(data)); wl_list_remove(&listener->link); + free(listener); } void From e0f531d5087cbd1223577c77262ec7476c157088 Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Wed, 12 Mar 2025 16:27:47 +0800 Subject: [PATCH 57/75] fix: crash when open some x11 app --- dwl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dwl.c b/dwl.c index ec4ca86..395b81d 100644 --- a/dwl.c +++ b/dwl.c @@ -3148,7 +3148,7 @@ sethints(struct wl_listener *listener, void *data) { Client *c = wl_container_of(listener, c, set_hints); struct wlr_surface *surface = client_surface(c); - if (c == focustop(selmon)) + if (c == focustop(selmon) || !c->surface.xwayland->hints) return; c->isurgent = xcb_icccm_wm_hints_get_urgency(c->surface.xwayland->hints); From 4456f4536a483c127909151a84d7b62da4f40e8b Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Wed, 12 Mar 2025 16:17:44 +0800 Subject: [PATCH 58/75] fix: shouldn't configure uninitialized layer_surface --- dwl.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dwl.c b/dwl.c index 395b81d..4816159 100644 --- a/dwl.c +++ b/dwl.c @@ -551,6 +551,9 @@ arrangelayer(Monitor *m, struct wl_list *list, struct wlr_box *usable_area, int wl_list_for_each(l, list, link) { struct wlr_layer_surface_v1 *layer_surface = l->layer_surface; + if (!layer_surface->initialized) + continue; + if (exclusive != (layer_surface->current.exclusive_zone > 0)) continue; From faa56cc9b9718e1b195a02682836fe040963eb7d Mon Sep 17 00:00:00 2001 From: fauxmight Date: Thu, 24 Apr 2025 04:28:44 +0000 Subject: [PATCH 59/75] Update README.md --- README.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 1bcc36e..b8e3a3a 100644 --- a/README.md +++ b/README.md @@ -15,10 +15,11 @@ philosophy. Like dwm, dwl is: ## Getting Started: ### Latest semi-stable [release] -This is probably where you want to start. This builds against the dependent -packages' versions currently shipping in major distributions. If your -distribution's wlroots version is older, use an earlier dwl [release] or [0.x -branch]. +This is probably where you want to start. This builds against the [wlroots] +versions currently shipping in major distributions. If your +distribution's `wlroots` version is older, use an earlier dwl [release]. +The `wlroots` version against which a given `dwl` release builds is specified +with each release on the [release] page ### Development branch [main] Active development progresses on the `main` branch. The `main` branch is built @@ -181,6 +182,7 @@ inspiration, and to the various contributors to the project, including: - Stivvo for output management and fullscreen support, and patch maintenance +[wlroots]: https://gitlab.freedesktop.org/wlroots [`systemd --user`]: https://wiki.archlinux.org/title/Systemd/User [#dwl on Libera Chat]: https://web.libera.chat/?channels=#dwl [0.7-rc1]: https://codeberg.org/dwl/dwl/releases/tag/v0.7-rc1 From de57f6c315f0ad70b68e083ae9a1822e43f01586 Mon Sep 17 00:00:00 2001 From: A Frederick Christensen Date: Sat, 7 Jun 2025 00:25:30 -0500 Subject: [PATCH 60/75] Cleanup comments --- client.h | 4 ++-- config.mk | 2 +- dwl.c | 49 +++++++++++++++++++++++++------------------------ 3 files changed, 28 insertions(+), 27 deletions(-) diff --git a/client.h b/client.h index f1e2ab5..d9f90bb 100644 --- a/client.h +++ b/client.h @@ -264,8 +264,8 @@ client_is_stopped(Client *c) wl_client_get_credentials(c->surface.xdg->client->client, &pid, NULL, NULL); if (waitid(P_PID, pid, &in, WNOHANG|WCONTINUED|WSTOPPED|WNOWAIT) < 0) { - /* This process is not our child process, while is very unluckely that - * it is stopped, in order to do not skip frames assume that it is. */ + /* This process is not our child process, while is very unlikely that + * it is stopped, in order to do not skip frames, assume that it is. */ if (errno == ECHILD) return 1; } else if (in.si_pid) { diff --git a/config.mk b/config.mk index e2f1816..eb08a05 100644 --- a/config.mk +++ b/config.mk @@ -11,7 +11,7 @@ DATADIR = $(PREFIX)/share WLR_INCS = `$(PKG_CONFIG) --cflags wlroots-0.19` WLR_LIBS = `$(PKG_CONFIG) --libs wlroots-0.19` -# Allow using an alternative wlroots installations +# Allow using an alternative wlroots installation # This has to have all the includes required by wlroots, e.g: # Assuming wlroots git repo is "${PWD}/wlroots" and you only ran "meson setup build && ninja -C build" #WLR_INCS = -I/usr/include/pixman-1 -I/usr/include/elogind -I/usr/include/libdrm \ diff --git a/dwl.c b/dwl.c index 4816159..775dadf 100644 --- a/dwl.c +++ b/dwl.c @@ -609,8 +609,8 @@ axisnotify(struct wl_listener *listener, void *data) * for example when you move the scroll wheel. */ struct wlr_pointer_axis_event *event = data; wlr_idle_notifier_v1_notify_activity(idle_notifier, seat); - /* TODO: allow usage of scroll whell for mousebindings, it can be implemented - * checking the event's orientation and the delta of the event */ + /* TODO: allow usage of scroll wheel for mousebindings, it can be implemented + * by checking the event's orientation and the delta of the event */ /* Notify the client with pointer focus of the axis event. */ wlr_seat_pointer_notify_axis(seat, event->time_msec, event->orientation, event->delta, @@ -712,8 +712,8 @@ cleanup(void) destroykeyboardgroup(&kb_group->destroy, NULL); - /* If it's not destroyed manually it will cause a use-after-free of wlr_seat. - * Destroy it until it's fixed in the wlroots side */ + /* If it's not destroyed manually, it will cause a use-after-free of wlr_seat. + * Destroy it until it's fixed on the wlroots side */ wlr_backend_destroy(backend); wl_display_destroy(dpy); @@ -858,7 +858,7 @@ commitnotify(struct wl_listener *listener, void *data) /* * Get the monitor this client will be rendered on * Note that if the user set a rule in which the client is placed on - * a different monitor based on its title this will likely select + * a different monitor based on its title, this will likely select * a wrong monitor. */ applyrules(c); @@ -1212,7 +1212,7 @@ cursorconstrain(struct wlr_pointer_constraint_v1 *constraint) void cursorframe(struct wl_listener *listener, void *data) { - /* This event is forwarded by the cursor when a pointer emits an frame + /* This event is forwarded by the cursor when a pointer emits a frame * event. Frame events are sent after regular pointer events to group * multiple events together. For instance, two axis events may happen at the * same time, in which case a frame event won't be sent in between. */ @@ -1508,7 +1508,7 @@ focusstack(const Arg *arg) focusclient(c, 1); } -/* We probably should change the name of this, it sounds like +/* We probably should change the name of this: it sounds like it * will focus the topmost client of this mon, when actually will * only return that client */ Client * @@ -1780,8 +1780,8 @@ mapnotify(struct wl_listener *listener, void *data) /* Set initial monitor, tags, floating status, and focus: * we always consider floating, clients that have parent and thus - * we set the same tags and monitor than its parent, if not - * try to apply rules for them */ + * we set the same tags and monitor as its parent. + * If there is no parent, apply rules */ if ((p = client_get_parent(c))) { c->isfloating = 1; setmon(c, p->mon, p->tags); @@ -1841,8 +1841,7 @@ motionabsolute(struct wl_listener *listener, void *data) * motion event, from 0..1 on each axis. This happens, for example, when * wlroots is running under a Wayland window rather than KMS+DRM, and you * move the mouse over the window. You could enter the window from any edge, - * so we have to warp the mouse there. There is also some hardware which - * emits these events. */ + * so we have to warp the mouse there. Also, some hardware emits these events. */ struct wlr_pointer_motion_absolute_event *event = data; double lx, ly, dx, dy; @@ -2027,9 +2026,9 @@ apply_or_test: ok &= test ? wlr_output_test_state(wlr_output, &state) : wlr_output_commit_state(wlr_output, &state); - /* Don't move monitors if position wouldn't change, this to avoid - * wlroots marking the output as manually configured. - * wlr_output_layout_add does not like disabled outputs */ + /* Don't move monitors if position wouldn't change. This avoids + * wlroots marking the output as manually configured. + * wlr_output_layout_add does not like disabled outputs */ if (!test && wlr_output->enabled && (m->m.x != config_head->state.x || m->m.y != config_head->state.y)) wlr_output_layout_add(output_layout, wlr_output, config_head->state.x, config_head->state.y); @@ -2266,8 +2265,10 @@ run(char *startup_cmd) close(piperw[0]); } - /* Mark stdout as non-blocking to avoid people who does not close stdin - * nor consumes it in their startup script getting dwl frozen */ + /* Mark stdout as non-blocking to avoid the startup script + * causing dwl to freeze when a user neither closes stdin + * nor consumes standard input in his startup script */ + if (fd_set_nonblock(STDOUT_FILENO) < 0) close(STDOUT_FILENO); @@ -2278,7 +2279,7 @@ run(char *startup_cmd) selmon = xytomon(cursor->x, cursor->y); /* TODO hack to get cursor to display in its initial location (100, 100) - * instead of (0, 0) and then jumping. still may not be fully + * instead of (0, 0) and then jumping. Still may not be fully * initialized, as the image/coordinates are not transformed for the * monitor when displayed here */ wlr_cursor_warp_closest(cursor, NULL, cursor->x, cursor->y); @@ -2301,7 +2302,7 @@ setcursor(struct wl_listener *listener, void *data) * event, which will result in the client requesting set the cursor surface */ if (cursor_mode != CurNormal && cursor_mode != CurPressed) return; - /* This can be sent by any client, so we check to make sure this one is + /* This can be sent by any client, so we check to make sure this one * actually has pointer focus first. If so, we can tell the cursor to * use the provided surface as the cursor image. It will set the * hardware cursor on the output that it's currently on and continue to @@ -2317,7 +2318,7 @@ setcursorshape(struct wl_listener *listener, void *data) struct wlr_cursor_shape_manager_v1_request_set_shape_event *event = data; if (cursor_mode != CurNormal && cursor_mode != CurPressed) return; - /* This can be sent by any client, so we check to make sure this one is + /* This can be sent by any client, so we check to make sure this one * actually has pointer focus first. If so, we can tell the cursor to * use the provided cursor shape. */ if (event->seat_client == seat->pointer_state.focused_client) @@ -2420,7 +2421,7 @@ setpsel(struct wl_listener *listener, void *data) { /* This event is raised by the seat when a client wants to set the selection, * usually when the user copies something. wlroots allows compositors to - * ignore such requests if they so choose, but in dwl we always honor + * ignore such requests if they so choose, but in dwl we always honor them */ struct wlr_seat_request_set_primary_selection_event *event = data; wlr_seat_set_primary_selection(seat, event->source, event->serial); @@ -2431,7 +2432,7 @@ setsel(struct wl_listener *listener, void *data) { /* This event is raised by the seat when a client wants to set the selection, * usually when the user copies something. wlroots allows compositors to - * ignore such requests if they so choose, but in dwl we always honor + * ignore such requests if they so choose, but in dwl we always honor them */ struct wlr_seat_request_set_selection_event *event = data; wlr_seat_set_selection(seat, event->source, event->serial); @@ -2478,9 +2479,9 @@ setup(void) wl_signal_add(&drw->events.lost, &gpu_reset); /* Create shm, drm and linux_dmabuf interfaces by ourselves. - * The simplest way is call: + * The simplest way is to call: * wlr_renderer_init_wl_display(drw); - * but we need to create manually the linux_dmabuf interface to integrate it + * but we need to create the linux_dmabuf interface manually to integrate it * with wlr_scene. */ wlr_renderer_init_wl_shm(drw, dpy); @@ -2529,7 +2530,7 @@ setup(void) power_mgr = wlr_output_power_manager_v1_create(dpy); wl_signal_add(&power_mgr->events.set_mode, &output_power_mgr_set_mode); - /* Creates an output layout, which a wlroots utility for working with an + /* Creates an output layout, which is a wlroots utility for working with an * arrangement of screens in a physical layout. */ output_layout = wlr_output_layout_create(dpy); wl_signal_add(&output_layout->events.change, &layout_change); From 7d2415bfe854cccc2bcf2709fecc1eaacddbe903 Mon Sep 17 00:00:00 2001 From: mcsimw Date: Fri, 16 May 2025 06:24:58 +0000 Subject: [PATCH 61/75] Update config.mk compiles and works fine on wlroots-0.20 --- config.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config.mk b/config.mk index eb08a05..f641d04 100644 --- a/config.mk +++ b/config.mk @@ -8,8 +8,8 @@ PREFIX = /usr/local MANDIR = $(PREFIX)/share/man DATADIR = $(PREFIX)/share -WLR_INCS = `$(PKG_CONFIG) --cflags wlroots-0.19` -WLR_LIBS = `$(PKG_CONFIG) --libs wlroots-0.19` +WLR_INCS = `$(PKG_CONFIG) --cflags wlroots-0.20` +WLR_LIBS = `$(PKG_CONFIG) --libs wlroots-0.20` # Allow using an alternative wlroots installation # This has to have all the includes required by wlroots, e.g: From 78e75a83a4541d0fd4c5b0be56057380a5fb639e Mon Sep 17 00:00:00 2001 From: A Frederick Christensen Date: Mon, 9 Jun 2025 00:18:17 -0500 Subject: [PATCH 62/75] Revert "Update config.mk" This reverts commit 7d2415bfe854cccc2bcf2709fecc1eaacddbe903. Will stick with wlroots 0.19 for now. --- config.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config.mk b/config.mk index f641d04..eb08a05 100644 --- a/config.mk +++ b/config.mk @@ -8,8 +8,8 @@ PREFIX = /usr/local MANDIR = $(PREFIX)/share/man DATADIR = $(PREFIX)/share -WLR_INCS = `$(PKG_CONFIG) --cflags wlroots-0.20` -WLR_LIBS = `$(PKG_CONFIG) --libs wlroots-0.20` +WLR_INCS = `$(PKG_CONFIG) --cflags wlroots-0.19` +WLR_LIBS = `$(PKG_CONFIG) --libs wlroots-0.19` # Allow using an alternative wlroots installation # This has to have all the includes required by wlroots, e.g: From d1880b44223701c91b51b319fc69a0f63044f861 Mon Sep 17 00:00:00 2001 From: Nikita Ivanov Date: Tue, 4 Feb 2025 20:51:06 +0100 Subject: [PATCH 63/75] Fix crash disabling monitor with locked surface --- dwl.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dwl.c b/dwl.c index 775dadf..5beef8b 100644 --- a/dwl.c +++ b/dwl.c @@ -739,6 +739,8 @@ cleanupmon(struct wl_listener *listener, void *data) wl_list_remove(&m->frame.link); wl_list_remove(&m->link); wl_list_remove(&m->request_state.link); + if (m->lock_surface) + destroylocksurface(&m->destroy_lock_surface, NULL); m->wlr_output->data = NULL; wlr_output_layout_remove(output_layout, m->wlr_output); wlr_scene_output_destroy(m->scene_output); From 02f8744a486713bfac41661e7c5590ec11ec8989 Mon Sep 17 00:00:00 2001 From: kilpilainen <> Date: Thu, 27 Mar 2025 16:07:45 +0200 Subject: [PATCH 64/75] Use `all-scroll` instead of `fleur` xcursor shape for window dragging When there are no xcursor themes available, Wayland uses its own built-in shapes [1]. Wayland (and thus to extend wlroots) is based on the XDG's cursor spec [2], which itself is based on CSS' [3][4], neither of which define `fleur` shape. So dwl, without any external themes, falls back to `default` shape when dragging a window. There is `all-scroll` shape that is being symlinked to (or vice versa) by `move`, `dnd-move`, `grabbed` and `fleur` shapes by various themes. Since `all-scroll` is being symlinked to anyway, and has been part of all relevant specs as the shape for this use case for a very long time now, use it instead. [1] https://gitlab.freedesktop.org/wayland/wayland/-/blob/main/cursor/cursor-data.h#L559 [2] https://www.freedesktop.org/wiki/Specifications/cursor-spec [3] https://drafts.csswg.org/css-ui/#cursor [4] https://developer.mozilla.org/en-US/docs/Web/CSS/cursor --- dwl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dwl.c b/dwl.c index 5beef8b..76b7755 100644 --- a/dwl.c +++ b/dwl.c @@ -1965,7 +1965,7 @@ moveresize(const Arg *arg) case CurMove: grabcx = (int)round(cursor->x) - grabc->geom.x; grabcy = (int)round(cursor->y) - grabc->geom.y; - wlr_cursor_set_xcursor(cursor, cursor_mgr, "fleur"); + wlr_cursor_set_xcursor(cursor, cursor_mgr, "all-scroll"); break; case CurResize: /* Doesn't work for X11 output - the next absolute motion event From 59c99308b0cad19f48fa0586aca40eaec58695a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Sun, 28 Jul 2024 12:28:31 -0600 Subject: [PATCH 65/75] drop CAVEATS section from the man page Since 71f11e6cf63289d51f152469a0da81a85fe2608c it is not longer the case --- dwl.1 | 8 -------- 1 file changed, 8 deletions(-) diff --git a/dwl.1 b/dwl.1 index 780c78f..f254096 100644 --- a/dwl.1 +++ b/dwl.1 @@ -146,13 +146,5 @@ with s6 in the background: .Xr wmenu 1 , .Xr dwm 1 , .Xr xkeyboard-config 7 -.Sh CAVEATS -The child process's standard input is connected with a pipe to -.Nm . -If the child process neither reads from the pipe nor closes its -standard input, -.Nm -will freeze after a while due to it blocking when writing to the full -pipe buffer. .Sh BUGS All of them. From 9dbce43a69988b62430f6060f30049fb6ab036f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Fri, 27 Sep 2024 21:18:47 -0600 Subject: [PATCH 66/75] document mouse button actions [sevz: commit message is mine. The content was written by scottro11 and shared in https://codeberg.org/dwl/dwl/issues/697] Closes: https://codeberg.org/dwl/dwl/issues/697 --- dwl.1 | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/dwl.1 b/dwl.1 index f254096..65648f4 100644 --- a/dwl.1 +++ b/dwl.1 @@ -100,6 +100,16 @@ Quit .Nm . .El These might differ depending on your keyboard layout. +.Sh Mouse commands +.Bl -tag -width 20n -offset indent -compact +.It Mod-Button1 +Move focused window while dragging. Tiled windows will be toggled to the floating state. +.It Mod-Button2 +Toggles focused window between floating and tiled state. +.It Mod-Button3 +Resize focused window while dragging. Tiled windows will be toggled to +the +floating state. .Sh ENVIRONMENT These environment variables are used by .Nm : From 661e1ee38ceeb6e8e41b32ea13dc2eec591afba8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Fri, 27 Sep 2024 22:20:16 -0600 Subject: [PATCH 67/75] Use a subsection for mouse commands also add missing ".El", s/Toggles/Toggle/ in second command and add newlines after a full stop --- dwl.1 | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/dwl.1 b/dwl.1 index 65648f4..fccf569 100644 --- a/dwl.1 +++ b/dwl.1 @@ -100,16 +100,17 @@ Quit .Nm . .El These might differ depending on your keyboard layout. -.Sh Mouse commands +.Ss Mouse commands .Bl -tag -width 20n -offset indent -compact .It Mod-Button1 -Move focused window while dragging. Tiled windows will be toggled to the floating state. +Move focused window while dragging. +Tiled windows will be toggled to the floating state. .It Mod-Button2 -Toggles focused window between floating and tiled state. +Toggle focused window between floating and tiled state. .It Mod-Button3 -Resize focused window while dragging. Tiled windows will be toggled to -the -floating state. +Resize focused window while dragging. +Tiled windows will be toggled to the floating state. +.El .Sh ENVIRONMENT These environment variables are used by .Nm : From 67ff29eb953b135d95371b462fc8f14e89d839f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Thu, 26 Dec 2024 21:10:36 -0600 Subject: [PATCH 68/75] document status output --- README.md | 2 +- dwl.1 | 105 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 102 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index b8e3a3a..b876fdb 100644 --- a/README.md +++ b/README.md @@ -103,7 +103,7 @@ automatically, you will need to configure it prior to launching `dwl`, e.g.: Information about selected layouts, current window title, app-id, and selected/occupied/urgent tags is written to the stdin of the `-s` command (see -the `printstatus()` function for details). This information can be used to +the `STATUS INFORMATION` section in `_dwl_(1)`). This information can be used to populate an external status bar with a script that parses the information. Failing to read this information will cause dwl to block, so if you do want to run a startup command that does not consume the status information, diff --git a/dwl.1 b/dwl.1 index fccf569..7fee870 100644 --- a/dwl.1 +++ b/dwl.1 @@ -37,7 +37,7 @@ starts a shell process running when starting. When stopping, it sends .Dv SIGTERM -to the child process and waits for it to exit. +to the child process group and waits for it to exit. .Pp Users are encouraged to customize .Nm @@ -55,10 +55,10 @@ Move window to a single tag. Toggle tag for window. .It Mod-p Spawn -.Nm wmenu-run . +.Xr wmenu-run 1 . .It Mod-Shift-Return Spawn -.Nm foot . +.Xr foot 1 . .It Mod-[jk] Move focus down/up the stack. .It Mod-[id] @@ -111,6 +111,103 @@ Toggle focused window between floating and tiled state. Resize focused window while dragging. Tiled windows will be toggled to the floating state. .El +.Sh STATUS INFORMATION +.Nm +writes its status information to standard output. +If the +.Fl s +option is given, the status information is written to the standard input of the +child process instead. +.Pp +Said information has the following format: +.Bd -ragged -offset indent +.Ar +.Ar +.Ar +.Ed +.Pp +.Bl -tag -width 11n -offset 0 -compact +.It Ar +is the name given to the output. +.It Ar +is one of (in order) +.Em title , +.Em appid , +.Em fullscreen , +.Em floating , +.Em selmon , +.Em tags , +.Em layout . +.It Ar +changes depending on +.Ar . +.Bl -tag -width 10n -compact +.It Em title +The title of the focused window on +.Ar +or nothing if there is no focused window. +.It Em appid +The app_id of the focused window on +.Ar +or nothing if there is no focused window. +.It Em fullscreen +Prints 1 if the focused window on +.Ar +is in fullscreen state, otherwise prints 0. If there is no focused +window it prints nothing. +.It Em floating +Prints 1 if the focused window on +.Ar +is in floating state, otherwise prints 0. If there is no focused +window it prints nothing. +.It Em selmon +Prints 1 if +.Ar +is the selected monitor, otherwise prints 0. +.It Em tags +Prints four bitmasks in the following order: +.Bl -bullet -width 2n -compact +.It +Occupied tags of +.Ar . +.It +Selected tags of +.Ar . +.It +Tags of the focused window on +.Ar . +.It +Tags where a window on +.Ar +requested activation or has urgency hints. +.El +The bitmasks are 32-bit unsigned decimal integers. +.It Em layout +Prints the symbol of the current layout. +.El +.El +.Ss Examples +When there is a selected window: +.Bd -literal -offset indent +HDMI\-A\-1 title \(ti/source/repos/dwl > man \-l dwl.1 +HDMI\-A\-1 appid footclient +HDMI\-A\-1 fullscreen 0 +HDMI\-A\-1 floating 0 +HDMI\-A\-1 selmon 1 +HDMI\-A\-1 tags 271 4 4 0 +HDMI\-A\-1 layout [T] +.Ed +.Pp +When there is no selected window: +.Bd -literal -offset indent +HDMI\-A\-1 title +HDMI\-A\-1 appid +HDMI\-A\-1 fullscreen +HDMI\-A\-1 floating +HDMI\-A\-1 selmon 1 +HDMI\-A\-1 tags 271 512 0 0 +HDMI\-A\-1 layout [T] +.Ed .Sh ENVIRONMENT These environment variables are used by .Nm : @@ -153,9 +250,9 @@ Start with s6 in the background: .Dl dwl \-s \(aqs6\-svscan <&\-\(aq .Sh SEE ALSO +.Xr dwm 1 , .Xr foot 1 , .Xr wmenu 1 , -.Xr dwm 1 , .Xr xkeyboard-config 7 .Sh BUGS All of them. From ea263a0ed50d62033ca305fe7a4c5c36fddb4755 Mon Sep 17 00:00:00 2001 From: Guido Cella Date: Sat, 14 Jun 2025 22:27:25 +0200 Subject: [PATCH 69/75] float sub-windows matching a rule Currently when a rule that doesn't make windows floating matches, even sub-windows of float type get tiled rather than just the main window. This is inconsistent with dwm and other compositors. Fix this by making these windows floating after applying rules. Fixes #1142. --- dwl.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dwl.c b/dwl.c index 76b7755..12f441e 100644 --- a/dwl.c +++ b/dwl.c @@ -483,7 +483,6 @@ applyrules(Client *c) const Rule *r; Monitor *mon = selmon, *m; - c->isfloating = client_is_float_type(c); appid = client_get_appid(c); title = client_get_title(c); @@ -499,6 +498,8 @@ applyrules(Client *c) } } } + + c->isfloating |= client_is_float_type(c); setmon(c, mon, newtags); } From 90b8371707a136a2c8f2f20a3fa9d3dd7bd3ed5c Mon Sep 17 00:00:00 2001 From: fauxmight Date: Wed, 18 Jun 2025 14:52:15 +0200 Subject: [PATCH 70/75] Update README.md Correct description of default background color --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b876fdb..364e3ca 100644 --- a/README.md +++ b/README.md @@ -75,7 +75,7 @@ seatd daemon. When dwl is run with no arguments, it will launch the server and begin handling any shortcuts configured in `config.h`. There is no status bar or other decoration initially; these are instead clients that can be run within the -Wayland session. Do note that the default background color is black. This can be +Wayland session. Do note that the default background color is grey. This can be modified in `config.h`. If you would like to run a script or command automatically at startup, you can From 15bfffd87a6f9da0bc551db95c7c2a9a069b3708 Mon Sep 17 00:00:00 2001 From: A Frederick Christensen Date: Wed, 18 Jun 2025 23:41:14 -0500 Subject: [PATCH 71/75] fullscreen_bg defaults to black Per conversation at PR #1147 with @kilpilainen --- config.def.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.def.h b/config.def.h index 22d2171..95c2afa 100644 --- a/config.def.h +++ b/config.def.h @@ -12,7 +12,7 @@ static const float bordercolor[] = COLOR(0x444444ff); static const float focuscolor[] = COLOR(0x005577ff); static const float urgentcolor[] = COLOR(0xff0000ff); /* This conforms to the xdg-protocol. Set the alpha to zero to restore the old behavior */ -static const float fullscreen_bg[] = {0.1f, 0.1f, 0.1f, 1.0f}; /* You can also use glsl colors */ +static const float fullscreen_bg[] = {0.0f, 0.0f, 0.0f, 1.0f}; /* You can also use glsl colors */ /* tagging - TAGCOUNT must be no greater than 31 */ #define TAGCOUNT (9) From b28674e0ca4a9ecc92cb0607498e3db2df3d4c00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?= Date: Tue, 14 Jan 2025 12:34:20 -0600 Subject: [PATCH 72/75] add support for ext-image-copy-capture-v1 and ext-image-capture-source-v1 (wlroots!4545) References: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4545 --- Makefile | 4 ++++ dwl.c | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/Makefile b/Makefile index 578194f..3981fbb 100644 --- a/Makefile +++ b/Makefile @@ -20,6 +20,7 @@ all: dwl dwl: dwl.o util.o $(CC) dwl.o util.o $(DWLCFLAGS) $(LDFLAGS) $(LDLIBS) -o $@ dwl.o: dwl.c client.h config.h config.mk cursor-shape-v1-protocol.h \ + ext-image-copy-capture-v1-protocol.h \ pointer-constraints-unstable-v1-protocol.h wlr-layer-shell-unstable-v1-protocol.h \ wlr-output-power-management-unstable-v1-protocol.h xdg-shell-protocol.h util.o: util.c util.h @@ -33,6 +34,9 @@ WAYLAND_PROTOCOLS = `$(PKG_CONFIG) --variable=pkgdatadir wayland-protocols` cursor-shape-v1-protocol.h: $(WAYLAND_SCANNER) enum-header \ $(WAYLAND_PROTOCOLS)/staging/cursor-shape/cursor-shape-v1.xml $@ +ext-image-copy-capture-v1-protocol.h: + $(WAYLAND_SCANNER) enum-header \ + $(WAYLAND_PROTOCOLS)/staging/ext-image-copy-capture/ext-image-copy-capture-v1.xml $@ pointer-constraints-unstable-v1-protocol.h: $(WAYLAND_SCANNER) enum-header \ $(WAYLAND_PROTOCOLS)/unstable/pointer-constraints/pointer-constraints-unstable-v1.xml $@ diff --git a/dwl.c b/dwl.c index 12f441e..1dad6ac 100644 --- a/dwl.c +++ b/dwl.c @@ -24,6 +24,8 @@ #include #include #include +#include +#include #include #include #include @@ -2516,6 +2518,8 @@ setup(void) wlr_data_device_manager_create(dpy); wlr_export_dmabuf_manager_v1_create(dpy); wlr_screencopy_manager_v1_create(dpy); + wlr_ext_image_copy_capture_manager_v1_create(dpy, 1); + wlr_ext_output_image_capture_source_manager_v1_create(dpy, 1); wlr_data_control_manager_v1_create(dpy); wlr_primary_selection_v1_device_manager_create(dpy); wlr_viewporter_create(dpy); From ab4cb6e28365cf8754d6d3bdd293c05abfc27e26 Mon Sep 17 00:00:00 2001 From: A Frederick Christensen Date: Mon, 4 Aug 2025 16:27:34 -0500 Subject: [PATCH 73/75] Revert "add support for ext-image-copy-capture-v1 and ext-image-capture-source-v1 (wlroots!4545)" This reverts commit b28674e0ca4a9ecc92cb0607498e3db2df3d4c00. This PR is not yet finalized. (Screen freezes). --- Makefile | 4 ---- dwl.c | 4 ---- 2 files changed, 8 deletions(-) diff --git a/Makefile b/Makefile index 3981fbb..578194f 100644 --- a/Makefile +++ b/Makefile @@ -20,7 +20,6 @@ all: dwl dwl: dwl.o util.o $(CC) dwl.o util.o $(DWLCFLAGS) $(LDFLAGS) $(LDLIBS) -o $@ dwl.o: dwl.c client.h config.h config.mk cursor-shape-v1-protocol.h \ - ext-image-copy-capture-v1-protocol.h \ pointer-constraints-unstable-v1-protocol.h wlr-layer-shell-unstable-v1-protocol.h \ wlr-output-power-management-unstable-v1-protocol.h xdg-shell-protocol.h util.o: util.c util.h @@ -34,9 +33,6 @@ WAYLAND_PROTOCOLS = `$(PKG_CONFIG) --variable=pkgdatadir wayland-protocols` cursor-shape-v1-protocol.h: $(WAYLAND_SCANNER) enum-header \ $(WAYLAND_PROTOCOLS)/staging/cursor-shape/cursor-shape-v1.xml $@ -ext-image-copy-capture-v1-protocol.h: - $(WAYLAND_SCANNER) enum-header \ - $(WAYLAND_PROTOCOLS)/staging/ext-image-copy-capture/ext-image-copy-capture-v1.xml $@ pointer-constraints-unstable-v1-protocol.h: $(WAYLAND_SCANNER) enum-header \ $(WAYLAND_PROTOCOLS)/unstable/pointer-constraints/pointer-constraints-unstable-v1.xml $@ diff --git a/dwl.c b/dwl.c index 1dad6ac..12f441e 100644 --- a/dwl.c +++ b/dwl.c @@ -24,8 +24,6 @@ #include #include #include -#include -#include #include #include #include @@ -2518,8 +2516,6 @@ setup(void) wlr_data_device_manager_create(dpy); wlr_export_dmabuf_manager_v1_create(dpy); wlr_screencopy_manager_v1_create(dpy); - wlr_ext_image_copy_capture_manager_v1_create(dpy, 1); - wlr_ext_output_image_capture_source_manager_v1_create(dpy, 1); wlr_data_control_manager_v1_create(dpy); wlr_primary_selection_v1_device_manager_create(dpy); wlr_viewporter_create(dpy); From ed2e1efda8470d4c7971f5d75d50bb1c8e627316 Mon Sep 17 00:00:00 2001 From: fauxmight Date: Mon, 29 Sep 2025 05:39:54 +0200 Subject: [PATCH 74/75] Update README.md Make "dwl" references in README.md links to dwm main site. Closes #1168 --- README.md | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 364e3ca..d131bb0 100644 --- a/README.md +++ b/README.md @@ -4,9 +4,9 @@ Join us on our IRC channel: [#dwl on Libera Chat] Or on the community-maintained [Discord server]. dwl is a compact, hackable compositor for [Wayland] based on [wlroots]. It is -intended to fill the same space in the Wayland world that dwm does in X11, +intended to fill the same space in the Wayland world that [dwm] does in X11, primarily in terms of functionality, and secondarily in terms of -philosophy. Like dwm, dwl is: +philosophy. Like [dwm], dwl is: - Easy to understand, hack on, and extend with patches - One C source file (or a very small number) configurable via `config.h` @@ -55,11 +55,11 @@ To enable XWayland, you should uncomment its flags in `config.mk`. ## Configuration All configuration is done by editing `config.h` and recompiling, in the same -manner as dwm. There is no way to separately restart the window manager in +manner as [dwm]. There is no way to separately restart the window manager in Wayland without restarting the entire display server, so any changes will take effect the next time dwl is executed. -As in the dwm community, we encourage users to share patches they have +As in the [dwm] community, we encourage users to share patches they have created. Check out the [dwl-patches] repository! ## Running dwl @@ -124,11 +124,11 @@ You can find a [list of useful resources on our wiki]. ## Background -dwl is not meant to provide every feature under the sun. Instead, like dwm, it +dwl is not meant to provide every feature under the sun. Instead, like [dwm], it sticks to features which are necessary, simple, and straightforward to implement given the base on which it is built. Implemented default features are: -- Any features provided by dwm/Xlib: simple window borders, tags, keybindings, +- Any features provided by [dwm]/Xlib: simple window borders, tags, keybindings, client rules, mouse move/resize. Providing a built-in status bar is an exception to this goal, to avoid dependencies on font rendering and/or drawing libraries when an external bar could work well. @@ -145,10 +145,10 @@ given the base on which it is built. Implemented default features are: - Layer shell popups (used by Waybar) - Damage tracking provided by scenegraph API -Given the Wayland architecture, dwl has to implement features from dwm **and** +Given the Wayland architecture, dwl has to implement features from [dwm] **and** the xorg-server. Because of this, it is impossible to maintain the original project goal of 2000 SLOC and have a reasonably complete compositor with -features comparable to dwm. However, this does not mean that the code will grow +features comparable to [dwm]. However, this does not mean that the code will grow indiscriminately. We will try to keep the code as small as possible. Features under consideration (possibly as patches) are: @@ -172,7 +172,7 @@ developers. This was made possible in many cases by looking at how sway accomplished something, then trying to do the same in as suckless a way as possible. -Many thanks to suckless.org and the dwm developers and community for the +Many thanks to suckless.org and the [dwm] developers and community for the inspiration, and to the various contributors to the project, including: - **Devin J. Pohly for creating and nurturing the fledgling project** @@ -183,6 +183,7 @@ inspiration, and to the various contributors to the project, including: [wlroots]: https://gitlab.freedesktop.org/wlroots +[dwm]: https://dwm.suckless.org/ [`systemd --user`]: https://wiki.archlinux.org/title/Systemd/User [#dwl on Libera Chat]: https://web.libera.chat/?channels=#dwl [0.7-rc1]: https://codeberg.org/dwl/dwl/releases/tag/v0.7-rc1 From 6cd26568d5b8be2252ac0def36cd194b4fb2d7c3 Mon Sep 17 00:00:00 2001 From: fauxmight Date: Mon, 29 Sep 2025 05:56:22 +0200 Subject: [PATCH 75/75] Update README.md Document Java nonreparenting WM issue Closes #722 --- README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.md b/README.md index d131bb0..390788d 100644 --- a/README.md +++ b/README.md @@ -118,6 +118,15 @@ script with the line To get a list of status bars that work with dwl consult our [wiki]. +### (Known) Java nonreparenting WM issue +Certain IDEs don't display correctly unless an environmental variable for Java AWT +indicates that the WM is nonreparenting. + +For some Java AWT-based IDEs, such as Xilinx Vivado and Microchip MPLAB X, the +following environment variable needs to be set before running the IDE or dwl: + + export _JAVA_AWT_WM_NONREPARENTING=1 + ## Replacements for X applications You can find a [list of useful resources on our wiki].