From df34fdd4831bb4f94ad261d743edcd0493c24f9c Mon Sep 17 00:00:00 2001
From: Jan Beich <jbeich@FreeBSD.org>
Date: Fri, 2 Dec 2022 16:37:15 +0000
Subject: chase default terminal in manpage after 7710cf050d1a

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

diff --git a/dwl.1 b/dwl.1
index d958210..cae1036 100644
--- a/dwl.1
+++ b/dwl.1
@@ -51,7 +51,7 @@ Spawn
 .Nm bemenu-run .
 .It Mod-Shift-Return
 Spawn
-.Nm alacritty .
+.Nm foot .
 .It Mod-[jk]
 Move focus down/up the stack.
 .It Mod-[id]
@@ -135,7 +135,7 @@ Start
 with s6 in the background:
 .Dl dwl -s 's6-svscan <&-'
 .Sh SEE ALSO
-.Xr alacritty 1 ,
+.Xr foot 1 ,
 .Xr bemenu 1 ,
 .Xr dwm 1 ,
 .Xr xkeyboard-config 7
-- 
cgit v1.2.3


From 9c155eefdc018f878ea6950e6bd383b985401339 Mon Sep 17 00:00:00 2001
From: Ben Jargowsky <benjar63@gmail.com>
Date: Fri, 2 Dec 2022 11:15:55 -0800
Subject: Check that inhibitor scene tree is not null

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

diff --git a/dwl.c b/dwl.c
index 5f6d061..7ab649a 100644
--- a/dwl.c
+++ b/dwl.c
@@ -598,7 +598,7 @@ checkidleinhibitor(struct wlr_surface *exclude)
 	wl_list_for_each(inhibitor, &idle_inhibit_mgr->inhibitors, link) {
 		struct wlr_scene_tree *tree = inhibitor->surface->data;
 		if (bypass_surface_visibility || (exclude != inhibitor->surface
-				&& tree->node.enabled)) {
+				&& tree && tree->node.enabled)) {
 			inhibited = 1;
 			break;
 		}
-- 
cgit v1.2.3


From 035bb99d67b59a84cfc2e911d222fb597591a8be Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?=
 <leohdz172@protonmail.com>
Date: Fri, 2 Dec 2022 23:22:58 -0600
Subject: Revert "Check that inhibitor scene tree is not null"

This reverts commit 9c155eefdc018f878ea6950e6bd383b985401339.

This commit was applied just a workaround, the proper fix is the next commit
---
 dwl.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/dwl.c b/dwl.c
index 7ab649a..5f6d061 100644
--- a/dwl.c
+++ b/dwl.c
@@ -598,7 +598,7 @@ checkidleinhibitor(struct wlr_surface *exclude)
 	wl_list_for_each(inhibitor, &idle_inhibit_mgr->inhibitors, link) {
 		struct wlr_scene_tree *tree = inhibitor->surface->data;
 		if (bypass_surface_visibility || (exclude != inhibitor->surface
-				&& tree && tree->node.enabled)) {
+				&& tree->node.enabled)) {
 			inhibited = 1;
 			break;
 		}
-- 
cgit v1.2.3


From fac3b6f2cf7e2d5e9de2b0618a5a2ad2e0809b03 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?=
 <leohdz172@protonmail.com>
Date: Fri, 2 Dec 2022 22:53:03 -0600
Subject: use root surfaces to check idle inhibitors

References: https://github.com/djpohly/dwl/pull/343
---
 dwl.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/dwl.c b/dwl.c
