From eac1c79a73ae2cee4870db8282a163bb64d5ea88 Mon Sep 17 00:00:00 2001 From: Bakkeby Date: Mon, 10 Jan 2022 14:03:26 +0100 Subject: [PATCH] Adding window role rule This patch adds a new rule property based on WM_WINDOW_ROLE(STRING) so that one can differentiate between window roles, e.g. Firefox "browser" vs "Preferences". --- config.def.h | 7 ++++--- dwm.c | 7 ++++++- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/config.def.h b/config.def.h index a2ac963..bbb7c85 100644 --- a/config.def.h +++ b/config.def.h @@ -25,10 +25,11 @@ static const Rule rules[] = { /* xprop(1): * WM_CLASS(STRING) = instance, class * WM_NAME(STRING) = title + * WM_WINDOW_ROLE(STRING) = role */ - /* class instance title tags mask isfloating monitor */ - { "Gimp", NULL, NULL, 0, 1, -1 }, - { "Firefox", NULL, NULL, 1 << 8, 0, -1 }, + /* class role instance title tags mask isfloating monitor */ + { "Gimp", NULL, NULL, NULL, 0, 1, -1 }, + { "Firefox", NULL, NULL, NULL, 1 << 8, 0, -1 }, }; /* layout(s) */ diff --git a/dwm.c b/dwm.c index a96f33c..ae66867 100644 --- a/dwm.c +++ b/dwm.c @@ -63,7 +63,7 @@ enum { SchemeNorm, SchemeSel }; /* color schemes */ enum { NetSupported, NetWMName, NetWMState, NetWMCheck, NetWMFullscreen, NetActiveWindow, NetWMWindowType, NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */ -enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */ +enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMWindowRole, WMLast }; /* default atoms */ enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, ClkRootWin, ClkLast }; /* clicks */ @@ -134,6 +134,7 @@ struct Monitor { typedef struct { const char *class; + const char *role; const char *instance; const char *title; unsigned int tags; @@ -280,6 +281,7 @@ void applyrules(Client *c) { const char *class, *instance; + char role[64]; unsigned int i; const Rule *r; Monitor *m; @@ -291,11 +293,13 @@ applyrules(Client *c) XGetClassHint(dpy, c->win, &ch); class = ch.res_class ? ch.res_class : broken; instance = ch.res_name ? ch.res_name : broken; + gettextprop(c->win, wmatom[WMWindowRole], role, sizeof(role)); for (i = 0; i < LENGTH(rules); i++) { r = &rules[i]; if ((!r->title || strstr(c->name, r->title)) && (!r->class || strstr(class, r->class)) + && (!r->role || strstr(role, r->role)) && (!r->instance || strstr(instance, r->instance))) { c->isfloating = r->isfloating; @@ -1557,6 +1561,7 @@ setup(void) wmatom[WMDelete] = XInternAtom(dpy, "WM_DELETE_WINDOW", False); wmatom[WMState] = XInternAtom(dpy, "WM_STATE", False); wmatom[WMTakeFocus] = XInternAtom(dpy, "WM_TAKE_FOCUS", False); + wmatom[WMWindowRole] = XInternAtom(dpy, "WM_WINDOW_ROLE", False); netatom[NetActiveWindow] = XInternAtom(dpy, "_NET_ACTIVE_WINDOW", False); netatom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False); netatom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False); -- 2.19.1