From 03e167dbb70fbc967e310f95200bcd63f43cac72 Mon Sep 17 00:00:00 2001
From: Raphael Robatsch <raphael-git@tapesoftware.net>
Date: Sat, 13 Nov 2021 17:22:52 +0100
Subject: fullscreennotify: don't crash if called before map

SDL2 calls xdg_toplevel.unset_fullscreen() before the surface is
mapped. This causes a segfault in dwl because setfullscreen() expects
the surface to be mapped already.
Therefore, delay the setfullscreen call until the surface is mapped.
---
 dwl.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/dwl.c b/dwl.c
index 6303c25..f99fc9a 100644
--- a/dwl.c
+++ b/dwl.c
@@ -1042,7 +1042,13 @@ void
 fullscreennotify(struct wl_listener *listener, void *data)
 {
 	Client *c = wl_container_of(listener, c, fullscreen);
-	setfullscreen(c, !c->isfullscreen);
+	struct wlr_xdg_toplevel_set_fullscreen_event *event = data;
+	if (!c->mon) {
+		/* if the client is not mapped yet, let mapnotify() call setfullscreen() */
+		c->isfullscreen = event->fullscreen;
+		return;
+	}
+	setfullscreen(c, event->fullscreen);
 }
 
 Monitor *
@@ -1316,6 +1322,9 @@ mapnotify(struct wl_listener *listener, void *data)
 
 	/* Set initial monitor, tags, floating status, and focus */
 	applyrules(c);
+
+	if (c->isfullscreen)
+		setfullscreen(c, 1);
 }
 
 void
-- 
cgit v1.2.3


From b0098d9d095509e4999965d261fe4282040a187a Mon Sep 17 00:00:00 2001
From: Nihal Jere <nihal@nihaljere.xyz>
Date: Tue, 22 Feb 2022 23:03:26 -0600
Subject: die on allocation failure

---
 dwl.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/dwl.c b/dwl.c
index 36a3871..1b9260b 100644
--- a/dwl.c
+++ b/dwl.c
@@ -787,6 +787,8 @@ createkeyboard(struct wlr_input_device *device)
 	struct xkb_context *context;
 	struct xkb_keymap *keymap;
 	Keyboard *kb = device->data = calloc(1, sizeof(*kb));
+	if (!kb)
+		EBARF("createkeyboard: calloc");
 	kb->device = device;
 
 	/* Prepare an XKB keymap and assign it to the keyboard. */
@@ -818,6 +820,8 @@ createmon(struct wl_listener *listener, void *data)
 	struct wlr_output *wlr_output = data;
 	const MonitorRule *r;
 	Monitor *m = wlr_output->data = calloc(1, sizeof(*m));
+	if (!m)
+		EBARF("createmon: calloc");
 	m->wlr_output = wlr_output;
 
 	wlr_output_init_render(wlr_output, alloc, drw);
@@ -891,6 +895,8 @@ createnotify(struct wl_listener *listener, void *data)
 
 	/* Allocate a Client for this surface */
 	c = xdg_surface->data = calloc(1, sizeof(*c));
+	if (!c)
+		EBARF("createnotify: calloc");
 	c->surface.xdg = xdg_surface;
 	c->bw = borderpx;
 
@@ -917,6 +923,8 @@ createlayersurface(struct wl_listener *listener, void *data)
 	}
 
 	layersurface = calloc(1, sizeof(LayerSurface));