index 5f6d061..a635cbe 100644
--- a/dwl.c
+++ b/dwl.c
@@ -596,8 +596,9 @@ checkidleinhibitor(struct wlr_surface *exclude)
 	int inhibited = 0;
 	struct wlr_idle_inhibitor_v1 *inhibitor;
 	wl_list_for_each(inhibitor, &idle_inhibit_mgr->inhibitors, link) {
-		struct wlr_scene_tree *tree = inhibitor->surface->data;
-		if (bypass_surface_visibility || (exclude != inhibitor->surface
+		struct wlr_surface *surface = wlr_surface_get_root_surface(inhibitor->surface);
+		struct wlr_scene_tree *tree = surface->data;
+		if (bypass_surface_visibility || (exclude != surface
 				&& tree->node.enabled)) {
 			inhibited = 1;
 			break;
@@ -1014,7 +1015,7 @@ destroyidleinhibitor(struct wl_listener *listener, void *data)
 {
 	/* `data` is the wlr_surface of the idle inhibitor being destroyed,
 	 * at this point the idle inhibitor is still in the list of the manager */
-	checkidleinhibitor(data);
+	checkidleinhibitor(wlr_surface_get_root_surface(data));
 }
 
 void
-- 
cgit v1.2.3


From 017bb7d7521f68d37bfe656c10f45edbcc92dd61 Mon Sep 17 00:00:00 2001
From: Palanix <palanixyt@gmail.com>
Date: Wed, 31 Aug 2022 06:11:07 +0200
Subject: fix flickering when resizing/spawning windows

Fixes: https://github.com/djpohly/dwl/issues/306
---
 client.h | 15 +++++++++++++++
 dwl.c    | 29 ++++++-----------------------
 2 files changed, 21 insertions(+), 23 deletions(-)

diff --git a/client.h b/client.h
index c18d01a..4dc9e1a 100644
--- a/client.h
+++ b/client.h
@@ -197,6 +197,21 @@ client_is_mapped(Client *c)
 	return c->surface.xdg->mapped;
 }
 
+static inline int
+client_is_rendered_on_mon(Client *c, Monitor *m)
+{
+	/* This is needed for when you don't want to check formal assignment,
+	 * but rather actual displaying of the pixels.
+	 * Usually VISIBLEON suffices and is also faster. */
+	struct wlr_surface_output *s;
+	if (!c->scene->node.enabled)
+		return 0;
+	wl_list_for_each(s, &client_surface(c)->current_outputs, link)
+		if (s->output == m->wlr_output)
+			return 1;
+	return 0;
+}
+
 static inline int
 client_is_unmanaged(Client *c)
 {
diff --git a/dwl.c b/dwl.c
index a635cbe..c409187 100644
--- a/dwl.c
+++ b/dwl.c
@@ -182,7 +182,6 @@ struct Monitor {
 	unsigned int tagset[2];
 	double mfact;
 	int nmaster;
-	int un_map; /* If a map/unmap happened on this monitor, then this should be true */
 };
 
 typedef struct {
@@ -1393,8 +1392,6 @@ mapnotify(struct wl_listener *listener, void *data)
 	}
 	printstatus();
 
-	c->mon->un_map = 1;
-
 unset_fullscreen:
 	m = c->mon ? c->mon : xytomon(c->geom.x, c->geom.y);
 	wl_list_for_each(w, &clients, link)
@@ -1693,30 +1690,19 @@ 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;
-	int skip = 0;
 	struct timespec now;
 
-	clock_gettime(CLOCK_MONOTONIC, &now);
-
 	/* Render if no XDG clients have an outstanding resize and are visible on
 	 * this monitor. */
-	/* Checking m->un_map for every client is not optimal but works */
-	wl_list_for_each(c, &clients, link) {
-		if ((c->resize && m->un_map) || (c->type == XDGShell
-				&& (c->surface.xdg->pending.geometry.width !=
-				c->surface.xdg->current.geometry.width
-				|| c->surface.xdg->pending.geometry.height !=
-				c->surface.xdg->current.geometry.height))) {
-			/* Lie */
-			wlr_surface_send_frame_done(client_surface(c), &now);
-			skip = 1;
-		}
-	}
-	if (!skip && !wlr_scene_output_commit(m->scene_output))
+	wl_list_for_each(c, &clients, link)
+		if (client_is_rendered_on_mon(c, m) && (!c->isfloating && c->resize))
+			goto skip;
+	if (!wlr_scene_output_commit(m->scene_output))
 		return;
+skip:
 	/* Let clients know a frame has been rendered */
+	clock_gettime(CLOCK_MONOTONIC, &now);
 	wlr_scene_output_send_frame_done(m->scene_output, &now);
-	m->un_map = 0;
 }
 
 void
@@ -2281,9 +2267,6 @@ unmapnotify(struct wl_listener *listener, void *data)
 		grabc = NULL;
 	}
 
-	if (c->mon)
-		c->mon->un_map = 1;
-
 	if (client_is_unmanaged(c)) {
 		if (c == exclusive_focus)
 			exclusive_focus = NULL;
-- 
cgit v1.2.3


From 30c24a53ad2aaa842bc3b028ba0b98e3362dad7c Mon Sep 17 00:00:00 2001
From: Palanix <palanixyt@gmail.com>
Date: Sat, 24 Sep 2022 13:37:05 +0200
Subject: remove unneeded changes in commitnotify()

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

diff --git a/dwl.c b/dwl.c
index c409187..cea34cc 100644
--- a/dwl.c
+++ b/dwl.c
@@ -729,14 +729,9 @@ commitnotify(struct wl_listener *listener, void *data)
 	struct wlr_box box = {0};
 	client_get_geometry(c, &box);
 
-	if (c->mon && !wlr_box_empty(&box) && (box.width != c->geom.width - 2 * c->bw
-			|| box.height != c->geom.height - 2 * c->bw))
-		arrange(c->mon);
 
 	/* mark a pending resize as completed */
-	if (c->resize && (c->resize <= c->surface.xdg->current.configure_serial
-			|| (c->surface.xdg->current.geometry.width == c->surface.xdg->pending.geometry.width
-			&& c->surface.xdg->current.geometry.height == c->surface.xdg->pending.geometry.height)))
+	if (c->resize && (c->resize <= c->surface.xdg->current.configure_serial))
 		c->resize = 0;
 }
 
-- 
cgit v1.2.3


From 16a49e99557563252b9f91db767b431e2238f587 Mon Sep 17 00:00:00 2001
From: Dima Krasner <dima@dimakrasner.com>
Date: Sat, 3 Dec 2022 12:06:29 +0200
Subject: fix null deref in sigchld() if Xwayland is disabled

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

diff --git a/dwl.c b/dwl.c
index cea34cc..3891cb7 100644
--- a/dwl.c
+++ b/dwl.c
@@ -2543,7 +2543,7 @@ sigchld(int unused)
 	 * XWayland process
 	 */
 	while (!waitid(P_ALL, 0, &in, WEXITED|WNOHANG|WNOWAIT) && in.si_pid
-			&& in.si_pid != xwayland->server->pid)
+			&& (!xwayland || in.si_pid != xwayland->server->pid))
 		waitpid(in.si_pid, NULL, 0);
 }
 
