dwm-keychord-6.2.diff - sites - public wiki contents of suckless.org
 (HTM) git clone git://git.suckless.org/sites
 (DIR) Log
 (DIR) Files
 (DIR) Refs
       ---
       dwm-keychord-6.2.diff (9320B)
       ---
            1 From af959703381f2c216624eff7795f59156b05c2a0 Mon Sep 17 00:00:00 2001
            2 From: Hai Nguyen <hhai2105@gmail.com>
            3 Date: Wed, 19 Jan 2022 04:38:20 -0500
            4 Subject: [PATCH] implement keychord using array and pointer instead of heap
            5  allocation
            6 
            7 ---
            8  config.def.h | 63 +++++++++++++++++++++++----------------------
            9  dwm.c        | 72 ++++++++++++++++++++++++++++++++++++++++------------
           10  2 files changed, 88 insertions(+), 47 deletions(-)
           11 
           12 diff --git a/config.def.h b/config.def.h
           13 index a2ac963..7cc8ddd 100644
           14 --- a/config.def.h
           15 +++ b/config.def.h
           16 @@ -46,11 +46,11 @@ static const Layout layouts[] = {
           17  
           18  /* key definitions */
           19  #define MODKEY Mod1Mask
           20 -#define TAGKEYS(KEY,TAG) \
           21 -        { MODKEY,                       KEY,      view,           {.ui = 1 << TAG} }, \
           22 -        { MODKEY|ControlMask,           KEY,      toggleview,     {.ui = 1 << TAG} }, \
           23 -        { MODKEY|ShiftMask,             KEY,      tag,            {.ui = 1 << TAG} }, \
           24 -        { MODKEY|ControlMask|ShiftMask, KEY,      toggletag,      {.ui = 1 << TAG} },
           25 +#define TAGKEYS(KEY,TAG)                                                                                                \
           26 +        &((Keychord){1, {{MODKEY, KEY}},                                                                view,           {.ui = 1 << TAG} }), \
           27 +                &((Keychord){1, {{MODKEY|ControlMask, KEY}},                                        toggleview,     {.ui = 1 << TAG} }), \
           28 +                &((Keychord){1, {{MODKEY|ShiftMask, KEY}},                                                tag,            {.ui = 1 << TAG} }), \
           29 +                &((Keychord){1, {{MODKEY|ControlMask|ShiftMask, KEY}},                        toggletag,      {.ui = 1 << TAG} }),
           30  
           31  /* helper for spawning shell commands in the pre dwm-5.0 fashion */
           32  #define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
           33 @@ -60,31 +60,32 @@ static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn()
           34  static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL };
           35  static const char *termcmd[]  = { "st", NULL };
           36  
           37 -static Key keys[] = {
           38 -        /* modifier                     key        function        argument */
           39 -        { MODKEY,                       XK_p,      spawn,          {.v = dmenucmd } },
           40 -        { MODKEY|ShiftMask,             XK_Return, spawn,          {.v = termcmd } },
           41 -        { MODKEY,                       XK_b,      togglebar,      {0} },
           42 -        { MODKEY,                       XK_j,      focusstack,     {.i = +1 } },
           43 -        { MODKEY,                       XK_k,      focusstack,     {.i = -1 } },
           44 -        { MODKEY,                       XK_i,      incnmaster,     {.i = +1 } },
           45 -        { MODKEY,                       XK_d,      incnmaster,     {.i = -1 } },
           46 -        { MODKEY,                       XK_h,      setmfact,       {.f = -0.05} },
           47 -        { MODKEY,                       XK_l,      setmfact,       {.f = +0.05} },
           48 -        { MODKEY,                       XK_Return, zoom,           {0} },
           49 -        { MODKEY,                       XK_Tab,    view,           {0} },
           50 -        { MODKEY|ShiftMask,             XK_c,      killclient,     {0} },
           51 -        { MODKEY,                       XK_t,      setlayout,      {.v = &layouts[0]} },
           52 -        { MODKEY,                       XK_f,      setlayout,      {.v = &layouts[1]} },
           53 -        { MODKEY,                       XK_m,      setlayout,      {.v = &layouts[2]} },
           54 -        { MODKEY,                       XK_space,  setlayout,      {0} },
           55 -        { MODKEY|ShiftMask,             XK_space,  togglefloating, {0} },
           56 -        { MODKEY,                       XK_0,      view,           {.ui = ~0 } },
           57 -        { MODKEY|ShiftMask,             XK_0,      tag,            {.ui = ~0 } },
           58 -        { MODKEY,                       XK_comma,  focusmon,       {.i = -1 } },
           59 -        { MODKEY,                       XK_period, focusmon,       {.i = +1 } },
           60 -        { MODKEY|ShiftMask,             XK_comma,  tagmon,         {.i = -1 } },
           61 -        { MODKEY|ShiftMask,             XK_period, tagmon,         {.i = +1 } },
           62 +static Keychord *keychords[] = {
           63 +        /* Keys        function        argument */
           64 +        &((Keychord){1, {{MODKEY, XK_p}},                                                        spawn,          {.v = dmenucmd } }),
           65 +        &((Keychord){1, {{MODKEY|ShiftMask, XK_Return}},                        spawn,          {.v = termcmd } }),
           66 +        &((Keychord){2, {{MODKEY, XK_e}, {MODKEY, XK_e}},                        spawn,          {.v = termcmd } }),
           67 +        &((Keychord){1, {{MODKEY, XK_b}},                                                        togglebar,      {0} }),
           68 +        &((Keychord){1, {{MODKEY, XK_j}},                                                        focusstack,     {.i = +1 } }),
           69 +        &((Keychord){1, {{MODKEY, XK_k}},                                                        focusstack,     {.i = -1 } }),
           70 +        &((Keychord){1, {{MODKEY, XK_i}},                                                        incnmaster,     {.i = +1 } }),
           71 +        &((Keychord){1, {{MODKEY, XK_d}},                                                        incnmaster,     {.i = -1 } }),
           72 +        &((Keychord){1, {{MODKEY, XK_h}},                                                        setmfact,       {.f = -0.05} }),
           73 +        &((Keychord){1, {{MODKEY, XK_l}},                                                        setmfact,       {.f = +0.05} }),
           74 +        &((Keychord){1, {{MODKEY, XK_Return}},                                                zoom,           {0} }),
           75 +        &((Keychord){1, {{MODKEY, XK_Tab}},                                                        view,           {0} }),
           76 +        &((Keychord){1, {{MODKEY|ShiftMask, XK_c}},                                        killclient,     {0} }),
           77 +        &((Keychord){1, {{MODKEY, XK_t}},                                                        setlayout,      {.v = &layouts[0]} }),
           78 +        &((Keychord){1, {{MODKEY, XK_f}},                                                        setlayout,      {.v = &layouts[1]} }),
           79 +        &((Keychord){1, {{MODKEY, XK_m}},                                                        setlayout,      {.v = &layouts[2]} }),
           80 +        &((Keychord){1, {{MODKEY, XK_space}},                                                setlayout,      {0} }),
           81 +        &((Keychord){1, {{MODKEY|ShiftMask, XK_space}},                                togglefloating, {0} }),
           82 +        &((Keychord){1, {{MODKEY, XK_0}},                                                        view,           {.ui = ~0 } }),
           83 +        &((Keychord){1, {{MODKEY|ShiftMask, XK_0}},                                        tag,            {.ui = ~0 } }),
           84 +        &((Keychord){1, {{MODKEY, XK_comma}},                                                focusmon,       {.i = -1 } }),
           85 +        &((Keychord){1, {{MODKEY, XK_period}},                                                focusmon,       {.i = +1 } }),
           86 +        &((Keychord){1, {{MODKEY|ShiftMask, XK_comma}},                                tagmon,         {.i = -1 } }),
           87 +        &((Keychord){1, {{MODKEY|ShiftMask, XK_period}},                        tagmon,         {.i = +1 } }),
           88          TAGKEYS(                        XK_1,                      0)
           89          TAGKEYS(                        XK_2,                      1)
           90          TAGKEYS(                        XK_3,                      2)
           91 @@ -94,7 +95,7 @@ static Key keys[] = {
           92          TAGKEYS(                        XK_7,                      6)
           93          TAGKEYS(                        XK_8,                      7)
           94          TAGKEYS(                        XK_9,                      8)
           95 -        { MODKEY|ShiftMask,             XK_q,      quit,           {0} },
           96 +        &((Keychord){1, {{MODKEY|ShiftMask, XK_q}},                                        quit,           {0} }),
           97  };
           98  
           99  /* button definitions */
          100 diff --git a/dwm.c b/dwm.c
          101 index a96f33c..f9777bd 100644
          102 --- a/dwm.c
          103 +++ b/dwm.c
          104 @@ -102,9 +102,14 @@ struct Client {
          105  typedef struct {
          106          unsigned int mod;
          107          KeySym keysym;
          108 +} Key;
          109 +
          110 +typedef struct {
          111 +        unsigned int n;
          112 +        const Key keys[5];
          113          void (*func)(const Arg *);
          114          const Arg arg;
          115 -} Key;
          116 +} Keychord;
          117  
          118  typedef struct {
          119          const char *symbol;
          120 @@ -268,6 +273,7 @@ static Display *dpy;
          121  static Drw *drw;
          122  static Monitor *mons, *selmon;
          123  static Window root, wmcheckwin;
          124 +unsigned int currentkey = 0;
          125  
          126  /* configuration, allows nested code to access above variables */
          127  #include "config.h"
          128 @@ -954,16 +960,17 @@ grabkeys(void)
          129  {
          130          updatenumlockmask();
          131          {
          132 -                unsigned int i, j;
          133 +                unsigned int i, k;
          134                  unsigned int modifiers[] = { 0, LockMask, numlockmask, numlockmask|LockMask };
          135                  KeyCode code;
          136 -
          137                  XUngrabKey(dpy, AnyKey, AnyModifier, root);
          138 -                for (i = 0; i < LENGTH(keys); i++)
          139 -                        if ((code = XKeysymToKeycode(dpy, keys[i].keysym)))
          140 -                                for (j = 0; j < LENGTH(modifiers); j++)
          141 -                                        XGrabKey(dpy, code, keys[i].mod | modifiers[j], root,
          142 -                                                True, GrabModeAsync, GrabModeAsync);
          143 +                for (i = 0; i < LENGTH(keychords); i++)
          144 +                        if ((code = XKeysymToKeycode(dpy, keychords[i]->keys[currentkey].keysym)))
          145 +                                for (k = 0; k < LENGTH(modifiers); k++)
          146 +                                        XGrabKey(dpy, code, keychords[i]->keys[currentkey].mod | modifiers[k], root,
          147 +                                                         True, GrabModeAsync, GrabModeAsync);
          148 +                if(currentkey > 0)
          149 +                        XGrabKey(dpy, XKeysymToKeycode(dpy, XK_Escape), AnyModifier, root, True, GrabModeAsync, GrabModeAsync);
          150          }
          151  }
          152  
          153 @@ -989,17 +996,50 @@ isuniquegeom(XineramaScreenInfo *unique, size_t n, XineramaScreenInfo *info)
          154  void
          155  keypress(XEvent *e)
          156  {
          157 -        unsigned int i;
          158 +        XEvent event = *e;
          159 +        unsigned int ran = 0;
          160          KeySym keysym;
          161          XKeyEvent *ev;
          162  
          163 -        ev = &e->xkey;
          164 -        keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0);
          165 -        for (i = 0; i < LENGTH(keys); i++)
          166 -                if (keysym == keys[i].keysym
          167 -                && CLEANMASK(keys[i].mod) == CLEANMASK(ev->state)
          168 -                && keys[i].func)
          169 -                        keys[i].func(&(keys[i].arg));
          170 +        Keychord *arr1[sizeof(keychords) / sizeof(Keychord*)];
          171 +        Keychord *arr2[sizeof(keychords) / sizeof(Keychord*)];
          172 +        memcpy(arr1, keychords, sizeof(keychords));
          173 +        Keychord **rpointer = arr1;
          174 +        Keychord **wpointer = arr2;
          175 +
          176 +        size_t r = sizeof(keychords)/ sizeof(Keychord*);
          177 +
          178 +        while(1){
          179 +                ev = &event.xkey;
          180 +                keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0);
          181 +                size_t w = 0;
          182 +                for (int i = 0; i < r; i++){
          183 +                        if(keysym == (*(rpointer + i))->keys[currentkey].keysym
          184 +                           && CLEANMASK((*(rpointer + i))->keys[currentkey].mod) == CLEANMASK(ev->state)
          185 +                           && (*(rpointer + i))->func){
          186 +                                if((*(rpointer + i))->n == currentkey +1){
          187 +                                        (*(rpointer + i))->func(&((*(rpointer + i))->arg));
          188 +                                        ran = 1;
          189 +                                }else{
          190 +                                        *(wpointer + w) = *(rpointer + i);
          191 +                                        w++;
          192 +                                }
          193 +                        }
          194 +                }
          195 +                currentkey++;
          196 +                if(w == 0 || ran == 1)
          197 +                        break;
          198 +                grabkeys();
          199 +                while (running && !XNextEvent(dpy, &event) && !ran)
          200 +                        if(event.type == KeyPress)
          201 +                                break;
          202 +                r = w;
          203 +                Keychord **holder = rpointer;
          204 +                rpointer = wpointer;
          205 +                wpointer = holder;
          206 +        }
          207 +        currentkey = 0;
          208 +        grabkeys();
          209  }
          210  
          211  void
          212 -- 
          213 2.34.1
          214