On Wed, May 08, 2019 at 10:21:09PM +0200, Philip Linde wrote:
> - 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
> 
> 

Hi,

Patches which you think are useful to others can be uploaded to the wiki
(public repository "sites" on git.suckless.org).

See also: https://suckless.org/hacking/

-- 
Kind regards,
Hiltjo

Reply via email to