-- 
cgit v1.2.3


From b6d6127733ea5f96db57a9f47fa4a6134a868a19 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?=
 <leohdz172@protonmail.com>
Date: Wed, 1 Jun 2022 21:38:45 -0500
Subject: add option for set button map

---
 config.def.h | 5 +++++
 dwl.c        | 1 +
 2 files changed, 6 insertions(+)

diff --git a/config.def.h b/config.def.h
index 8f01192..a4f7c13 100644
--- a/config.def.h
+++ b/config.def.h
@@ -85,6 +85,11 @@ LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE
 */
 static const enum libinput_config_accel_profile accel_profile = LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE;
 static const double accel_speed = 0.0;
+/* You can choose between:
+LIBINPUT_CONFIG_TAP_MAP_LRM -- 1/2/3 finger tap maps to left/right/middle
+LIBINPUT_CONFIG_TAP_MAP_LMR -- 1/2/3 finger tap maps to left/middle/right
+*/
+static const enum libinput_config_tap_button_map button_map = LIBINPUT_CONFIG_TAP_MAP_LRM;
 
 /* If you want to use the windows key for MODKEY, use WLR_MODIFIER_LOGO */
 #define MODKEY WLR_MODIFIER_ALT
diff --git a/dwl.c b/dwl.c
index 3891cb7..2a8162c 100644
--- a/dwl.c
+++ b/dwl.c
@@ -951,6 +951,7 @@ createpointer(struct wlr_pointer *pointer)
 			libinput_device_config_tap_set_enabled(libinput_device, tap_to_click);
 			libinput_device_config_tap_set_drag_enabled(libinput_device, tap_and_drag);
 			libinput_device_config_tap_set_drag_lock_enabled(libinput_device, drag_lock);
