From b12cfff672f0705d8259cf26b3a574faa5ca43ae Mon Sep 17 00:00:00 2001
From: wochap <gean.marroquin@gmail.com>
Date: Tue, 4 Jun 2024 16:02:25 -0500
Subject: [PATCH] implement borders patch

tihs patch adds 2 extra borders relative to the client, they don't
change the size of the client
---
 client.h     | 16 +++++++++++++---
 config.def.h |  8 ++++++++
 dwl.c        | 53 ++++++++++++++++++++++++++++++++++++++++++++++++----
 3 files changed, 70 insertions(+), 7 deletions(-)

diff --git a/client.h b/client.h
index 800b867..33fd579 100644
--- a/client.h
+++ b/client.h
@@ -325,11 +325,21 @@ client_send_close(Client *c)
 }
 
 static inline void
-client_set_border_color(Client *c, const float color[static 4])
+client_set_border_color(Client *c, const float color[static 4], const float colors[static 4], const float colore[static 4])
 {
 	int i;
-	for (i = 0; i < 4; i++)
-		wlr_scene_rect_set_color(c->border[i], color);
+	for (i = 0; i < 4; i++) {
+		if (border_color_type == BrdOriginal) {
+			wlr_scene_rect_set_color(c->border[i], color);
+		} else if (border_color_type == BrdStart) {
+			wlr_scene_rect_set_color(c->borders[i], colors);
+		} else if (border_color_type == BrdEnd) {
+			wlr_scene_rect_set_color(c->bordere[i], colore);
+		} else if (border_color_type == BrdStartEnd) {
+			wlr_scene_rect_set_color(c->borders[i], colors);
+			wlr_scene_rect_set_color(c->bordere[i], colore);
+		}
+	}
 }
 
 static inline void
diff --git a/config.def.h b/config.def.h
index 8847e58..2d6bbe5 100644
--- a/config.def.h
+++ b/config.def.h
@@ -7,8 +7,16 @@
 static const int sloppyfocus               = 1;  /* focus follows mouse */
 static const int bypass_surface_visibility = 0;  /* 1 means idle inhibitors will disable idle tracking even if it's surface isn't visible  */
 static const unsigned int borderpx         = 1;  /* border pixel of windows */
+static const unsigned int borderspx        = 0;  /* width of the border that start from outside the windows */
+static const unsigned int borderepx        = 0;  /* width of the border that start from inside the windows */
+static const unsigned int borderspx_offset = 0;  /* offset of the border that start from outside the windows */
+static const unsigned int borderepx_negative_offset = 0; /* offset of the border that start from inside the windows */
 static const float rootcolor[]             = COLOR(0x222222ff);
 static const float bordercolor[]           = COLOR(0x444444ff);
+static const float borderscolor[]          = COLOR(0x444444ff); /* color of the border that start from outside the windows */
+static const float borderecolor[]          = COLOR(0x444444ff); /* color of the border that start from inside the windows */
+static const int border_color_type         = BrdOriginal; /* borders to be colored (focuscolor, urgentcolor) */
+static const int borders_only_floating     = 0;
 static const float focuscolor[]            = COLOR(0x005577ff);
 static const float urgentcolor[]           = COLOR(0xff0000ff);
 /* This conforms to the xdg-protocol. Set the alpha to zero to restore the old behavior */
