From 31d0ceb3f7dea83282e61e556d71d06b7f43d753 Mon Sep 17 00:00:00 2001
From: Gavin M <git@gavinm.us>
Date: Sat, 16 Nov 2024 08:47:02 -0500
Subject: [PATCH] Add cfact to gaps

---
 config.def.h |  3 +++
 dwl.c        | 63 +++++++++++++++++++++++++++++++++++++++++-----------
 2 files changed, 53 insertions(+), 13 deletions(-)

diff --git a/config.def.h b/config.def.h
index b388b4e..a871364 100644
--- a/config.def.h
+++ b/config.def.h
@@ -136,6 +136,9 @@ static const Key keys[] = {
 	{ MODKEY,                    XKB_KEY_d,          incnmaster,     {.i = -1} },
 	{ MODKEY,                    XKB_KEY_h,          setmfact,       {.f = -0.05f} },
 	{ MODKEY,                    XKB_KEY_l,          setmfact,       {.f = +0.05f} },
+	{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_H,          setcfact,       {.f = +0.25f} },
+	{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_L,          setcfact,       {.f = -0.25f} },
+	{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_K,          setcfact,       {.f = 0.0f} },
 	{ MODKEY,                    XKB_KEY_Return,     zoom,           {0} },
 	{ MODKEY,                    XKB_KEY_Tab,        view,           {0} },
 	{ MODKEY,                    XKB_KEY_g,          togglegaps,     {0} },
diff --git a/dwl.c b/dwl.c
index dc851df..b5313c1 100644
--- a/dwl.c
+++ b/dwl.c
@@ -140,6 +140,7 @@ typedef struct {
 	uint32_t tags;
 	int isfloating, isurgent, isfullscreen;
 	uint32_t resize; /* configure serial of a pending resize */
+	float cweight;
 } Client;
 
 typedef struct {
@@ -319,6 +320,7 @@ static void requeststartdrag(struct wl_listener *listener, void *data);
 static void requestmonstate(struct wl_listener *listener, void *data);
 static void resize(Client *c, struct wlr_box geo, int interact);
 static void run(char *startup_cmd);
+static void setcfact(const Arg *arg);
 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);
@@ -1045,6 +1047,7 @@ createnotify(struct wl_listener *listener, void *data)
 	c = xdg_surface->data = ecalloc(1, sizeof(*c));
 	c->surface.xdg = xdg_surface;
 	c->bw = borderpx;
+	c->cweight = 1.0;
 
 	wlr_xdg_toplevel_set_wm_capabilities(xdg_surface->toplevel,
 			WLR_XDG_TOPLEVEL_WM_CAPABILITIES_FULLSCREEN);
@@ -2223,6 +2226,19 @@ run(char *startup_cmd)
 	wl_display_run(dpy);
 }
 
+void
+setcfact(const Arg *arg)
+{
+	Client *sel = focustop(selmon);
+
+	if(!arg || !sel || !selmon->lt[selmon->sellt]->arrange)
+		return;
+	sel->cweight = (float) (arg->f ? sel->cweight + arg->f : 1.0);
+	if (sel->cweight < 0)
+		sel->cweight = 0;
+	arrange(selmon);
+}
+
 void
 setcursor(struct wl_listener *listener, void *data)
 {
@@ -2642,38 +2658,58 @@ tagmon(const Arg *arg)
 void
 tile(Monitor *m)
 {
-	unsigned int h, r, e = m->gaps, mw, my, ty;
+	unsigned int e = m->gaps, mw, my, ty;
 	int i, n = 0;
-	Client *c;
+	float mweight = 0, tweight = 0;
+	Client *c, *sel = NULL;
+
+	wl_list_for_each(c, &fstack, flink) {
+		if (VISIBLEON(c, m) && !c->isfullscreen) {
+			if (!sel)
+				sel = c;
+			if (!c->isfloating)
+				n++;
+		}
+	}
 
-	wl_list_for_each(c, &clients, link)
-		if (VISIBLEON(c, m) && !c->isfloating && !c->isfullscreen)
-			n++;
 	if (n == 0)
 		return;
+
 	if (smartgaps == n)
 		e = 0;
 
 	if (n > m->nmaster)
 		mw = m->nmaster ? (int)roundf((m->w.width + gappx*e) * m->mfact) : 0;
 	else
-		mw = m->w.width;
+		mw = m->w.width - gappx*e;
+
+	i = 0;
+	wl_list_for_each(c, &clients, link){
+		if (!VISIBLEON(c, m) || c->isfloating || c->isfullscreen)
+			continue;
+		if (i < m->nmaster)
+			mweight += c->cweight;
+		else
+			tweight += c->cweight;
+		i++;
+	}
+
 	i = 0;
 	my = ty = gappx*e;
 	wl_list_for_each(c, &clients, link) {
 		if (!VISIBLEON(c, m) || c->isfloating || c->isfullscreen)
 			continue;
 		if (i < m->nmaster) {
-			r = MIN(n, m->nmaster) - i;
-			h = (m->w.height - my - gappx*e - gappx*e * (r - 1)) / r;
 			resize(c, (struct wlr_box){.x = m->w.x + gappx*e, .y = m->w.y + my,
-				.width = mw - 2*gappx*e, .height = h}, 0);
+				.width = mw - gappx*e,
+				.height = (int)((c->cweight / mweight) * (float)(m->w.height - gappx*e)) - gappx*e
+			}, 0);
 			my += c->geom.height + gappx*e;
 		} else {
-			r = n - i;
-			h = (m->w.height - ty - gappx*e - gappx*e * (r - 1)) / r;
-			resize(c, (struct wlr_box){.x = m->w.x + mw, .y = m->w.y + ty,
-				.width = m->w.width - mw - gappx*e, .height = h}, 0);
+			resize(c, (struct wlr_box){.x = m->w.x + mw + gappx*e, .y = m->w.y + ty,
+				.width = m->w.width - mw - 2*gappx*e,
+				.height = (int)((c->cweight / tweight) * (float)(m->w.height - gappx*e)) - gappx*e
+			}, 0);
 			ty += c->geom.height + gappx*e;
 		}
 		i++;
@@ -3068,6 +3104,7 @@ createnotifyx11(struct wl_listener *listener, void *data)
 	c->surface.xwayland = xsurface;
 	c->type = X11;
 	c->bw = client_is_unmanaged(c) ? 0 : borderpx;
+	c->cweight = 1.0;
 
 	/* Listen to the various events it can emit */
 	LISTEN(&xsurface->events.associate, &c->associate, associatex11);
-- 
2.47.0