+			libinput_device_config_tap_set_button_map(libinput_device, button_map);
 		}
 
 		if (libinput_device_config_scroll_has_natural_scroll(libinput_device))
-- 
cgit v1.2.3


From 13b929d7d79a7142901d0e7035806ee7f3b7af9d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?=
 <leohdz172@protonmail.com>
Date: Mon, 5 Dec 2022 23:06:53 -0600
Subject: remove unneeded call to wlr_scene_rect_set_color()

wlr_scene_rect_create() requires a color as parameter
---
 dwl.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/dwl.c b/dwl.c
index 2a8162c..c304256 100644
--- a/dwl.c
+++ b/dwl.c
@@ -1361,7 +1361,6 @@ mapnotify(struct wl_listener *listener, void *data)
 	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);
 	}
 
 	/* Initialize client geometry with room for border */
-- 
cgit v1.2.3


From c56bc42eb5480783f3bc97f769bac3d9eebcb373 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?=
 <leohdz172@protonmail.com>
Date: Sat, 3 Dec 2022 14:30:38 -0600
Subject: sort client_get_parent()

---
 client.h | 26 +++++++++++++-------------
 1 file changed, 13 insertions(+), 13 deletions(-)

diff --git a/client.h b/client.h
index 4dc9e1a..b443a8d 100644
--- a/client.h
+++ b/client.h
@@ -37,19 +37,6 @@ client_from_wlr_surface(struct wlr_surface *s)
 	return NULL;
 }
 
-static inline Client *
-client_get_parent(Client *c)
-{
-#ifdef XWAYLAND
-	if (client_is_x11(c) && c->surface.xwayland->parent)
-		return client_from_wlr_surface(c->surface.xwayland->parent->surface);
-#endif
-	if (c->surface.xdg->toplevel->parent)
-		return client_from_wlr_surface(c->surface.xdg->toplevel->parent->base->surface);
-
-	return NULL;
-}
-
 static inline void
 client_get_size_hints(Client *c, struct wlr_box *max, struct wlr_box *min)
 {
@@ -153,6 +140,19 @@ client_get_geometry(Client *c, struct wlr_box *geom)
 	wlr_xdg_surface_get_geometry(c->surface.xdg, geom);
 }
 
+static inline Client *
+client_get_parent(Client *c)
+{
+#ifdef XWAYLAND
+	if (client_is_x11(c) && c->surface.xwayland->parent)
+		return toplevel_from_wlr_surface(c->surface.xwayland->parent->surface);
+#endif
+	if (c->surface.xdg->toplevel->parent)
+		return toplevel_from_wlr_surface(c->surface.xdg->toplevel->parent->base->surface);
+
+	return NULL;
+}
+
 static inline const char *
 client_get_title(Client *c)
 {
-- 
cgit v1.2.3


From 38bd00351a444d37184716d6124bb47817758bc9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?=
 <leohdz172@protonmail.com>
Date: Sat, 3 Dec 2022 14:31:18 -0600
Subject: merge toplevel_from_{wlr_layer_surface,popup} into
 client_from_wlr_surface

now it is a big function called toplevel_from_wlr_surface
---
 client.h | 108 +++++++++++++++++++++++++++------------------------------------
 dwl.c    |  10 +++---
 2 files changed, 52 insertions(+), 66 deletions(-)

diff --git a/client.h b/client.h
index b443a8d..c12a107 100644
--- a/client.h
+++ b/client.h
@@ -16,27 +16,6 @@ client_is_x11(Client *c)
 #endif
 }
 