diff --git a/dwl.c b/dwl.c
index bf763df..303832a 100644
--- a/dwl.c
+++ b/dwl.c
@@ -86,6 +86,7 @@ enum { LyrBg, LyrBottom, LyrTile, LyrFloat, LyrTop, LyrFS, LyrOverlay, LyrBlock,
 enum { NetWMWindowTypeDialog, NetWMWindowTypeSplash, NetWMWindowTypeToolbar,
 	NetWMWindowTypeUtility, NetLast }; /* EWMH atoms */
 #endif
+enum { BrdOriginal, BrdStart, BrdEnd, BrdStartEnd };
 
 typedef union {
 	int i;
@@ -109,6 +110,8 @@ typedef struct {
 	Monitor *mon;
 	struct wlr_scene_tree *scene;
 	struct wlr_scene_rect *border[4]; /* top, bottom, left, right */
+	struct wlr_scene_rect *borders[4]; /* top, bottom, left, right */
+	struct wlr_scene_rect *bordere[4]; /* top, bottom, left, right */
 	struct wlr_scene_tree *scene_surface;
 	struct wl_list link;
 	struct wl_list flink;
@@ -136,6 +139,8 @@ typedef struct {
 	struct wl_listener set_hints;
 #endif
 	unsigned int bw;
+	unsigned int bws;
+	unsigned int bwe;
 	uint32_t tags;
 	int isfloating, isurgent, isfullscreen;
 	uint32_t resize; /* configure serial of a pending resize */
@@ -973,6 +978,8 @@ createnotify(struct wl_listener *listener, void *data)
 	c = xdg_surface->data = ecalloc(1, sizeof(*c));
 	c->surface.xdg = xdg_surface;
 	c->bw = borderpx;
+	c->bws = borders_only_floating ? 0 : borderspx;
+	c->bwe = borders_only_floating ? 0 : borderepx;
 
 	wlr_xdg_toplevel_set_wm_capabilities(xdg_surface->toplevel,
 			WLR_XDG_TOPLEVEL_WM_CAPABILITIES_FULLSCREEN);
@@ -1268,7 +1275,7 @@ focusclient(Client *c, int lift)
 		/* Don't change border color if there is an exclusive focus or we are
 		 * handling a drag operation */
 		if (!exclusive_focus && !seat->drag)
-			client_set_border_color(c, focuscolor);
+			client_set_border_color(c, focuscolor, focuscolor, focuscolor);
 	}
 
 	/* Deactivate old client if focus is changing */
@@ -1285,7 +1292,7 @@ focusclient(Client *c, int lift)
 		/* Don't deactivate old client if the new one wants focus, as this causes issues with winecfg
 		 * and probably other clients */
 		} else if (old_c && !client_is_unmanaged(old_c) && (!c || !client_wants_focus(c))) {
-			client_set_border_color(old_c, bordercolor);
+			client_set_border_color(old_c, bordercolor, borderscolor, borderecolor);
 
 			client_activate_surface(old, 0);
 		}
@@ -1597,6 +1604,12 @@ mapnotify(struct wl_listener *listener, void *data)
 		c->border[i] = wlr_scene_rect_create(c->scene, 0, 0,
 				c->isurgent ? urgentcolor : bordercolor);
 		c->border[i]->node.data = c;
+
+		c->borders[i] = wlr_scene_rect_create(c->scene, 0, 0, borderscolor);
+		c->borders[i]->node.data = c;
+
+		c->bordere[i] = wlr_scene_rect_create(c->scene, 0, 0, borderecolor);
+		c->bordere[i]->node.data = c;
 	}
 
 	/* Initialize client geometry with room for border */
@@ -1618,6 +1631,12 @@ mapnotify(struct wl_listener *listener, void *data)
 	} else {
 		applyrules(c);
 	}
+
+	if (borders_only_floating) {
+		c->bws = c->isfloating ? borderspx : 0;
+		c->bwe = c->isfloating ? borderepx : 0;
+	}
+
 	printstatus();
 
 unset_fullscreen:
@@ -2051,6 +2070,24 @@ resize(Client *c, struct wlr_box geo, int interact)
 	wlr_scene_node_set_position(&c->border[2]->node, 0, c->bw);
 	wlr_scene_node_set_position(&c->border[3]->node, c->geom.width - c->bw, c->bw);
 
