diff --git a/README.md b/README.md index 4bde0530..b39109d1 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,8 @@ Refer to [https://dwm.suckless.org/](https://dwm.suckless.org/) for details on t ### Changelog: +2020-09-29 - Added the on\_empty\_keys patch (ported from InstantOS) + 2020-09-28 - Added the \_IS\_FLOATING patch (embedded in the EWMHTAGS patch) 2020-09-18 - Added the nomodbuttons patch allowing for toggleable mouse button bindings that have no modifiers @@ -426,6 +428,10 @@ Refer to [https://dwm.suckless.org/](https://dwm.suckless.org/) for details on t - this patch ensures that borders have no transparency - note that this patch is only relevant if you are not using the alpha patch + - [on\_empty\_keys](https://github.com/bakkeby/dwm-flexipatch/issues/51) + - port of InstantVM's on_empty_keys functionality allowing keybindings that apply only when a tag/view is empty + - an example use case is being able to launch applications with first hand keys like "f" to launch firefox + - [onlyquitonempty](https://dwm.suckless.org/patches/onlyquitonempty/) - makes it so dwm will only exit via quit() if no windows are open (in order to prevent accidental loss of work) diff --git a/config.def.h b/config.def.h index ff93493c..517b887c 100644 --- a/config.def.h +++ b/config.def.h @@ -733,6 +733,14 @@ static const char *statuscmds[] = { "notify-send Mouse$BUTTON" }; static char *statuscmd[] = { "/bin/sh", "-c", NULL, NULL }; #endif // BAR_STATUSCMD_PATCH | DWMBLOCKS_PATCH +#if ON_EMPTY_KEYS_PATCH +static const char* firefoxcmd[] = {"firefox", NULL}; +static Key on_empty_keys[] = { + /* modifier key function argument */ + { 0, XK_f, spawn, {.v = firefoxcmd } }, +}; +#endif // ON_EMPTY_KEYS_PATCH + static Key keys[] = { /* modifier key function argument */ #if KEYMODES_PATCH diff --git a/dwm.c b/dwm.c index 355d44d6..76fbebc7 100644 --- a/dwm.c +++ b/dwm.c @@ -420,6 +420,9 @@ struct Monitor { unsigned int sellt; unsigned int tagset[2]; int showbar; + #if ON_EMPTY_KEYS_PATCH + int isempty; + #endif // ON_EMPTY_KEYS_PATCH Client *clients; Client *sel; Client *stack; @@ -1813,6 +1816,13 @@ focus(Client *c) } selmon->sel = c; drawbars(); + + #if ON_EMPTY_KEYS_PATCH + if ((selmon->isempty && selmon->sel) || (!selmon->isempty && !selmon->sel)) { + selmon->isempty = !selmon->isempty; + grabkeys(); + } + #endif // ON_EMPTY_KEYS_PATCH } /* there are some broken focus acquiring clients needing extra handling */ @@ -2028,6 +2038,14 @@ grabkeys(void) for (j = 0; j < LENGTH(modifiers); j++) XGrabKey(dpy, code, keys[i].mod | modifiers[j], root, True, GrabModeAsync, GrabModeAsync); + #if ON_EMPTY_KEYS_PATCH + if (!selmon->sel) + for (i = 0; i < LENGTH(on_empty_keys); i++) + if ((code = XKeysymToKeycode(dpy, on_empty_keys[i].keysym))) + for (j = 0; j < LENGTH(modifiers); j++) + XGrabKey(dpy, code, on_empty_keys[i].mod | modifiers[j], root, + True, GrabModeAsync, GrabModeAsync); + #endif // ON_EMPTY_KEYS_PATCH } } @@ -2073,6 +2091,14 @@ keypress(XEvent *e) && CLEANMASK(keys[i].mod) == CLEANMASK(ev->state) && keys[i].func) keys[i].func(&(keys[i].arg)); + #if ON_EMPTY_KEYS_PATCH + if (!selmon->sel) + for (i = 0; i < LENGTH(on_empty_keys); i++) + if (*keysym == on_empty_keys[i].keysym + && CLEANMASK(on_empty_keys[i].mod) == CLEANMASK(ev->state) + && on_empty_keys[i].func) + on_empty_keys[i].func(&(on_empty_keys[i].arg)); + #endif // ON_EMPTY_KEYS_PATCH XFree(keysym); } @@ -2128,13 +2154,13 @@ manage(Window w, XWindowAttributes *wa) c->cfact = 1.0; #endif // CFACTS_PATCH updatetitle(c); - #if CENTER_PATCH - if (c->x == c->mon->wx && c->y == c->mon->wy) - c->iscentered = 1; - #endif // CENTER_PATCH if (XGetTransientForHint(dpy, w, &trans) && (t = wintoclient(trans))) { c->mon = t->mon; c->tags = t->tags; + #if CENTER_PATCH + if (c->x == c->mon->wx && c->y == c->mon->wy) + c->iscentered = 1; + #endif // CENTER_PATCH #if SETBORDERPX_PATCH c->bw = c->mon->borderpx; #else @@ -2151,6 +2177,10 @@ manage(Window w, XWindowAttributes *wa) #endif // CENTER_TRANSIENT_WINDOWS_PATCH | CENTER_TRANSIENT_WINDOWS_BY_PARENT_PATCH } else { c->mon = selmon; + #if CENTER_PATCH + if (c->x == c->mon->wx && c->y == c->mon->wy) + c->iscentered = 1; + #endif // CENTER_PATCH #if SETBORDERPX_PATCH c->bw = c->mon->borderpx; #else diff --git a/patches.def.h b/patches.def.h index 916d9716..13e929ef 100644 --- a/patches.def.h +++ b/patches.def.h @@ -677,6 +677,15 @@ */ #define NO_TRANSPARENT_BORDERS_PATCH 0 +/* Port of InstantVM's on_empty_keys functionality allowing keybindings that apply only when + * a tag is empty. An example use case is being able to launch applications with first hand + * keys like "f" to launch firefox. + * + * https://github.com/instantOS/instantWM/ + * https://github.com/bakkeby/dwm-flexipatch/issues/51 + */ +#define ON_EMPTY_KEYS_PATCH 0 + /* Minor patch that prevents more than one rule being matched for a given client. */ #define ONLY_ONE_RULE_MATCH_PATCH 0