commit 5c5b9056c30c7eae7fbbf7af1043b01960e966cd
parent 0652ef9359bfaf8c2b03e77f22d23be415cfd996
Author: Matthew Carlson <matt@mcarlson.xyz>
Date: Mon, 12 Jul 2021 01:27:26 +0000
Merge branch 'dwmc' into dwm
Diffstat:
M | Makefile | | | 2 | +- |
M | config.h | | | 71 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
M | dwm.c | | | 55 | +++++++++++++++++++++++++++++++++++++++++++++++++++++-- |
A | dwmc | | | 40 | ++++++++++++++++++++++++++++++++++++++++ |
4 files changed, 165 insertions(+), 3 deletions(-)
diff --git a/Makefile b/Makefile
@@ -24,7 +24,7 @@ dwm: ${OBJ}
install: all
mkdir -p ${DESTDIR}${PREFIX}/bin
- cp -f dwm ${DESTDIR}${PREFIX}/bin
+ cp -f dwm dwmc ${DESTDIR}${PREFIX}/bin
chmod 755 ${DESTDIR}${PREFIX}/bin/dwm
rm -f dwm *.o
diff --git a/config.h b/config.h
@@ -196,3 +196,74 @@ static Button buttons[] = {
{ ClkTagBar, MODKEY, Button1, tag, {0} },
{ ClkTagBar, MODKEY, Button3, toggletag, {0} },
};
+
+void
+setlayoutex(const Arg *arg)
+{
+ setlayout(&((Arg) { .v = &layouts[arg->i] }));
+}
+
+void
+viewex(const Arg *arg)
+{
+ view(&((Arg) { .ui = 1 << arg->ui }));
+}
+
+void
+viewall(const Arg *arg)
+{
+ view(&((Arg){.ui = ~0}));
+}
+
+void
+toggleviewex(const Arg *arg)
+{
+ toggleview(&((Arg) { .ui = 1 << arg->ui }));
+}
+
+void
+tagex(const Arg *arg)
+{
+ tag(&((Arg) { .ui = 1 << arg->ui }));
+}
+
+void
+toggletagex(const Arg *arg)
+{
+ toggletag(&((Arg) { .ui = 1 << arg->ui }));
+}
+
+void
+tagall(const Arg *arg)
+{
+ tag(&((Arg){.ui = ~0}));
+}
+
+/* signal definitions */
+/* signum must be greater than 0 */
+/* trigger signals using `xsetroot -name "fsignal:<signame> [<type> <value>]"` */
+static Signal signals[] = {
+ /* signum function */
+ { "focusstack", focusstack },
+ { "setmfact", setmfact },
+ { "togglebar", togglebar },
+ { "incnmaster", incnmaster },
+ { "togglefloating", togglefloating },
+ { "focusmon", focusmon },
+ { "tagmon", tagmon },
+ { "zoom", zoom },
+ { "view", view },
+ { "viewall", viewall },
+ { "viewex", viewex },
+ { "toggleview", view },
+ { "toggleviewex", toggleviewex },
+ { "tag", tag },
+ { "tagall", tagall },
+ { "tagex", tagex },
+ { "toggletag", tag },
+ { "toggletagex", toggletagex },
+ { "killclient", killclient },
+ { "quit", quit },
+ { "setlayout", setlayout },
+ { "setlayoutex", setlayoutex },
+};
diff --git a/dwm.c b/dwm.c
@@ -118,6 +118,11 @@ typedef struct {
} Key;
typedef struct {
+ const char * sig;
+ void (*func)(const Arg *);
+} Signal;
+
+typedef struct {
const char *symbol;
void (*arrange)(Monitor *);
} Layout;
@@ -178,6 +183,7 @@ static void arrange(Monitor *m);
static void arrangemon(Monitor *m);
static void attach(Client *c);
static void attachstack(Client *c);
+static int fake_signal(void);
static void buttonpress(XEvent *e);
static void checkotherwm(void);
static void cleanup(void);
@@ -1172,6 +1178,49 @@ keypress(XEvent *e)
keys[i].func(&(keys[i].arg));
}
+int
+fake_signal(void)
+{
+ char fsignal[256];
+ char indicator[9] = "fsignal:";
+ char str_sig[50];
+ char param[16];
+ int i, len_str_sig, n, paramn;
+ size_t len_fsignal, len_indicator = strlen(indicator);
+ Arg arg;
+
+ // Get root name property
+ if (gettextprop(root, XA_WM_NAME, fsignal, sizeof(fsignal))) {
+ len_fsignal = strlen(fsignal);
+
+ // Check if this is indeed a fake signal
+ if (len_indicator > len_fsignal ? 0 : strncmp(indicator, fsignal, len_indicator) == 0) {
+ paramn = sscanf(fsignal+len_indicator, "%s%n%s%n", str_sig, &len_str_sig, param, &n);
+
+ if (paramn == 1) arg = (Arg) {0};
+ else if (paramn > 2) return 1;
+ else if (strncmp(param, "i", n - len_str_sig) == 0)
+ sscanf(fsignal + len_indicator + n, "%i", &(arg.i));
+ else if (strncmp(param, "ui", n - len_str_sig) == 0)
+ sscanf(fsignal + len_indicator + n, "%u", &(arg.ui));
+ else if (strncmp(param, "f", n - len_str_sig) == 0)
+ sscanf(fsignal + len_indicator + n, "%f", &(arg.f));
+ else return 1;
+
+ // Check if a signal was found, and if so handle it
+ for (i = 0; i < LENGTH(signals); i++)
+ if (strncmp(str_sig, signals[i].sig, len_str_sig) == 0 && signals[i].func)
+ signals[i].func(&(arg));
+
+ // A fake signal was sent
+ return 1;
+ }
+ }
+
+ // No fake signal was sent, so proceed with update
+ return 0;
+}
+
void
killclient(const Arg *arg)
{
@@ -1393,8 +1442,10 @@ propertynotify(XEvent *e)
Window trans;
XPropertyEvent *ev = &e->xproperty;
- if ((ev->window == root) && (ev->atom == XA_WM_NAME))
- updatestatus();
+ if ((ev->window == root) && (ev->atom == XA_WM_NAME)) {
+ if (!fake_signal())
+ updatestatus();
+ }
else if (ev->state == PropertyDelete)
return; /* ignore */
else if ((c = wintoclient(ev->window))) {
diff --git a/dwmc b/dwmc
@@ -0,0 +1,40 @@
+#!/usr/bin/env sh
+
+signal() {
+ xsetroot -name "fsignal:$*"
+}
+
+case $# in
+1)
+ case $1 in
+ setlayout | view | viewall | togglebar | togglefloating | zoom | killclient | quit)
+ signal $1
+ ;;
+ *)
+ echo "Unknown command or missing one argument."
+ exit 1
+ ;;
+ esac
+ ;;
+2)
+ case $1 in
+ view)
+ signal $1 ui $2
+ ;;
+ viewex | toggleviewex | tagex | toggletagex | setlayoutex | focusstack | incnmaster | focusmon | tagmon)
+ signal $1 i $2
+ ;;
+ setmfact)
+ signal $1 f $2
+ ;;
+ *)
+ echo "Unknown command or one too many arguments."
+ exit 1
+ ;;
+ esac
+ ;;
+*)
+ echo "Too many arguments."
+ exit 1
+ ;;
+esac