+	wlr_scene_rect_set_size(c->borders[0], c->geom.width - 2 * borderspx_offset, c->bws);
+	wlr_scene_rect_set_size(c->borders[1], c->geom.width - 2 * borderspx_offset, c->bws);
+	wlr_scene_rect_set_size(c->borders[2], c->bws, c->geom.height - 2 * c->bws - 2 * borderspx_offset);
+	wlr_scene_rect_set_size(c->borders[3], c->bws, c->geom.height - 2 * c->bws - 2 * borderspx_offset);
+	wlr_scene_node_set_position(&c->borders[0]->node, borderspx_offset, borderspx_offset);
+	wlr_scene_node_set_position(&c->borders[1]->node, borderspx_offset, c->geom.height - c->bws - borderspx_offset);
+	wlr_scene_node_set_position(&c->borders[2]->node, borderspx_offset, c->bws + borderspx_offset);
+	wlr_scene_node_set_position(&c->borders[3]->node, c->geom.width - c->bws - borderspx_offset, c->bws + borderspx_offset);
+
+	wlr_scene_rect_set_size(c->bordere[0], c->geom.width - (c->bw - c->bwe) * 2 + borderepx_negative_offset * 2, c->bwe);
+	wlr_scene_rect_set_size(c->bordere[1], c->geom.width - (c->bw - c->bwe) * 2 + borderepx_negative_offset * 2, c->bwe);
+	wlr_scene_rect_set_size(c->bordere[2], c->bwe, c->geom.height - 2 * c->bw + 2 * borderepx_negative_offset);
+	wlr_scene_rect_set_size(c->bordere[3], c->bwe, c->geom.height - 2 * c->bw + 2 * borderepx_negative_offset);
+	wlr_scene_node_set_position(&c->bordere[0]->node, c->bw - c->bwe - borderepx_negative_offset, c->bw - c->bwe - borderepx_negative_offset);
+	wlr_scene_node_set_position(&c->bordere[1]->node, c->bw - c->bwe - borderepx_negative_offset, c->geom.height - c->bw + borderepx_negative_offset);
+	wlr_scene_node_set_position(&c->bordere[2]->node, c->bw - c->bwe - borderepx_negative_offset, c->bw - borderepx_negative_offset);
+	wlr_scene_node_set_position(&c->bordere[3]->node, c->geom.width - c->bw + borderepx_negative_offset, c->bw - borderepx_negative_offset);
+
 	/* this is a no-op if size hasn't changed */
 	c->resize = client_set_size(c, c->geom.width - 2 * c->bw,
 			c->geom.height - 2 * c->bw);
@@ -2151,6 +2188,12 @@ setfloating(Client *c, int floating)
 	c->isfloating = floating;
 	if (!c->mon)
 		return;
+
+	if (borders_only_floating) {
+		c->bws = c->isfloating ? borderspx : 0;
+		c->bwe = c->isfloating ? borderepx : 0;
+	}
+
 	wlr_scene_node_reparent(&c->scene->node, layers[c->isfullscreen ||
 			(p && p->isfullscreen) ? LyrFS
 			: c->isfloating ? LyrFloat : LyrTile]);
@@ -2165,6 +2208,8 @@ setfullscreen(Client *c, int fullscreen)
 	if (!c->mon)
 		return;
 	c->bw = fullscreen ? 0 : borderpx;
+	c->bws = fullscreen ? 0 : borderspx;
+	c->bwe = fullscreen ? 0 : borderepx;
 	client_set_fullscreen(c, fullscreen);
 	wlr_scene_node_reparent(&c->scene->node, layers[c->isfullscreen
 			? LyrFS : c->isfloating ? LyrFloat : LyrTile]);
@@ -2819,7 +2864,7 @@ urgent(struct wl_listener *listener, void *data)
 	printstatus();
 
 	if (client_surface(c)->mapped)
-		client_set_border_color(c, urgentcolor);
+		client_set_border_color(c, urgentcolor, urgentcolor, urgentcolor);
 }
 
 void
@@ -3023,7 +3068,7 @@ sethints(struct wl_listener *listener, void *data)
 	printstatus();
 
 	if (c->isurgent && surface && surface->mapped)
-		client_set_border_color(c, urgentcolor);
+		client_set_border_color(c, urgentcolor, urgentcolor, urgentcolor);
 }
 
 void
-- 
2.44.1