-static inline Client *
-client_from_wlr_surface(struct wlr_surface *s)
-{
-	struct wlr_xdg_surface *surface;
-
-#ifdef XWAYLAND
-	struct wlr_xwayland_surface *xsurface;
-	if (s && wlr_surface_is_xwayland_surface(s)
-			&& (xsurface = wlr_xwayland_surface_from_wlr_surface(s)))
-		return xsurface->data;
-#endif
-	if (s && wlr_surface_is_xdg_surface(s)
-			&& (surface = wlr_xdg_surface_from_wlr_surface(s))
-			&& surface->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL)
-		return surface->data;
-
-	if (s && wlr_surface_is_subsurface(s))
-		return client_from_wlr_surface(wlr_surface_get_root_surface(s));
-	return NULL;
-}
-
 static inline void
 client_get_size_hints(Client *c, struct wlr_box *max, struct wlr_box *min)
 {
@@ -72,6 +51,53 @@ client_surface(Client *c)
 	return c->surface.xdg->surface;
 }
 
+static inline void *
+toplevel_from_wlr_surface(struct wlr_surface *s)
+{
+	struct wlr_xdg_surface *xdg_surface;
+	struct wlr_surface *root_surface;
+	struct wlr_layer_surface_v1 *layer_surface;
+#ifdef XWAYLAND
+	struct wlr_xwayland_surface *xsurface;
+#endif
+
+	if (!s)
+		return NULL;
+	root_surface = wlr_surface_get_root_surface(s);
+
+#ifdef XWAYLAND
+	if (wlr_surface_is_xwayland_surface(root_surface)
+			&& (xsurface = wlr_xwayland_surface_from_wlr_surface(root_surface)))
+		return xsurface->data;
+#endif
+
+	if (wlr_surface_is_layer_surface(root_surface)
+			&& (layer_surface = wlr_layer_surface_v1_from_wlr_surface(root_surface)))
+		return layer_surface->data;
+
+	if (wlr_surface_is_xdg_surface(root_surface)
+			&& (xdg_surface = wlr_xdg_surface_from_wlr_surface(root_surface))) {
+		while (1) {
+			switch (xdg_surface->role) {
+			case WLR_XDG_SURFACE_ROLE_POPUP:
+				if (!xdg_surface->popup->parent)
+					return NULL;
+				else if (!wlr_surface_is_xdg_surface(xdg_surface->popup->parent))
+					return toplevel_from_wlr_surface(xdg_surface->popup->parent);
+
+				xdg_surface = wlr_xdg_surface_from_wlr_surface(xdg_surface->popup->parent);
+				break;
+			case WLR_XDG_SURFACE_ROLE_TOPLEVEL:
+					return xdg_surface->data;
+			case WLR_XDG_SURFACE_ROLE_NONE:
+				return NULL;
+			}
+		}
+	}
+
+	return NULL;
+}
+
 /* The others */
 static inline void
 client_activate_surface(struct wlr_surface *s, int activated)
@@ -320,43 +346,3 @@ client_wants_fullscreen(Client *c)
 #endif
 	return c->surface.xdg->toplevel->requested.fullscreen;
 }
