- Run "prefix" to enter prefix mode.
- Prefix mode is indicated by a flag in the tag bar.
- While prefix mode is enabled, MODKEY is ignored in all bindings.
- Executing prefix while in prefix mode will send the keysym/mod
combination of its argument to the active window.
- Executing any key-bound command while in prefix mode will exit prefix
mode.
---
config.def.h | 2 ++
dwm.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++---
2 files changed, 50 insertions(+), 3 deletions(-)
diff --git a/config.def.h b/config.def.h
index 1c0b587..b14b678 100644
--- a/config.def.h
+++ b/config.def.h
@@ -94,6 +94,8 @@ static Key keys[] = {
TAGKEYS( XK_8, 7)
TAGKEYS( XK_9, 8)
{ MODKEY|ShiftMask, XK_q, quit, {0} },
+ { ControlMask, XK_t, prefix, {.c = {
ControlMask, XK_t } } },
+ { MODKEY, XK_Escape, noop, {0} },
};
/* button definitions */
diff --git a/dwm.c b/dwm.c
index 4465af1..43714ae 100644
--- a/dwm.c
+++ b/dwm.c
@@ -67,11 +67,17 @@ enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast
}; /* default atoms *
enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle,
ClkClientWin, ClkRootWin, ClkLast }; /* clicks */
+typedef struct {
+ unsigned int mod;
+ KeySym keysym;
+} Combo;
+
typedef union {
int i;
unsigned int ui;
float f;
const void *v;
+ Combo c;
} Arg;
typedef struct {
@@ -233,6 +239,8 @@ static int xerror(Display *dpy, XErrorEvent *ee);
static int xerrordummy(Display *dpy, XErrorEvent *ee);
static int xerrorstart(Display *dpy, XErrorEvent *ee);
static void zoom(const Arg *arg);
+static void prefix(const Arg *arg);
+static void noop(const Arg *arg);
/* variables */
static const char broken[] = "broken";
@@ -243,6 +251,7 @@ static int bh, blw = 0; /* bar geometry */
static int lrpad; /* sum of left and right padding for text */
static int (*xerrorxlib)(Display *, XErrorEvent *);
static unsigned int numlockmask = 0;
+static unsigned int prefixmask = ~0;
static void (*handler[LASTEvent]) (XEvent *) = {
[ButtonPress] = buttonpress,
[ClientMessage] = clientmessage,
@@ -699,6 +708,7 @@ drawbar(Monitor *m)
int boxs = drw->fonts->h / 9;
int boxw = drw->fonts->h / 6 + 2;
unsigned int i, occ = 0, urg = 0;
+ char *prefixmode;
Client *c;
/* draw status first so it can be overdrawn by tags later */
@@ -728,6 +738,9 @@ drawbar(Monitor *m)
drw_setscheme(drw, scheme[SchemeNorm]);
x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0);
+ prefixmode = prefixmask == ~MODKEY ? "⚑" : " ";
+ x = drw_text(drw, x, 0, TEXTW(prefixmode), bh, lrpad / 2, prefixmode,
0);
+
if ((w = m->ww - sw - x) > bh) {
if (m->sel) {
drw_setscheme(drw, scheme[m == selmon ? SchemeSel :
SchemeNorm]);
@@ -958,8 +971,8 @@ grabkeys(void)
for (i = 0; i < LENGTH(keys); i++)
if ((code = XKeysymToKeycode(dpy, keys[i].keysym)))
for (j = 0; j < LENGTH(modifiers); j++)
- XGrabKey(dpy, code, keys[i].mod |
modifiers[j], root,
- True, GrabModeAsync,
GrabModeAsync);
+ XGrabKey(dpy, code, (keys[i].mod &
prefixmask) | modifiers[j],
+ root, True, GrabModeAsync,
GrabModeAsync);
}
}
@@ -988,14 +1001,23 @@ keypress(XEvent *e)
unsigned int i;
KeySym keysym;
XKeyEvent *ev;
+ unsigned int prevmask;
+ prevmask = prefixmask;
ev = &e->xkey;
keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0);
for (i = 0; i < LENGTH(keys); i++)
if (keysym == keys[i].keysym
- && CLEANMASK(keys[i].mod) == CLEANMASK(ev->state)
+ && CLEANMASK(keys[i].mod & prefixmask) == CLEANMASK(ev->state)
&& keys[i].func)
keys[i].func(&(keys[i].arg));
+
+ if (prevmask == prefixmask)
+ prefixmask = ~0;
+ if (prevmask != prefixmask) {
+ drawbar(selmon);
+ grabkeys();
+ }
}
void
@@ -2124,6 +2146,29 @@ zoom(const Arg *arg)
pop(c);
}
+void
+prefix(const Arg *arg)
+{
+ unsigned int keycode;
+ XEvent fwd = {0};
+
+ keycode = XKeysymToKeycode(dpy, arg->c.keysym);
+ if (selmon->sel && prefixmask == ~MODKEY) {
+ fwd.xkey.type = KeyPress;
+ fwd.xkey.display = dpy;
+ fwd.xkey.window = selmon->sel->win;
+ fwd.xkey.state = arg->c.mod;
+ fwd.xkey.time = CurrentTime;
+ fwd.xkey.keycode = keycode;
+ XSendEvent(dpy, selmon->sel->win, False, KeyPressMask, &fwd);
+ } else {
+ prefixmask = ~MODKEY;
+ }
+}
+
+void
+noop(const Arg *arg) { }
+
int
main(int argc, char *argv[])
{
--
2.21.0