From 487abc28ba6879bf3a2492ef766f0420ae6f904b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?=
 <leohdz172@proton.me>
Date: Wed, 24 Jul 2024 15:51:49 -0600
Subject: [PATCH 01/40] 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 <humm@ljabl.com> <hummsmith42@gmail.com>
+Leonardo Hernández Hernández <leohdz172@proton.me> <leohdz172@outlook.com>
+Leonardo Hernández Hernández <leohdz172@proton.me> <leohdz172@protonmail.com>

From 986beef5be32a2bead22ca85d19f4d6d7e5c0ce1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?=
 <leohdz172@proton.me>
Date: Sat, 27 Jul 2024 00:40:24 -0600
Subject: [PATCH 02/40] 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?=
 <leohdz172@proton.me>
Date: Sat, 27 Jul 2024 21:34:18 -0600
Subject: [PATCH 03/40] 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 <sivecano@gmail.com>
Date: Sat, 27 Jul 2024 14:46:54 +0200
Subject: [PATCH 04/40] 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?=
 <leohdz172@proton.me>
Date: Thu, 1 Aug 2024 20:38:57 -0600
Subject: [PATCH 05/40] `-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?=
 <leohdz172@proton.me>
Date: Mon, 5 Aug 2024 12:11:42 -0600
Subject: [PATCH 06/40] 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?=
 <leohdz172@proton.me>
Date: Tue, 11 Jun 2024 11:32:50 -0600
Subject: [PATCH 07/40] 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 <wlr/types/wlr_keyboard_group.h>
 #include <wlr/types/wlr_layer_shell_v1.h>
 #include <wlr/types/wlr_linux_dmabuf_v1.h>
+#include <wlr/types/wlr_linux_drm_syncobj_v1.h>
 #include <wlr/types/wlr_output.h>
 #include <wlr/types/wlr_output_layout.h>
 #include <wlr/types/wlr_output_management_v1.h>
@@ -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?=
 <leohdz172@proton.me>
Date: Sat, 3 Aug 2024 12:09:18 -0600
Subject: [PATCH 08/40] 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?=
 <leohdz172@proton.me>
Date: Thu, 8 Aug 2024 14:19:39 -0600
Subject: [PATCH 09/40] 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?=
 <leohdz172@proton.me>
Date: Thu, 8 Aug 2024 14:33:03 -0600
Subject: [PATCH 10/40] 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?=
 <leohdz172@proton.me>
Date: Thu, 8 Aug 2024 14:38:43 -0600
Subject: [PATCH 11/40] 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?=
 <leohdz172@proton.me>
Date: Thu, 8 Aug 2024 14:42:16 -0600
Subject: [PATCH 12/40] 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?=
 <leohdz172@proton.me>
Date: Sat, 10 Aug 2024 10:39:25 -0600
Subject: [PATCH 13/40] 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?=
 <leohdz172@proton.me>
Date: Thu, 20 Jun 2024 12:36:56 -0600
Subject: [PATCH 14/40] 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?=
 <leohdz172@proton.me>
Date: Fri, 9 Aug 2024 21:34:02 -0600
Subject: [PATCH 15/40] 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?=
 <leohdz172@proton.me>
Date: Wed, 14 Aug 2024 11:47:29 -0600
Subject: [PATCH 16/40] 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?=
 <leohdz172@proton.me>
Date: Wed, 14 Aug 2024 13:37:14 -0600
Subject: [PATCH 17/40] 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 <dwl@ivories.org>
Date: Sat, 17 Aug 2024 09:46:20 -0500
Subject: [PATCH 18/40] 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?=
 <leohdz172@proton.me>
Date: Sat, 17 Aug 2024 21:15:17 -0600
Subject: [PATCH 19/40] 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?=
 <leohdz172@proton.me>
Date: Sun, 25 Aug 2024 11:33:54 -0600
Subject: [PATCH 20/40] 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?=
 <leohdz172@proton.me>
Date: Fri, 9 Aug 2024 20:51:33 -0600
Subject: [PATCH 21/40] 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?=
 <leohdz172@proton.me>
Date: Fri, 9 Aug 2024 21:35:21 -0600
Subject: [PATCH 22/40] 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?=
 <leohdz172@proton.me>
Date: Wed, 14 Aug 2024 13:09:09 -0600
Subject: [PATCH 23/40] 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?=
 <leohdz172@proton.me>
Date: Fri, 9 Aug 2024 22:05:04 -0600
Subject: [PATCH 24/40] 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?=
 <leohdz172@proton.me>
Date: Fri, 9 Aug 2024 22:27:51 -0600
Subject: [PATCH 25/40] 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?=
 <leohdz172@proton.me>
Date: Wed, 14 Aug 2024 13:10:14 -0600
Subject: [PATCH 26/40] 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?=
 <leohdz172@proton.me>
Date: Wed, 14 Aug 2024 13:10:58 -0600
Subject: [PATCH 27/40] 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?=
 <leohdz172@proton.me>
Date: Wed, 14 Aug 2024 13:12:09 -0600
Subject: [PATCH 28/40] 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?=
 <leohdz172@proton.me>
Date: Wed, 14 Aug 2024 13:14:15 -0600
Subject: [PATCH 29/40] 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?=
 <leohdz172@proton.me>
Date: Wed, 14 Aug 2024 13:15:48 -0600
Subject: [PATCH 30/40] 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?=
 <leohdz172@proton.me>
Date: Wed, 14 Aug 2024 13:18:04 -0600
Subject: [PATCH 31/40] 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 <notchoc@disroot.org>
Date: Mon, 26 Aug 2024 21:40:27 +0800
Subject: [PATCH 32/40] 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?=
 <leohdz172@proton.me>
Date: Fri, 30 Aug 2024 18:19:18 -0600
Subject: [PATCH 33/40] 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 <guido@guidocella.xyz>
Date: Sun, 8 Sep 2024 20:51:41 +0200
Subject: [PATCH 34/40] 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 <guido@guidocella.xyz>
Date: Sat, 7 Sep 2024 21:22:40 +0200
Subject: [PATCH 35/40] 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?=
 <leohdz172@proton.me>
Date: Sun, 25 Aug 2024 13:02:34 -0600
Subject: [PATCH 36/40] 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?=
 <leohdz172@proton.me>
Date: Sun, 27 Oct 2024 20:26:55 -0600
Subject: [PATCH 37/40] 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?=
 <leohdz172@proton.me>
Date: Sun, 27 Oct 2024 20:08:02 -0600
Subject: [PATCH 38/40] 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?=
 <leohdz172@proton.me>
Date: Fri, 15 Nov 2024 00:17:43 -0600
Subject: [PATCH 39/40] 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?=
 <leohdz172@proton.me>
Date: Tue, 10 Dec 2024 22:32:21 -0600
Subject: [PATCH 40/40] 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