+	if (!layersurface)
+		EBARF("layersurface: calloc");
 	LISTEN(&wlr_layer_surface->surface->events.commit,
 		&layersurface->surface_commit, commitlayersurfacenotify);
 	LISTEN(&wlr_layer_surface->events.destroy, &layersurface->destroy,
@@ -2478,6 +2486,8 @@ createnotifyx11(struct wl_listener *listener, void *data)
 
 	/* Allocate a Client for this surface */
 	c = xwayland_surface->data = calloc(1, sizeof(*c));
+	if (!c)
+		EBARF("createnotifyx11: calloc");
 	c->surface.xwayland = xwayland_surface;
 	c->type = xwayland_surface->override_redirect ? X11Unmanaged : X11Managed;
 	c->bw = borderpx;
-- 
cgit v1.2.3


From 8cace1921823e250041f7d85d939960f33824451 Mon Sep 17 00:00:00 2001
From: Leonardo Hernandez Hernandez <leohdz172@protonmail.com>
Date: Thu, 4 Nov 2021 08:19:13 -0600
Subject: fix crash when the last monitor is disconnected

---
 dwl.c | 21 ++++++++++++++++-----
 1 file changed, 16 insertions(+), 5 deletions(-)

diff --git a/dwl.c b/dwl.c
index 0619ff1..67a3cd5 100644
--- a/dwl.c
+++ b/dwl.c
@@ -57,7 +57,7 @@
 #define MAX(A, B)               ((A) > (B) ? (A) : (B))
 #define MIN(A, B)               ((A) < (B) ? (A) : (B))
 #define CLEANMASK(mask)         (mask & ~WLR_MODIFIER_CAPS)
-#define VISIBLEON(C, M)         ((C)->mon == (M) && ((C)->tags & (M)->tagset[(M)->seltags]))
+#define VISIBLEON(C, M)         ((M) && (C)->mon == (M) && ((C)->tags & (M)->tagset[(M)->seltags]))
 #define LENGTH(X)               (sizeof X / sizeof X[0])
 #define END(A)                  ((A) + LENGTH(A))
 #define TAGMASK                 ((1 << LENGTH(tags)) - 1)
@@ -720,10 +720,11 @@ cleanupmon(struct wl_listener *listener, void *data)
 	wl_list_remove(&m->link);
 	wlr_output_layout_remove(output_layout, m->wlr_output);
 
-	nmons = wl_list_length(&mons);
-	do // don't switch to disabled mons
-		selmon = wl_container_of(mons.prev, selmon, link);
-	while (!selmon->wlr_output->enabled && i++ < nmons);
+	if ((nmons = wl_list_length(&mons)))
+		do // don't switch to disabled mons
+			selmon = wl_container_of(mons.prev, selmon, link);
+		while (!selmon->wlr_output->enabled && i++ < nmons);
+
 	focusclient(focustop(selmon), 1);
 	closemon(m);
 	free(m);
@@ -860,6 +861,16 @@ createmon(struct wl_listener *listener, void *data)
 	wlr_output_layout_add(output_layout, wlr_output, r->x, r->y);
 	sgeom = *wlr_output_layout_get_box(output_layout, NULL);
 
+	/* If length == 1 we need update selmon.
+	 * Maybe it will change in run(). */
+	if (wl_list_length(&mons) == 1) {
+		Client *c;
+		selmon = m;
+		/* If there is any client, set c->mon to this monitor */
+		wl_list_for_each(c, &clients, link)
+			setmon(c, m, c->tags);
+	}
+
 	/* When adding monitors, the geometries of all monitors must be updated */
 	wl_list_for_each(m, &mons, link) {
 		/* The first monitor in the list is the most recently added */
-- 
cgit v1.2.3


From f673305e86bea5804fa8c68ffa43f120e7d9f9fa Mon Sep 17 00:00:00 2001
From: Leonardo Hernández Hernández <leohdz172@protonmail.com>
Date: Thu, 10 Mar 2022 11:37:11 -0600
Subject: replace tabs by spaces in alignment

---
 config.def.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/config.def.h b/config.def.h
index 738a3ca..8408659 100644
--- a/config.def.h
+++ b/config.def.h
@@ -84,7 +84,7 @@ static const Key keys[] = {
 	{ MODKEY,                    XKB_KEY_m,          setlayout,      {.v = &layouts[2]} },
 	{ MODKEY,                    XKB_KEY_space,      setlayout,      {0} },
 	{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_space,      togglefloating, {0} },
-	{ MODKEY, 					 XKB_KEY_e,    		togglefullscreen, {0} },
+	{ MODKEY,                    XKB_KEY_e,         togglefullscreen, {0} },
 	{ MODKEY,                    XKB_KEY_0,          view,           {.ui = ~0} },
 	{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_parenright, tag,            {.ui = ~0} },
 	{ MODKEY,                    XKB_KEY_comma,      focusmon,       {.i = WLR_DIRECTION_LEFT} },
-- 
cgit v1.2.3


From 5d9c9a9a685bb026b35032ab8cbc0575785a74ab Mon Sep 17 00:00:00 2001
From: Leonardo Hernández Hernández <leohdz172@protonmail.com>
Date: Thu, 10 Mar 2022 14:34:36 -0600
Subject: don't warn about unused result

Closes: #186
---
 config.mk | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/config.mk b/config.mk
index cd4e821..d1b161e 100644
--- a/config.mk
+++ b/config.mk
@@ -2,7 +2,7 @@
 PREFIX = /usr/local
 
 # Default compile flags (overridable by environment)
-CFLAGS ?= -g -Wall -Wextra -Werror -Wno-unused-parameter -Wno-sign-compare -Wno-unused-function -Wno-unused-variable -Wdeclaration-after-statement
+CFLAGS ?= -g -Wall -Wextra -Werror -Wno-unused-parameter -Wno-sign-compare -Wno-unused-function -Wno-unused-variable -Wno-unused-result -Wdeclaration-after-statement
 
 # Uncomment to build XWayland support
 #CFLAGS += -DXWAYLAND
-- 
cgit v1.2.3


From 05a473335ea4c69569d9ad34298b4f42a555e6e3 Mon Sep 17 00:00:00 2001
From: Leonardo Hernández Hernández <leohdz172@protonmail.com>
Date: Thu, 10 Mar 2022 14:48:14 -0600
Subject: use wlr_box for previous geom

---
 dwl.c | 13 +++----------
 1 file changed, 3 insertions(+), 10 deletions(-)

diff --git a/dwl.c b/dwl.c
index 67a3cd5..ba150fa 100644
--- a/dwl.c
+++ b/dwl.c
@@ -101,7 +101,7 @@ typedef struct {
 	struct wl_listener destroy;
 	struct wl_listener set_title;
 	struct wl_listener fullscreen;
-	struct wlr_box geom;  /* layout-relative, includes border */
+	struct wlr_box geom, prev;  /* layout-relative, includes border */
 	Monitor *mon;
 #ifdef XWAYLAND
 	unsigned int type;
@@ -112,10 +112,6 @@ typedef struct {
 	unsigned int tags;
 	int isfloating, isurgent;
 	uint32_t resize; /* configure serial of a pending resize */
-	int prevx;
-	int prevy;
-	int prevwidth;
-	int prevheight;
 	int isfullscreen;
 } Client;
 
@@ -1035,15 +1031,12 @@ setfullscreen(Client *c, int fullscreen)
 	client_set_fullscreen(c, fullscreen);
 
 	if (fullscreen) {
-		c->prevx = c->geom.x;
-		c->prevy = c->geom.y;
-		c->prevheight = c->geom.height;
-		c->prevwidth = c->geom.width;
+		c->prev = c->geom;
 		resize(c, c->mon->m.x, c->mon->m.y, c->mon->m.width, c->mon->m.height, 0);
 	} else {
 		/* restore previous size instead of arrange for floating windows since
 		 * client positions are set by the user and cannot be recalculated */
-		resize(c, c->prevx, c->prevy, c->prevwidth, c->prevheight, 0);
+		resize(c, c->prev.x, c->prev.y, c->prev.width, c->prev.height, 0);
 		arrange(c->mon);
 	}
 }
-- 
cgit v1.2.3


From 0e5d7124de4e7ba0baa080547fcfee41b1d5174d Mon Sep 17 00:00:00 2001
From: Leonardo Hernandez Hernandez <leohdz172@protonmail.com>
Date: Wed, 26 Jan 2022 00:54:00 -0600
Subject: use loop to call arrangelayer

zwlr_layer_shell_v1_layer are ordered by bottom-most first so we can
just use a loop from 3 to 0
---
 dwl.c | 25 +++++++------------------
 1 file changed, 7 insertions(+), 18 deletions(-)

diff --git a/dwl.c b/dwl.c
index 9991c95..cd9e74d 100644
--- a/dwl.c
+++ b/dwl.c
@@ -560,6 +560,7 @@ arrangelayer(Monitor *m, struct wl_list *list, struct wlr_box *usable_area, int
 void
 arrangelayers(Monitor *m)
 {
+	int i;
 	struct wlr_box usable_area = m->m;
 	uint32_t layers_above_shell[] = {
 		ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY,
@@ -568,30 +569,18 @@ arrangelayers(Monitor *m)
 	LayerSurface *layersurface;
 	struct wlr_keyboard *kb = wlr_seat_get_keyboard(seat);
 
-	// Arrange exclusive surfaces from top->bottom
-	arrangelayer(m, &m->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY],
-			&usable_area, 1);
-	arrangelayer(m, &m->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP],
-			&usable_area, 1);
-	arrangelayer(m, &m->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM],
-			&usable_area, 1);
-	arrangelayer(m, &m->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND],
-			&usable_area, 1);
+	/* Arrange exclusive surfaces from top->bottom */
+	for (i = 3; i >= 0; i--)
+		arrangelayer(m, &m->layers[i], &usable_area, 1);
 
 	if (memcmp(&usable_area, &m->w, sizeof(struct wlr_box))) {
 		m->w = usable_area;
 		arrange(m);
 	}
 
-	// Arrange non-exlusive surfaces from top->bottom
-	arrangelayer(m, &m->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY],
-			&usable_area, 0);
-	arrangelayer(m, &m->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP],
-			&usable_area, 0);
-	arrangelayer(m, &m->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM],
-			&usable_area, 0);
-	arrangelayer(m, &m->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND],
-			&usable_area, 0);
+	/* Arrange non-exlusive surfaces from top->bottom */
+	for (i = 3; i >= 0; i--)
+		arrangelayer(m, &m->layers[i], &usable_area, 0);
 
 	// Find topmost keyboard interactive layer, if such a layer exists
 	for (size_t i = 0; i < LENGTH(layers_above_shell); i++) {
-- 
cgit v1.2.3


From 4d26d302200f20294b97d01e49a9a4a7f0b189d2 Mon Sep 17 00:00:00 2001
From: Leonardo Hernández Hernández <leohdz172@protonmail.com>
Date: Fri, 11 Mar 2022 18:52:22 -0600
Subject: suckless style: don't use '//' for comments

---
 dwl.c | 34 +++++++++++++++++-----------------
 1 file changed, 17 insertions(+), 17 deletions(-)

diff --git a/dwl.c b/dwl.c
index cd9e74d..47b5187 100644
--- a/dwl.c
+++ b/dwl.c
@@ -164,7 +164,7 @@ struct Monitor {
 	struct wl_listener destroy;
 	struct wlr_box m;      /* monitor area, layout-relative */
 	struct wlr_box w;      /* window area, layout-relative */
-	struct wl_list layers[4]; // LayerSurface::link
+	struct wl_list layers[4]; /* LayerSurface::link */
 	const Layout *lt[2];
 	unsigned int seltags;
 	unsigned int sellt;
@@ -394,7 +394,7 @@ applyexclusive(struct wlr_box *usable_area,
 		int32_t margin_top, int32_t margin_right,
 		int32_t margin_bottom, int32_t margin_left) {
 	Edge edges[] = {
-		{ // Top
+		{ /* Top */
 			.singular_anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP,
 			.anchor_triplet = ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT |
 				ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT |
@@ -403,7 +403,7 @@ applyexclusive(struct wlr_box *usable_area,
 			.negative_axis = &usable_area->height,
 			.margin = margin_top,
 		},
-		{ // Bottom
+		{ /* Bottom */
 			.singular_anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM,
 			.anchor_triplet = ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT |
 				ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT |
@@ -412,7 +412,7 @@ applyexclusive(struct wlr_box *usable_area,
 			.negative_axis = &usable_area->height,
 			.margin = margin_bottom,
 		},
-		{ // Left
+		{ /* Left */
 			.singular_anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT,
 			.anchor_triplet = ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT |
 				ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP |
@@ -421,7 +421,7 @@ applyexclusive(struct wlr_box *usable_area,
 			.negative_axis = &usable_area->width,
 			.margin = margin_left,
 		},
-		{ // Right
+		{ /* Right */
 			.singular_anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT,
 			.anchor_triplet = ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT |
 				ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP |
@@ -504,7 +504,7 @@ arrangelayer(Monitor *m, struct wl_list *list, struct wlr_box *usable_area, int
 
 		bounds = state->exclusive_zone == -1 ? full_area : *usable_area;
 
-		// Horizontal axis
+		/* Horizontal axis */
 		if ((state->anchor & both_horiz) && box.width == 0) {
 			box.x = bounds.x;
 			box.width = bounds.width;
@@ -515,7 +515,7 @@ arrangelayer(Monitor *m, struct wl_list *list, struct wlr_box *usable_area, int
 		} else {
 			box.x = bounds.x + ((bounds.width / 2) - (box.width / 2));
 		}
-		// Vertical axis
+		/* Vertical axis */
 		if ((state->anchor & both_vert) && box.height == 0) {
 			box.y = bounds.y;
 			box.height = bounds.height;
@@ -526,7 +526,7 @@ arrangelayer(Monitor *m, struct wl_list *list, struct wlr_box *usable_area, int
 		} else {
 			box.y = bounds.y + ((bounds.height / 2) - (box.height / 2));
 		}
-		// Margin
+		/* Margin */
 		if ((state->anchor & both_horiz) == both_horiz) {
 			box.x += state->margin.left;
 			box.width -= state->margin.left + state->margin.right;
@@ -582,13 +582,13 @@ arrangelayers(Monitor *m)
 	for (i = 3; i >= 0; i--)
 		arrangelayer(m, &m->layers[i], &usable_area, 0);
 
-	// Find topmost keyboard interactive layer, if such a layer exists
+	/* Find topmost keyboard interactive layer, if such a layer exists */
 	for (size_t i = 0; i < LENGTH(layers_above_shell); i++) {
 		wl_list_for_each_reverse(layersurface,
 				&m->layers[layers_above_shell[i]], link) {
 			if (layersurface->layer_surface->current.keyboard_interactive &&
 					layersurface->layer_surface->mapped) {
-				// Deactivate the focused client.
+				/* Deactivate the focused client. */
 				focusclient(NULL, 0);
 				wlr_seat_keyboard_notify_enter(seat, layersurface->layer_surface->surface,
 						kb->keycodes, kb->num_keycodes, &kb->modifiers);
@@ -706,7 +706,7 @@ cleanupmon(struct wl_listener *listener, void *data)
 	wlr_output_layout_remove(output_layout, m->wlr_output);
 
 	if ((nmons = wl_list_length(&mons)))
-		do // don't switch to disabled mons
+		do /* don't switch to disabled mons */
 			selmon = wl_container_of(mons.prev, selmon, link);
 		while (!selmon->wlr_output->enabled && i++ < nmons);
 
@@ -718,7 +718,7 @@ cleanupmon(struct wl_listener *listener, void *data)
 void
 closemon(Monitor *m)
 {
-	// move closed monitor's clients to the focused one
+	/* move closed monitor's clients to the focused one */
 	Client *c;
 
 	wl_list_for_each(c, &clients, link) {
@@ -932,8 +932,9 @@ createlayersurface(struct wl_listener *listener, void *data)
 	wl_list_insert(&m->layers[wlr_layer_surface->pending.layer],
 			&layersurface->link);
 
-	// Temporarily set the layer's current state to pending
-	// so that we can easily arrange it
+	/* Temporarily set the layer's current state to pending
+	 * so that we can easily arrange it
+	 */
 	old_state = wlr_layer_surface->current;
 	wlr_layer_surface->current = wlr_layer_surface->pending;
 	arrangelayers(m);
@@ -1352,7 +1353,7 @@ motionnotify(uint32_t time)
 	struct wlr_surface *surface = NULL;
 	Client *c = NULL;
 
-	// time is 0 in internal calls meant to restore pointer focus.
+	/* time is 0 in internal calls meant to restore pointer focus. */
 	if (time) {
 		wlr_idle_notify_activity(idle, seat);
 
@@ -2607,8 +2608,7 @@ main(int argc, char *argv[])
 	if (optind < argc)
 		goto usage;
 
-	// Wayland requires XDG_RUNTIME_DIR for creating its communications
-	// socket
+	/* Wayland requires XDG_RUNTIME_DIR for creating its communications socket */
 	if (!getenv("XDG_RUNTIME_DIR"))
 		BARF("XDG_RUNTIME_DIR must be set");
 	setup();
-- 
cgit v1.2.3


From 08020d61b7ed2c13a544c7c3f051754088475a2d Mon Sep 17 00:00:00 2001
From: Leonardo Hernández Hernández <leohdz172@protonmail.com>
Date: Fri, 11 Mar 2022 23:02:37 -0600
Subject: more style fixes

---
 dwl.c | 45 +++++++++++++++++----------------------------
 1 file changed, 17 insertions(+), 28 deletions(-)

diff --git a/dwl.c b/dwl.c
index 47b5187..65244e7 100644
--- a/dwl.c
+++ b/dwl.c
@@ -623,7 +623,7 @@ buttonpress(struct wl_listener *listener, void *data)
 	wlr_idle_notify_activity(idle, seat);
 
 	switch (event->state) {
-	case WLR_BUTTON_PRESSED:;
+	case WLR_BUTTON_PRESSED:
 		/* Change focus if the button was _pressed_ over a client */
 		if ((c = xytoclient(cursor->x, cursor->y)))
 			focusclient(c, 1);
@@ -642,8 +642,7 @@ buttonpress(struct wl_listener *listener, void *data)
 		/* If you released any buttons, we exit interactive move/resize mode. */
 		/* TODO should reset to the pointer focus's current setcursor */
 		if (cursor_mode != CurNormal) {
-			wlr_xcursor_manager_set_cursor_image(cursor_mgr,
-					"left_ptr", cursor);
+			wlr_xcursor_manager_set_cursor_image(cursor_mgr, "left_ptr", cursor);
 			cursor_mode = CurNormal;
 			/* Drop the window off on its new monitor */
 			selmon = xytomon(cursor->x, cursor->y);
@@ -1278,16 +1277,16 @@ void
 killclient(const Arg *arg)
 {
 	Client *sel = selclient();
-	if (!sel)
-		return;
-	client_send_close(sel);
+	if (sel)
+		client_send_close(sel);
 }
 
 void
 maplayersurfacenotify(struct wl_listener *listener, void *data)
 {
 	LayerSurface *layersurface = wl_container_of(listener, layersurface, map);
-	wlr_surface_send_enter(layersurface->layer_surface->surface, layersurface->layer_surface->output);
+	wlr_surface_send_enter(layersurface->layer_surface->surface,
+		layersurface->layer_surface->output);
 	motionnotify(0);
 }
 
@@ -1406,8 +1405,7 @@ motionnotify(uint32_t time)
 	 * default. This is what makes the cursor image appear when you move it
 	 * off of a client or over its border. */
 	if (!surface && time)
-		wlr_xcursor_manager_set_cursor_image(cursor_mgr,
-				"left_ptr", cursor);
+		wlr_xcursor_manager_set_cursor_image(cursor_mgr, "left_ptr", cursor);
 
 	pointerfocus(c, surface, sx, sy, time);
 }
@@ -1423,8 +1421,7 @@ motionrelative(struct wl_listener *listener, void *data)
 	 * special configuration applied for the specific input device which
 	 * generated the event. You can pass NULL for the device if you want to move
 	 * the cursor around without any input. */
-	wlr_cursor_move(cursor, event->device,
-			event->delta_x, event->delta_y);
+	wlr_cursor_move(cursor, event->device, event->delta_x, event->delta_y);
 	motionnotify(event->time_msec);
 }
 
@@ -1644,8 +1641,7 @@ render(struct wlr_surface *surface, int sx, int sy, void *data)
 	 * compositor.
 	 */
 	transform = wlr_output_transform_invert(surface->current.transform);
-	wlr_matrix_project_box(matrix, &obox, transform, 0,
-		output->transform_matrix);
+	wlr_matrix_project_box(matrix, &obox, transform, 0, output->transform_matrix);
 
 	/* This takes our matrix, the texture, and an alpha, and performs the actual
 	 * rendering on the GPU. */
@@ -1678,8 +1674,7 @@ renderclients(Monitor *m, struct timespec *now)
 
 		surface = client_surface(c);
 		ox = c->geom.x, oy = c->geom.y;
-		wlr_output_layout_output_coords(output_layout, m->wlr_output,
-				&ox, &oy);
+		wlr_output_layout_output_coords(output_layout, m->wlr_output, &ox, &oy);
 
 		if (c->bw) {
 			w = surface->current.width;
@@ -1695,8 +1690,7 @@ renderclients(Monitor *m, struct timespec *now)
 			color = (c == sel) ? focuscolor : bordercolor;
 			for (i = 0; i < 4; i++) {
 				scalebox(&borders[i], m->wlr_output->scale);
-				wlr_render_rect(drw, &borders[i], color,
-						m->wlr_output->transform_matrix);
+				wlr_render_rect(drw, &borders[i], color, m->wlr_output->transform_matrix);
 			}
 		}
 
@@ -2113,12 +2107,9 @@ setup(void)
 	wl_signal_add(&virtual_keyboard_mgr->events.new_virtual_keyboard,
 			&new_virtual_keyboard);
 	seat = wlr_seat_create(dpy, "seat0");
-	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_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);
 
 	output_mgr = wlr_output_manager_v1_create(dpy);
 	wl_signal_add(&output_mgr->events.apply, &output_mgr_apply);
@@ -2226,10 +2217,9 @@ void
 togglefloating(const Arg *arg)
 {
 	Client *sel = selclient();
-	if (!sel)
-		return;
 	/* return if fullscreen */
-	setfloating(sel, !sel->isfloating /* || sel->isfixed */);
+	if (sel && !sel->isfullscreen)
+		setfloating(sel, !sel->isfloating);
 }
 
 void
@@ -2491,8 +2481,7 @@ createnotifyx11(struct wl_listener *listener, void *data)
 	/* Listen to the various events it can emit */
 	LISTEN(&xwayland_surface->events.map, &c->map, mapnotify);
 	LISTEN(&xwayland_surface->events.unmap, &c->unmap, unmapnotify);
-	LISTEN(&xwayland_surface->events.request_activate, &c->activate,
-			activatex11);
+	LISTEN(&xwayland_surface->events.request_activate, &c->activate, activatex11);
 	LISTEN(&xwayland_surface->events.request_configure, &c->configure,
 			configurex11);
 	LISTEN(&xwayland_surface->events.set_title, &c->set_title, updatetitle);
-- 
cgit v1.2.3


From 2cd0b3173d2ba7078347a8172b497d12fa592549 Mon Sep 17 00:00:00 2001
From: Leonardo Hernández Hernández <leohdz172@protonmail.com>
Date: Sun, 13 Mar 2022 15:16:06 -0600
Subject: print status about floating and fullscreen

---
 dwl.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/dwl.c b/dwl.c
index 65244e7..1388acb 100644
--- a/dwl.c
+++ b/dwl.c
@@ -1036,6 +1036,7 @@ setfullscreen(Client *c, int fullscreen)
 		resize(c, c->prev.x, c->prev.y, c->prev.width, c->prev.height, 0);
 		arrange(c->mon);
 	}
+	printstatus();
 }
 
 void
@@ -1568,10 +1569,14 @@ printstatus(void)
 				urg |= c->tags;
 		}
 		if ((c = focustop(m))) {
-			printf("%s title %s\n", m->wlr_output->name, client_get_title(focustop(m)));
+			printf("%s title %s\n", m->wlr_output->name, client_get_title(c));
+			printf("%s fullscreen %u\n", m->wlr_output->name, c->isfullscreen);
+			printf("%s floating %u\n", m->wlr_output->name, c->isfloating);
 			sel = c->tags;
 		} else {
 			printf("%s title \n", m->wlr_output->name);
+			printf("%s fullscreen \n", m->wlr_output->name);
+			printf("%s floating \n", m->wlr_output->name);
 			sel = 0;
 		}
 
@@ -1902,6 +1907,7 @@ setfloating(Client *c, int floating)
 {
 	c->isfloating = floating;
 	arrange(c->mon);
+	printstatus();
 }
 
 void
-- 
cgit v1.2.3


From ebff6e38a02086bd6078a444641a83cb226f9995 Mon Sep 17 00:00:00 2001
From: Leonardo Hernández Hernández <leohdz172@protonmail.com>
Date: Sun, 13 Mar 2022 17:11:52 -0600
Subject: always call arrange() on setfullscreen()

also don't count full screen clients on tile()
---
 dwl.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/dwl.c b/dwl.c
index 1388acb..20e7c5c 100644
--- a/dwl.c
+++ b/dwl.c
@@ -1034,8 +1034,8 @@ setfullscreen(Client *c, int fullscreen)
 		/* restore previous size instead of arrange for floating windows since
 		 * client positions are set by the user and cannot be recalculated */
 		resize(c, c->prev.x, c->prev.y, c->prev.width, c->prev.height, 0);
-		arrange(c->mon);
 	}
+	arrange(c->mon);
 	printstatus();
 }
 
@@ -2193,7 +2193,7 @@ tile(Monitor *m)
 	Client *c;
 
 	wl_list_for_each(c, &clients, link)
-		if (VISIBLEON(c, m) && !c->isfloating)
+		if (VISIBLEON(c, m) && !c->isfloating && !c->isfullscreen)
 			n++;
 	if (n == 0)
 		return;
-- 
cgit v1.2.3


From 43228bd493f53f996a645156f0505b63e79a4f72 Mon Sep 17 00:00:00 2001
From: Leonardo Hernández Hernández <leohdz172@protonmail.com>
Date: Sun, 13 Mar 2022 20:54:44 -0600
Subject: don't use fullscreen event in fullscreennotify()

---
 client.h | 10 ++++++++++
 dwl.c    |  7 ++++---
 2 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/client.h b/client.h
index 56e3089..f955688 100644
--- a/client.h
+++ b/client.h
@@ -95,6 +95,16 @@ client_is_float_type(Client *c)
 	return 0;
 }
 
+static inline int
+client_wants_fullscreen(Client *c)
+{
+#ifdef XWAYLAND
+	if (client_is_x11(c))
+		return c->surface.xwayland->fullscreen;
+#endif
+	return c->surface.xdg->toplevel->requested.fullscreen;
+}
+
 static inline int
 client_is_unmanaged(Client *c)
 {
diff --git a/dwl.c b/dwl.c
index f99fc9a..612f3d7 100644
--- a/dwl.c
+++ b/dwl.c
@@ -1042,13 +1042,14 @@ void
 fullscreennotify(struct wl_listener *listener, void *data)
 {
 	Client *c = wl_container_of(listener, c, fullscreen);
-	struct wlr_xdg_toplevel_set_fullscreen_event *event = data;
+	int fullscreen = client_wants_fullscreen(c);
+
 	if (!c->mon) {
 		/* if the client is not mapped yet, let mapnotify() call setfullscreen() */
-		c->isfullscreen = event->fullscreen;
+		c->isfullscreen = fullscreen;
 		return;
 	}
-	setfullscreen(c, event->fullscreen);
+	setfullscreen(c, fullscreen);
 }
 
 Monitor *
-- 
cgit v1.2.3


From 1087bc5db98faf12e02e57433ed52cbc9845e98b Mon Sep 17 00:00:00 2001
From: Leonardo Hernandez Hernandez <leohdz172@protonmail.com>
Date: Fri, 29 Oct 2021 18:38:24 -0500
Subject: use wlr_scene_xdg_surface_create() for xdg_popups

---
 dwl.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/dwl.c b/dwl.c
index d2f910c..8deee97 100644
--- a/dwl.c
+++ b/dwl.c
@@ -875,7 +875,11 @@ createnotify(struct wl_listener *listener, void *data)
 	struct wlr_xdg_surface *xdg_surface = data;
 	Client *c;
 
-	if (xdg_surface->role != WLR_XDG_SURFACE_ROLE_TOPLEVEL)
+	if (xdg_surface->role == WLR_XDG_SURFACE_ROLE_POPUP) {
+		xdg_surface->surface->data = wlr_scene_xdg_surface_create(
+				xdg_surface->popup->parent->data, xdg_surface);
+		return;
+	} else if (xdg_surface->role == WLR_XDG_SURFACE_ROLE_NONE)
 		return;
 
 	/* Allocate a Client for this surface */
@@ -1311,7 +1315,8 @@ mapnotify(struct wl_listener *listener, void *data)
 
 	/* Create scene tree for this client and its border */
 	c->scene = &wlr_scene_tree_create(layers[LyrTile])->node;
-	c->scene_surface = wlr_scene_subsurface_tree_create(c->scene, client_surface(c));
+	c->scene_surface = client_surface(c)->data =
+		wlr_scene_subsurface_tree_create(c->scene, client_surface(c));
 	c->scene_surface->data = c;
 	for (i = 0; i < 4; i++) {
 		c->border[i] = wlr_scene_rect_create(c->scene, 0, 0, bordercolor);
-- 
cgit v1.2.3


From b92c0ff57fbf9cc9ffb2a33e689acc08b8745f1d Mon Sep 17 00:00:00 2001
From: Leonardo Hernandez Hernandez <leohdz172@protonmail.com>
Date: Tue, 1 Feb 2022 01:16:56 -0600
Subject: add support for layer_shell popups

---
 dwl.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/dwl.c b/dwl.c
index 8deee97..0d8a1b1 100644
--- a/dwl.c
+++ b/dwl.c
@@ -871,7 +871,10 @@ void
 createnotify(struct wl_listener *listener, void *data)
 {
 	/* This event is raised when wlr_xdg_shell receives a new xdg surface from a
-	 * client, either a toplevel (application window) or popup. */
+	 * client, either a toplevel (application window) or popup,
+	 * or when wlr_layer_shell receives a new popup from a layer.
+	 * If you want to do something tricky with popups you should check if
+	 * its parent is wlr_xdg_shell or wlr_layer_shell */
 	struct wlr_xdg_surface *xdg_surface = data;
 	Client *c;
 
@@ -924,8 +927,8 @@ createlayersurface(struct wl_listener *listener, void *data)
 	wlr_layer_surface->data = layersurface;
 	m = wlr_layer_surface->output->data;
 
-	layersurface->scene = wlr_scene_subsurface_tree_create(
-			layers[wlr_layer_surface->pending.layer],
+	layersurface->scene = wlr_layer_surface->surface->data =
+			wlr_scene_subsurface_tree_create(layers[wlr_layer_surface->pending.layer],
 			wlr_layer_surface->surface);
 	layersurface->scene->data = layersurface;
 
-- 
cgit v1.2.3


From 863eedd05e8d292ccef2530d9b4b8b5475b8cbef Mon Sep 17 00:00:00 2001
From: Leonardo Hernandez Hernandez <leohdz172@protonmail.com>
Date: Mon, 31 Jan 2022 14:02:59 -0600
Subject: set correct position for unmanaged clients

- don't allow to move/resize with them
- don't focus unmanaged clients on buttonpress()
---
 dwl.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/dwl.c b/dwl.c
index 0d8a1b1..7f8d3f4 100644
--- a/dwl.c
+++ b/dwl.c
@@ -645,7 +645,8 @@ buttonpress(struct wl_listener *listener, void *data)
 	case WLR_BUTTON_PRESSED:;
 		/* Change focus if the button was _pressed_ over a client */
 		xytonode(cursor->x, cursor->y, NULL, &c, NULL, NULL, NULL);
-		if (c)
+		/* Don't focus unmanaged clients */
+		if (c && !client_is_unmanaged(c))
 			focusclient(c, 1);
 
 		keyboard = wlr_seat_get_keyboard(seat);
@@ -1328,9 +1329,12 @@ mapnotify(struct wl_listener *listener, void *data)
 	}
 
 	if (client_is_unmanaged(c)) {
+		client_get_geometry(c, &c->geom);
 		/* Floating, no border */
 		wlr_scene_node_reparent(c->scene, layers[LyrFloat]);
 		c->bw = 0;
+		wlr_scene_node_set_position(c->scene, c->geom.x + borderpx,
+			c->geom.y + borderpx);
 
 		/* Insert this independent into independents lists. */
 		wl_list_insert(&independents, &c->link);
@@ -1442,7 +1446,7 @@ moveresize(const Arg *arg)
 	if (cursor_mode != CurNormal)
 		return;
 	xytonode(cursor->x, cursor->y, NULL, &grabc, NULL, NULL, NULL);
-	if (!grabc)
+	if (!grabc || client_is_unmanaged(grabc))
 		return;
 
 	/* Float the window and tell motionnotify to grab it */
-- 
cgit v1.2.3


From 2768af5a9bfd7cb5f874a8d61f4bc9a1188b82fd Mon Sep 17 00:00:00 2001
From: Leonardo Hernández Hernández <leohdz172@protonmail.com>
Date: Wed, 16 Mar 2022 21:42:45 -0600
Subject: make sure configure and activate listeners are removed from list

---
 dwl.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/dwl.c b/dwl.c
index 3c57c23..09ddc9a 100644
--- a/dwl.c
+++ b/dwl.c
@@ -1004,9 +1004,10 @@ destroynotify(struct wl_listener *listener, void *data)
 	wl_list_remove(&c->set_title.link);
 	wl_list_remove(&c->fullscreen.link);
 #ifdef XWAYLAND
-	if (c->type == X11Managed)
+	if (c->type != XDGShell) {
+		wl_list_remove(&c->configure.link);
 		wl_list_remove(&c->activate.link);
-	else if (c->type == XDGShell)
+	} else
 #endif
 		wl_list_remove(&c->commit.link);
 	free(c);
-- 
cgit v1.2.3


From 294fb324d8f67c33552b15d3f1f79fe524d5f8fd Mon Sep 17 00:00:00 2001
From: Leonardo Hernández Hernández <leohdz172@protonmail.com>
Date: Wed, 16 Mar 2022 23:08:17 -0600
Subject: constraint popups to its parent client

Closes: #146
Closes: #155
---
 client.h | 21 +++++++++++++++++++++
 dwl.c    |  9 ++++++++-
 2 files changed, 29 insertions(+), 1 deletion(-)

diff --git a/client.h b/client.h
index 191dcc5..22454a5 100644
--- a/client.h
+++ b/client.h
@@ -179,3 +179,24 @@ client_surface_at(Client *c, double cx, double cy, double *sx, double *sy)
 #endif
 	return wlr_xdg_surface_surface_at(c->surface.xdg, cx, cy, sx, sy);
 }
+
+static inline Client *
+client_from_popup(struct wlr_xdg_popup *popup)
+{
+	struct wlr_xdg_surface *surface = popup->base;
+
+	while (1) {
+		switch (surface->role) {
+		case WLR_XDG_SURFACE_ROLE_POPUP:
+			if (!wlr_surface_is_xdg_surface(surface->popup->parent))
+				return NULL;
+
+			surface = wlr_xdg_surface_from_wlr_surface(surface->popup->parent);
+			break;
+		case WLR_XDG_SURFACE_ROLE_TOPLEVEL:
+				return surface->data;
+		case WLR_XDG_SURFACE_ROLE_NONE:
+			return NULL;
+		}
+	}
+}
diff --git a/dwl.c b/dwl.c
index 09ddc9a..58f1b36 100644
--- a/dwl.c
+++ b/dwl.c
@@ -880,7 +880,14 @@ createnotify(struct wl_listener *listener, void *data)
 	struct wlr_xdg_surface *xdg_surface = data;
 	Client *c;
 
-	if (xdg_surface->role != WLR_XDG_SURFACE_ROLE_TOPLEVEL)
+	if (xdg_surface->role == WLR_XDG_SURFACE_ROLE_POPUP) {
+		struct wlr_box box;
+		if (!(c = client_from_popup(xdg_surface->popup)))
+			return;
+		client_get_geometry(c, &box);
+		wlr_xdg_popup_unconstrain_from_box(xdg_surface->popup, &box);
+		return;
+	} else if (xdg_surface->role == WLR_XDG_SURFACE_ROLE_NONE)
 		return;
 
 	/* Allocate a Client for this surface */
-- 
cgit v1.2.3


From 1dfd867d9caa61d9f3fabf695a72b2fea35b6193 Mon Sep 17 00:00:00 2001
From: Leonardo Hernández Hernández <leohdz172@protonmail.com>
Date: Thu, 17 Mar 2022 17:02:03 -0600
Subject: fix crash of Firefox when opening a popup larger than its size

---
 dwl.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/dwl.c b/dwl.c
index 58f1b36..8e0a399 100644
--- a/dwl.c
+++ b/dwl.c
@@ -882,9 +882,11 @@ createnotify(struct wl_listener *listener, void *data)
 
 	if (xdg_surface->role == WLR_XDG_SURFACE_ROLE_POPUP) {
 		struct wlr_box box;
-		if (!(c = client_from_popup(xdg_surface->popup)))
+		if (!(c = client_from_popup(xdg_surface->popup)) || !c->mon)
 			return;
-		client_get_geometry(c, &box);
+		box = c->mon->m;
+		box.x -= c->geom.x;
+		box.y -= c->geom.y;
 		wlr_xdg_popup_unconstrain_from_box(xdg_surface->popup, &box);
 		return;
 	} else if (xdg_surface->role == WLR_XDG_SURFACE_ROLE_NONE)
-- 
cgit v1.2.3


From f1c92b05fb124d6865d4dfb0c121b3dbf7fd5407 Mon Sep 17 00:00:00 2001
From: Leonardo Hernández Hernández <leohdz172@protonmail.com>
Date: Fri, 18 Mar 2022 00:49:47 -0600
Subject: get old client by surface's node

---
 dwl.c | 15 +++++----------
 1 file changed, 5 insertions(+), 10 deletions(-)

diff --git a/dwl.c b/dwl.c
index 347178b..4df0e95 100644
--- a/dwl.c
+++ b/dwl.c
@@ -1076,7 +1076,6 @@ focusclient(Client *c, int lift)
 {
 	struct wlr_surface *old = seat->keyboard_state.focused_surface;
 	struct wlr_keyboard *kb;
-	Client *w;
 	int i;
 
 	/* Raise client in stacking order if requested */
@@ -1114,15 +1113,11 @@ focusclient(Client *c, int lift)
 						))
 				return;
 		} else {
-#ifdef XWAYLAND
-			if (wlr_surface_is_xwayland_surface(old))
-				w = wlr_xwayland_surface_from_wlr_surface(old)->data;
-			else
-#endif
-				w = wlr_xdg_surface_from_wlr_surface(old)->data;
-
-			for (i = 0; i < 4; i++)
-				wlr_scene_rect_set_color(w->border[i], bordercolor);
+			Client *w;
+			struct wlr_scene_node *node = old->data;
+			if ((w = node->data))
+				for (i = 0; i < 4; i++)
+					wlr_scene_rect_set_color(w->border[i], bordercolor);
 
 			client_activate_surface(old, 0);
 		}
-- 
cgit v1.2.3


From 1b22ef16161fe832e14aa29678e09eb7df56e395 Mon Sep 17 00:00:00 2001
From: Leonardo Hernández Hernández <leohdz172@protonmail.com>
Date: Fri, 18 Mar 2022 00:52:21 -0600
Subject: use xdg_shell helper

for xwayland continue using wlr_scene_subsurface_create()
---
 dwl.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/dwl.c b/dwl.c
index 4df0e95..464554c 100644
--- a/dwl.c
+++ b/dwl.c
@@ -1319,8 +1319,9 @@ mapnotify(struct wl_listener *listener, void *data)
 
 	/* Create scene tree for this client and its border */
 	c->scene = &wlr_scene_tree_create(layers[LyrTile])->node;
-	c->scene_surface = client_surface(c)->data =
-		wlr_scene_subsurface_tree_create(c->scene, client_surface(c));
+	c->scene_surface = client_surface(c)->data = c->type == XDGShell
+			? wlr_scene_xdg_surface_create(c->scene, c->surface.xdg)
+			: wlr_scene_subsurface_tree_create(c->scene, client_surface(c));
 	c->scene_surface->data = c;
 	for (i = 0; i < 4; i++) {
 		c->border[i] = wlr_scene_rect_create(c->scene, 0, 0, bordercolor);
-- 
cgit v1.2.3


From 0815626d4c4db3aa05ed256975476d6a31be2125 Mon Sep 17 00:00:00 2001
From: Leonardo Hernández Hernández <leohdz172@protonmail.com>
Date: Fri, 18 Mar 2022 00:59:52 -0600
Subject: pointerfocus: only use provided surface

if a client is given focus it
---
 dwl.c | 22 ++++++----------------
 1 file changed, 6 insertions(+), 16 deletions(-)

diff --git a/dwl.c b/dwl.c
index 464554c..392cec1 100644
--- a/dwl.c
+++ b/dwl.c
@@ -1540,9 +1540,8 @@ pointerfocus(Client *c, struct wlr_surface *surface, double sx, double sy,
 	struct timespec now;
 	int internal_call = !time;
 
-	/* Use top level surface if nothing more specific given */
-	if (c && !surface)
-		surface = client_surface(c);
+	if (sloppyfocus && !internal_call && c && !client_is_unmanaged(c))
+		focusclient(c, 0);
 
 	/* If surface is NULL, clear pointer focus */
 	if (!surface) {
@@ -1555,21 +1554,12 @@ pointerfocus(Client *c, struct wlr_surface *surface, double sx, double sy,
 		time = now.tv_sec * 1000 + now.tv_nsec / 1000000;
 	}
 
-	/* If surface is already focused, only notify of motion */
-	if (surface == seat->pointer_state.focused_surface) {
-		wlr_seat_pointer_notify_motion(seat, time, sx, sy);
-		return;
-	}
-
-	/* Otherwise, let the client know that the mouse cursor has entered one
-	 * of its surfaces, and make keyboard focus follow if desired. */
+	/* Let the client know that the mouse cursor has entered one
+	 * of its surfaces, and make keyboard focus follow if desired.
+	 * wlroots makes this a no-op if surface is already focused */
 	wlr_seat_pointer_notify_enter(seat, surface, sx, sy);
+	wlr_seat_pointer_notify_motion(seat, time, sx, sy);
 
-	if (!c || client_is_unmanaged(c))
-		return;
-
-	if (sloppyfocus && !internal_call)
-		focusclient(c, 0);
 }
 
 void
-- 
cgit v1.2.3


From 254f799fde51faf71ce3ec5e7af75826f4263d81 Mon Sep 17 00:00:00 2001
From: Leonardo Hernández Hernández <leohdz172@protonmail.com>
Date: Fri, 18 Mar 2022 01:02:50 -0600
Subject: do not create borders for unmanaged clients

---
 dwl.c | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/dwl.c b/dwl.c
index 392cec1..8f6e816 100644
--- a/dwl.c
+++ b/dwl.c
@@ -1323,17 +1323,11 @@ mapnotify(struct wl_listener *listener, void *data)
 			? wlr_scene_xdg_surface_create(c->scene, c->surface.xdg)
 			: wlr_scene_subsurface_tree_create(c->scene, client_surface(c));
 	c->scene_surface->data = c;
-	for (i = 0; i < 4; i++) {
-		c->border[i] = wlr_scene_rect_create(c->scene, 0, 0, bordercolor);
-		c->border[i]->node.data = c;
-		wlr_scene_rect_set_color(c->border[i], bordercolor);
-	}
 
 	if (client_is_unmanaged(c)) {
 		client_get_geometry(c, &c->geom);
-		/* Floating, no border */
+		/* Floating */
 		wlr_scene_node_reparent(c->scene, layers[LyrFloat]);
-		c->bw = 0;
 		wlr_scene_node_set_position(c->scene, c->geom.x + borderpx,
 			c->geom.y + borderpx);
 
@@ -1342,6 +1336,13 @@ mapnotify(struct wl_listener *listener, void *data)
 		return;
 	}
 
+	for (i = 0; i < 4; i++) {
+		c->border[i] = wlr_scene_rect_create(c->scene, 0, 0, bordercolor);
+		c->border[i]->node.data = c;
+		wlr_scene_rect_set_color(c->border[i], bordercolor);
+		wlr_scene_node_lower_to_bottom(&c->border[i]->node);
+	}
+
 	/* Initialize client geometry with room for border */
 	client_set_tiled(c, WLR_EDGE_TOP | WLR_EDGE_BOTTOM | WLR_EDGE_LEFT | WLR_EDGE_RIGHT);
 	client_get_geometry(c, &c->geom);
-- 
cgit v1.2.3


From 467123dc99db4a537f1043e081cc4a6db136417b Mon Sep 17 00:00:00 2001
From: Leonardo Hernández Hernández <leohdz172@protonmail.com>
Date: Fri, 18 Mar 2022 01:03:33 -0600
Subject: make sure to destroy wlr_scene_node of unmanaged clients

---
 dwl.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/dwl.c b/dwl.c
index 8f6e816..c63dbe4 100644
--- a/dwl.c
+++ b/dwl.c
@@ -2139,8 +2139,10 @@ unmapnotify(struct wl_listener *listener, void *data)
 		grabc = NULL;
 	}
 	wl_list_remove(&c->link);
-	if (client_is_unmanaged(c))
+	if (client_is_unmanaged(c)) {
+		wlr_scene_node_destroy(c->scene);
 		return;
+	}
 
 	setmon(c, NULL, 0);
 	wl_list_remove(&c->flink);
-- 
cgit v1.2.3


From 475c13414479d1013c83309fcc4bb8a8707aa721 Mon Sep 17 00:00:00 2001
From: Leonardo Hernández Hernández <leohdz172@protonmail.com>
Date: Fri, 18 Mar 2022 01:25:53 -0600
Subject: do not allow set client size less than its min size

---
 client.h | 20 ++++++++++++++++++++
 dwl.c    |  6 ++++--
 2 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/client.h b/client.h
index 191dcc5..c59b7a9 100644
--- a/client.h
+++ b/client.h
@@ -179,3 +179,23 @@ client_surface_at(Client *c, double cx, double cy, double *sx, double *sy)
 #endif
 	return wlr_xdg_surface_surface_at(c->surface.xdg, cx, cy, sx, sy);
 }
+
+static inline void
+client_min_size(Client *c, int *width, int *height)
+{
+	struct wlr_xdg_toplevel *toplevel;
+	struct wlr_xdg_toplevel_state *state;
+#ifdef XWAYLAND
+	if (client_is_x11(c)) {
+		struct wlr_xwayland_surface_size_hints *size_hints;
+		size_hints = c->surface.xwayland->size_hints;
+		*width = size_hints->min_width;
+		*height = size_hints->min_height;
+		return;
+	}
+#endif
+	toplevel = c->surface.xdg->toplevel;
+	state = &toplevel->current;
+	*width = state->min_width;
+	*height = state->min_height;
+}
diff --git a/dwl.c b/dwl.c
index c63dbe4..d2f0718 100644
--- a/dwl.c
+++ b/dwl.c
@@ -1636,11 +1636,13 @@ rendermon(struct wl_listener *listener, void *data)
 void
 resize(Client *c, int x, int y, int w, int h, int interact)
 {
+	int min_width = 0, min_height = 0;
 	struct wlr_box *bbox = interact ? &sgeom : &c->mon->w;
+	client_min_size(c, &min_width, &min_height);
 	c->geom.x = x;
 	c->geom.y = y;
-	c->geom.width = w;
-	c->geom.height = h;
+	c->geom.width = MAX(min_width + 2 * c->bw, w);
+	c->geom.height = MAX(min_height + 2 * c->bw, h);
 	applybounds(c, bbox);
 
 	/* Update scene-graph, including borders */
-- 
cgit v1.2.3


From e4bf83e26d4eccfcab3d54c6ebdbcc53a90346cd Mon Sep 17 00:00:00 2001
From: Leonardo Hernández Hernández <leohdz172@protonmail.com>
Date: Fri, 18 Mar 2022 01:43:30 -0600
Subject: update README.md

---
 README.md | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/README.md b/README.md
index 1389803..d094599 100644
--- a/README.md
+++ b/README.md
@@ -19,15 +19,14 @@ dwl is not meant to provide every feature under the sun. Instead, like dwm, it s
 - Various Wayland protocols
 - XWayland support as provided by wlroots (can be enabled in `config.mk`)
 - Zero flickering - Wayland users naturally expect that "every frame is perfect"
+- Layer shell popups (used by Waybar)
+- Damage tracking provided by scenegraph API
 
 Features under consideration (possibly as patches) are:
 
 - Protocols made trivial by wlroots
-- Implement the input-inhibitor protocol to support screen lockers
-- Implement the idle-inhibit protocol which lets applications such as mpv disable idle monitoring
-- Layer shell popups (used by Waybar)
-- Basic yes/no damage tracking to avoid needless redraws
-- More in-depth damage region tracking ([which may improve power usage](https://mozillagfx.wordpress.com/2019/10/22/dramatically-reduced-power-usage-in-firefox-70-on-macos-with-core-animation/))
+- Implement the input-inhibitor protocol to support screen lockers (see https://github.com/djpohly/dwl/pull/132)
+- Implement the idle-inhibit protocol which lets applications such as mpv disable idle monitoring (see https://github.com/djpohly/dwl/pull/133)
 - Implement the text-input and input-method protocols to support IME once ibus implements input-method v2 (see https://github.com/ibus/ibus/pull/2256 and https://github.com/djpohly/dwl/pull/12)
 
 Feature *non-goals* for the main codebase include:
-- 
cgit v1.2.3


From e645ea8301f3d6edf14cfb36c4d663bf721d3200 Mon Sep 17 00:00:00 2001
From: Leonardo Hernández Hernández <leohdz172@protonmail.com>
Date: Fri, 18 Mar 2022 10:40:40 -0600
Subject: attach presentation to scene

---
 dwl.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/dwl.c b/dwl.c
index bb3ff9a..7f4da78 100644
--- a/dwl.c
+++ b/dwl.c
@@ -1986,6 +1986,7 @@ setup(void)
 	wl_signal_add(&output_mgr->events.test, &output_mgr_test);
 
 	presentation = wlr_presentation_create(dpy, backend);
+	wlr_scene_set_presentation(scene, presentation);
 
 #ifdef XWAYLAND
 	/*
-- 
cgit v1.2.3


From 19c14b058c9188b7010ffd62bcb1276417e9ed67 Mon Sep 17 00:00:00 2001
From: Leonardo Hernández Hernández <leohdz172@protonmail.com>
Date: Fri, 18 Mar 2022 11:04:34 -0600
Subject: remove unneeded variables

---
 dwl.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/dwl.c b/dwl.c
index 7f4da78..2d95286 100644
--- a/dwl.c
+++ b/dwl.c
@@ -1625,8 +1625,7 @@ rendermon(struct wl_listener *listener, void *data)
 	 * generally at the output's refresh rate (e.g. 60Hz). */
 	Monitor *m = wl_container_of(listener, m, frame);
 	Client *c;
-	LayerSurface *layer;
-	int i, skip = 0;
+	int skip = 0;
 	struct timespec now;
 
 	/* Render if no XDG clients have an outstanding resize. */
-- 
cgit v1.2.3


From dd463b25c7de4ea802038997a93ea749297b8c2d Mon Sep 17 00:00:00 2001
From: Leonardo Hernández Hernández <leohdz172@protonmail.com>
Date: Sun, 20 Mar 2022 12:32:44 -0600
Subject: remove independents list

---
 dwl.c | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/dwl.c b/dwl.c
index 2d95286..01f51ad 100644
--- a/dwl.c
+++ b/dwl.c
@@ -302,7 +302,6 @@ static struct wlr_xdg_shell *xdg_shell;
 static struct wlr_xdg_activation_v1 *activation;
 static struct wl_list clients; /* tiling order */
 static struct wl_list fstack;  /* focus order */
-static struct wl_list independents;
 static struct wlr_idle *idle;
 static struct wlr_layer_shell_v1 *layer_shell;
 static struct wlr_output_manager_v1 *output_mgr;
@@ -1337,9 +1336,6 @@ mapnotify(struct wl_listener *listener, void *data)
 		wlr_scene_node_reparent(c->scene, layers[LyrFloat]);
 		wlr_scene_node_set_position(c->scene, c->geom.x + borderpx,
 			c->geom.y + borderpx);
-
-		/* Insert this independent into independents lists. */
-		wl_list_insert(&independents, &c->link);
 		return;
 	}
 
@@ -1917,7 +1913,6 @@ setup(void)
 	 */
 	wl_list_init(&clients);
 	wl_list_init(&fstack);
-	wl_list_init(&independents);
 
 	idle = wlr_idle_create(dpy);
 
@@ -2147,12 +2142,13 @@ unmapnotify(struct wl_listener *listener, void *data)
 		cursor_mode = CurNormal;
 		grabc = NULL;
 	}
-	wl_list_remove(&c->link);
+
 	if (client_is_unmanaged(c)) {
 		wlr_scene_node_destroy(c->scene);
 		return;
 	}
 
+	wl_list_remove(&c->link);
 	setmon(c, NULL, 0);
 	wl_list_remove(&c->flink);
 	wlr_scene_node_destroy(c->scene);
-- 
cgit v1.2.3