mirror of
				https://codeberg.org/dwl/dwl-patches.git
				synced 2025-11-04 05:54:20 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			156 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			156 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
From 3c78308f0d74ac6ef112804333f82c098e33bb40 Mon Sep 17 00:00:00 2001
 | 
						|
From: Nikita Ivanov <nikita.vyach.ivanov@gmail.com>
 | 
						|
Date: Fri, 21 Mar 2025 22:20:54 +0100
 | 
						|
Subject: [PATCH] setrule: add/change rules at runtime
 | 
						|
 | 
						|
---
 | 
						|
 config.def.h |  4 ++++
 | 
						|
 dwl.c        | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++-
 | 
						|
 2 files changed, 70 insertions(+), 1 deletion(-)
 | 
						|
 | 
						|
diff --git a/config.def.h b/config.def.h
 | 
						|
index 22d2171..5b05e52 100644
 | 
						|
--- a/config.def.h
 | 
						|
+++ b/config.def.h
 | 
						|
@@ -20,6 +20,9 @@ static const float fullscreen_bg[]         = {0.1f, 0.1f, 0.1f, 1.0f}; /* You ca
 | 
						|
 /* logging */
 | 
						|
 static int log_level = WLR_ERROR;
 | 
						|
 
 | 
						|
+/* Max amount of dynamically added rules */
 | 
						|
+#define RULES_MAX 100
 | 
						|