-
-static inline void *
-toplevel_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 (!surface->popup->parent)
-				return NULL;
-			else if (wlr_surface_is_layer_surface(surface->popup->parent))
-				return wlr_layer_surface_v1_from_wlr_surface(surface->popup->parent)->data;
-			else 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;
-		}
-	}
-}
-
-static inline void *
-toplevel_from_wlr_layer_surface(struct wlr_surface *s)
-{
-	Client *c;
-	struct wlr_layer_surface_v1 *wlr_layer_surface;
-
-	if ((c = client_from_wlr_surface(s)))
-		return c;
-	else if (s && wlr_surface_is_layer_surface(s)
-			&& (wlr_layer_surface = wlr_layer_surface_v1_from_wlr_surface(s)))
-		return wlr_layer_surface->data;
-
-	return NULL;
-}
diff --git a/dwl.c b/dwl.c
index c304256..9c2fc3d 100644
--- a/dwl.c
+++ b/dwl.c
@@ -908,7 +908,7 @@ createnotify(struct wl_listener *listener, void *data)
 
 	if (xdg_surface->role == WLR_XDG_SURFACE_ROLE_POPUP) {
 		struct wlr_box box;
-		LayerSurface *l = toplevel_from_popup(xdg_surface->popup);
+		LayerSurface *l = toplevel_from_wlr_surface(xdg_surface->surface);
 		if (!xdg_surface->popup->parent)
 			return;
 		xdg_surface->surface->data = wlr_scene_xdg_surface_create(
@@ -1096,7 +1096,7 @@ focusclient(Client *c, int lift)
 		/* If an overlay is focused, don't focus or activate the client,
 		 * but only update its position in fstack to render its border with focuscolor
 		 * and focus it after the overlay is closed. */
-		Client *w = client_from_wlr_surface(old);
+		Client *w = toplevel_from_wlr_surface(old);
 		if (wlr_surface_is_layer_surface(old)) {
 			struct wlr_layer_surface_v1 *wlr_layer_surface =
 				wlr_layer_surface_v1_from_wlr_surface(old);
@@ -1472,7 +1472,7 @@ motionnotify(uint32_t time)
 	xytonode(cursor->x, cursor->y, &surface, &c, NULL, &sx, &sy);
 
 	if (cursor_mode == CurPressed && !seat->drag) {
-		if ((l = toplevel_from_wlr_layer_surface(
+		if ((l = toplevel_from_wlr_surface(
 				 seat->pointer_state.focused_surface))) {
 			surface = seat->pointer_state.focused_surface;
 			sx = cursor->x - l->geom.x;
@@ -2357,8 +2357,8 @@ void
 urgent(struct wl_listener *listener, void *data)
 {
 	struct wlr_xdg_activation_v1_request_activate_event *event = data;
-	Client *c = client_from_wlr_surface(event->surface);
-	if (c && c != selclient()) {
+	Client *c = toplevel_from_wlr_surface(event->surface);
+	if (c && c->type != LayerShell && c != selclient()) {
 		c->isurgent = 1;
 		printstatus();
 	}
-- 
cgit v1.2.3


From 22336612ae75954c68a7d4cd3f30fbebf94f441f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?=
 <leohdz172@protonmail.com>
Date: Sat, 3 Dec 2022 15:17:43 -0600
Subject: improve type safety of toplevel_from_wlr_surface()

---
 client.h | 47 ++++++++++++++++++++++++++++++++---------------
 dwl.c    | 49 ++++++++++++++++++++++++-------------------------
 2 files changed, 56 insertions(+), 40 deletions(-)

diff --git a/client.h b/client.h
index c12a107..77cde58 100644
--- a/client.h
+++ b/client.h
@@ -51,29 +51,38 @@ client_surface(Client *c)
 	return c->surface.xdg->surface;
 }
 
-static inline void *
-toplevel_from_wlr_surface(struct wlr_surface *s)
+static inline int
+toplevel_from_wlr_surface(struct wlr_surface *s, Client **pc, LayerSurface **pl)
 {
 	struct wlr_xdg_surface *xdg_surface;
 	struct wlr_surface *root_surface;
 	struct wlr_layer_surface_v1 *layer_surface;
+	Client *c = NULL;
+	LayerSurface *l = NULL;
+	int type = -1;
 #ifdef XWAYLAND
 	struct wlr_xwayland_surface *xsurface;
 #endif
 
 	if (!s)
-		return NULL;
+		return type;
 	root_surface = wlr_surface_get_root_surface(s);
 
 #ifdef XWAYLAND
 	if (wlr_surface_is_xwayland_surface(root_surface)
-			&& (xsurface = wlr_xwayland_surface_from_wlr_surface(root_surface)))
-		return xsurface->data;
+			&& (xsurface = wlr_xwayland_surface_from_wlr_surface(root_surface))) {
+		c = xsurface->data;
+		type = c->type;
+		goto end;
+	}
 #endif
 
 	if (wlr_surface_is_layer_surface(root_surface)
-			&& (layer_surface = wlr_layer_surface_v1_from_wlr_surface(root_surface)))
-		return layer_surface->data;
+			&& (layer_surface = wlr_layer_surface_v1_from_wlr_surface(root_surface))) {
+		l = layer_surface->data;
+		type = LayerShell;
+		goto end;
+	}
 
 	if (wlr_surface_is_xdg_surface(root_surface)
 			&& (xdg_surface = wlr_xdg_surface_from_wlr_surface(root_surface))) {
@@ -81,21 +90,28 @@ toplevel_from_wlr_surface(struct wlr_surface *s)
 			switch (xdg_surface->role) {
 			case WLR_XDG_SURFACE_ROLE_POPUP:
 				if (!xdg_surface->popup->parent)
-					return NULL;
+					return -1;
 				else if (!wlr_surface_is_xdg_surface(xdg_surface->popup->parent))
-					return toplevel_from_wlr_surface(xdg_surface->popup->parent);
+					return toplevel_from_wlr_surface(xdg_surface->popup->parent, pc, pl);
 
 				xdg_surface = wlr_xdg_surface_from_wlr_surface(xdg_surface->popup->parent);
 				break;
 			case WLR_XDG_SURFACE_ROLE_TOPLEVEL:
-					return xdg_surface->data;
+				c = xdg_surface->data;
+				type = c->type;
+				goto end;
 			case WLR_XDG_SURFACE_ROLE_NONE:
-				return NULL;
+				return -1;
 			}
 		}
 	}
 
-	return NULL;
+end:
+	if (pl)
+		*pl = l;
+	if (pc)
+		*pc = c;
+	return type;
 }
 
 /* The others */
@@ -169,14 +185,15 @@ client_get_geometry(Client *c, struct wlr_box *geom)
 static inline Client *
 client_get_parent(Client *c)
 {
+	Client *p = NULL;
 #ifdef XWAYLAND
 	if (client_is_x11(c) && c->surface.xwayland->parent)
-		return toplevel_from_wlr_surface(c->surface.xwayland->parent->surface);
+		toplevel_from_wlr_surface(c->surface.xwayland->parent->surface, &p, NULL);
 #endif
 	if (c->surface.xdg->toplevel->parent)
-		return toplevel_from_wlr_surface(c->surface.xdg->toplevel->parent->base->surface);
+		toplevel_from_wlr_surface(c->surface.xdg->toplevel->parent->base->surface, &p, NULL);
 
-	return NULL;
+	return p;
 }
 
 static inline const char *
diff --git a/dwl.c b/dwl.c
index 9c2fc3d..3d71d19 100644
--- a/dwl.c
+++ b/dwl.c
@@ -904,22 +904,21 @@ createnotify(struct wl_listener *listener, void *data)
 	 * 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;
+	Client *c = NULL;
+	LayerSurface *l = NULL;
 
 	if (xdg_surface->role == WLR_XDG_SURFACE_ROLE_POPUP) {
 		struct wlr_box box;
-		LayerSurface *l = toplevel_from_wlr_surface(xdg_surface->surface);
+		int type = toplevel_from_wlr_surface(xdg_surface->surface, &c, &l);
 		if (!xdg_surface->popup->parent)
 			return;
 		xdg_surface->surface->data = wlr_scene_xdg_surface_create(
 				xdg_surface->popup->parent->data, xdg_surface);
-		/* Probably the check of `l` is useless, the only thing that can be NULL
-		 * is its monitor */
-		if (!l || !l->mon)
+		if ((!l || !l->mon) || (!c || !c->mon))
 			return;
-		box = l->type == LayerShell ? l->mon->m : l->mon->w;
-		box.x -= l->geom.x;
-		box.y -= l->geom.y;
+		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);
 		wlr_xdg_popup_unconstrain_from_box(xdg_surface->popup, &box);
 		return;
 	} else if (xdg_surface->role == WLR_XDG_SURFACE_ROLE_NONE)
@@ -1096,15 +1095,12 @@ focusclient(Client *c, int lift)
 		/* If an overlay is focused, don't focus or activate the client,
 		 * but only update its position in fstack to render its border with focuscolor
 		 * and focus it after the overlay is closed. */
-		Client *w = toplevel_from_wlr_surface(old);
-		if (wlr_surface_is_layer_surface(old)) {
-			struct wlr_layer_surface_v1 *wlr_layer_surface =
-				wlr_layer_surface_v1_from_wlr_surface(old);
-
-			if (wlr_layer_surface && ((LayerSurface *)wlr_layer_surface->data)->mapped
-					&& (wlr_layer_surface->current.layer == ZWLR_LAYER_SHELL_V1_LAYER_TOP
-					|| wlr_layer_surface->current.layer == ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY))
-				return;
+		Client *w = NULL;
+		LayerSurface *l = NULL;
+		int type = toplevel_from_wlr_surface(old, &w, &l);
+		if (type == LayerShell && l->scene->node.enabled
+				&& l->layer_surface->current.layer >= ZWLR_LAYER_SHELL_V1_LAYER_TOP) {
+			return;
 		} else if (w && w == exclusive_focus && client_wants_focus(w)) {
 			return;
 		/* Don't deactivate old client if the new one wants focus, as this causes issues with winecfg
@@ -1438,8 +1434,9 @@ void
 motionnotify(uint32_t time)
 {
 	double sx = 0, sy = 0;
-	Client *c = NULL;
-	LayerSurface *l;
+	Client *c = NULL, *w = NULL;
+	LayerSurface *l = NULL;
+	int type;
 	struct wlr_surface *surface = NULL;
 	struct wlr_drag_icon *icon;
 
@@ -1472,11 +1469,12 @@ motionnotify(uint32_t time)
 	xytonode(cursor->x, cursor->y, &surface, &c, NULL, &sx, &sy);
 
 	if (cursor_mode == CurPressed && !seat->drag) {
-		if ((l = toplevel_from_wlr_surface(
-				 seat->pointer_state.focused_surface))) {
+		if ((type = toplevel_from_wlr_surface(
+				 seat->pointer_state.focused_surface, &w, &l)) >= 0) {
+			c = w;
 			surface = seat->pointer_state.focused_surface;
-			sx = cursor->x - l->geom.x;
-			sy = cursor->y - l->geom.y;
+			sx = cursor->x - (type == LayerShell ? l->geom.x : w->geom.x);
+			sy = cursor->y - (type == LayerShell ? l->geom.y : w->geom.y);
 		}
 	}
 
@@ -2357,8 +2355,9 @@ void
 urgent(struct wl_listener *listener, void *data)
 {
 	struct wlr_xdg_activation_v1_request_activate_event *event = data;
-	Client *c = toplevel_from_wlr_surface(event->surface);
-	if (c && c->type != LayerShell && c != selclient()) {
+	Client *c = NULL;
+	int type = toplevel_from_wlr_surface(event->surface, &c, NULL);
+	if (type >= 0 && type != LayerShell && c != selclient()) {
 		c->isurgent = 1;
 		printstatus();
 	}
-- 
cgit v1.2.3


From c9a0a8bf6de9130655342e362a5a9f09c6a7fd08 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?=
 <leohdz172@protonmail.com>
Date: Mon, 5 Dec 2022 23:21:21 -0600
Subject: bump version to 0.4-rc2

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

diff --git a/config.mk b/config.mk
index c2dd026..86b90ab 100644
--- a/config.mk
+++ b/config.mk
@@ -1,4 +1,4 @@
-_VERSION = 0.4-rc1
+_VERSION = 0.4-rc2
 VERSION  = `git describe --long --tags --dirty 2>/dev/null || echo $(_VERSION)`
 
 PKG_CONFIG = pkg-config
-- 
cgit v1.2.3