+
 | 
						|
 /* NOTE: ALWAYS keep a rule declared even if you don't use rules (e.g leave at least one example) */
 | 
						|
 static const Rule rules[] = {
 | 
						|
 	/* app_id             title       tags mask     isfloating   monitor */
 | 
						|
@@ -142,6 +145,7 @@ static const Key keys[] = {
 | 
						|
 	{ MODKEY,                    XKB_KEY_space,      setlayout,      {0} },
 | 
						|
 	{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_space,      togglefloating, {0} },
 | 
						|
 	{ MODKEY,                    XKB_KEY_e,         togglefullscreen, {0} },
 | 
						|
+	{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_R,          setruleisfloating,{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} },
 | 
						|
diff --git a/dwl.c b/dwl.c
 | 
						|
index def2562..8beac1f 100644
 | 
						|
--- a/dwl.c
 | 
						|
+++ b/dwl.c
 | 
						|
@@ -290,6 +290,7 @@ static void focusmon(const Arg *arg);
 | 
						|
 static void focusstack(const Arg *arg);
 | 
						|
 static Client *focustop(Monitor *m);
 | 
						|
 static void fullscreennotify(struct wl_listener *listener, void *data);
 | 
						|
+static Rule *getrule(Client *c);
 | 
						|
 static void gpureset(struct wl_listener *listener, void *data);
 | 
						|
 static void handlesig(int signo);
 | 
						|
 static void incnmaster(const Arg *arg);
 | 
						|
@@ -331,6 +332,7 @@ static void setlayout(const Arg *arg);
 | 
						|
 static void setmfact(const Arg *arg);
 | 
						|
 static void setmon(Client *c, Monitor *m, uint32_t newtags);
 | 
						|
 static void setpsel(struct wl_listener *listener, void *data);
 | 
						|
+static void setruleisfloating(const Arg *arg);
 | 
						|
 static void setsel(struct wl_listener *listener, void *data);
 | 
						|
 static void setup(void);
 | 
						|
 static void spawn(const Arg *arg);
 | 
						|
@@ -413,6 +415,9 @@ static struct wlr_box sgeom;
 | 
						|
 static struct wl_list mons;
 | 
						|
 static Monitor *selmon;
 | 
						|
 
 | 
						|
+static Rule *drules;
 | 
						|
+static size_t druleslen;
 | 
						|
+
 | 
						|
 #ifdef XWAYLAND
 | 
						|
 static void activatex11(struct wl_listener *listener, void *data);
 | 
						|
 static void associatex11(struct wl_listener *listener, void *data);
 | 
						|
@@ -466,7 +471,7 @@ applyrules(Client *c)
 | 
						|
 	if (!(title = client_get_title(c)))
 | 
						|
 		title = broken;
 | 
						|
 
 | 
						|
-	for (r = rules; r < END(rules); r++) {
 | 
						|
+	for (r = drules; r < drules + druleslen; r++) {
 | 
						|
 		if ((!r->title || strstr(title, r->title))
 | 
						|
 				&& (!r->id || strstr(appid, r->id))) {
 | 
						|
 			c->isfloating = r->isfloating;
 | 
						|
@@ -1472,6 +1477,53 @@ fullscreennotify(struct wl_listener *listener, void *data)
 | 
						|
 	setfullscreen(c, client_wants_fullscreen(c));
 | 
						|
 }
 | 
						|
 
 | 
						|
+Rule *
 | 
						|
+getrule(Client *c)
 | 
						|
+{
 | 
						|
+	Rule *r;
 | 
						|
+	const Rule *e;
 | 
						|
+	const char *appid, *title;
 | 
						|
+
 | 
						|
+	if (!c)
 | 
						|
+		return NULL;
 | 
						|
+	
 | 
						|
+	if (!(appid = client_get_appid(c)))
 | 
						|
+		appid = broken;
 | 
						|
+	if (!(title = client_get_title(c)))
 | 
						|
+		title = broken;
 | 
						|
+
 | 
						|
+	for (r = drules + druleslen - 1; r >= drules; r--)
 | 
						|
+		if ((!r->title || strstr(title, r->title))
 | 
						|
+				&& (!r->id || strstr(appid, r->id)))
 | 
						|
+			goto found;
 | 
						|
+
 | 
						|
+	if (druleslen >= LENGTH(rules) + RULES_MAX)
 | 
						|
+		return NULL; /* No free slots left */
 | 
						|
+
 | 
						|
+	r = drules + druleslen++;
 | 
						|
+
 | 
						|
+	/* Use [NULL,NULL] as the default rule if exists */
 | 
						|
+	for (e = rules; e < END(rules); e++)
 | 
						|
+		if (!e->title && !e->id) {
 | 
						|
+			*r = *e;
 | 
						|
+			break;
 | 
						|
+		}
 | 
						|
+
 | 
						|
+	/* No default rule found, set reasoble defaults */
 | 
						|
+	if (e >= END(rules)) {
 | 
						|
+		r->monitor = -1;
 | 
						|
+	}
 | 
						|
+
 | 
						|
+	/* Only set title if appid is unset */
 | 
						|
+	if (appid == broken)
 | 
						|
+		r->title = strdup(title);
 | 
						|
+	else
 | 
						|
+		r->id = strdup(appid);
 | 
						|
+
 | 
						|
+found:
 | 
						|
+	return r;
 | 
						|
+}
 | 
						|
+
 | 
						|
 void
 | 
						|
 gpureset(struct wl_listener *listener, void *data)
 | 
						|
 {
 | 
						|
@@ -2417,6 +2469,15 @@ setpsel(struct wl_listener *listener, void *data)
 | 
						|
 	wlr_seat_set_primary_selection(seat, event->source, event->serial);
 | 
						|
 }
 | 
						|
 
 | 
						|
+void
 | 
						|
+setruleisfloating(const Arg *arg)
 | 
						|
+{
 | 
						|
+	Rule *r = getrule(focustop(selmon));
 | 
						|
+	if (!r)
 | 
						|
+		return;
 | 
						|
+	r->isfloating = !r->isfloating;
 | 
						|
+}
 | 
						|
+
 | 
						|
 void
 | 
						|
 setsel(struct wl_listener *listener, void *data)
 | 
						|
 {
 | 
						|
@@ -2645,6 +2706,10 @@ setup(void)
 | 
						|
 		fprintf(stderr, "failed to setup XWayland X server, continuing without it\n");
 | 
						|
 	}
 | 
						|
 #endif
 | 
						|
+
 | 
						|
+	drules = ecalloc(LENGTH(rules) + RULES_MAX, sizeof(Rule));
 | 
						|
+	memcpy(drules, rules, sizeof(rules));
 | 
						|
+	druleslen = LENGTH(rules);
 | 
						|
 }
 | 
						|
 
 | 
						|
 void
 | 
						|
-- 
 | 
						|
2.49.0
 | 
						|
 |