commit cf0cdaf45a66c4043071183f86534af3b34a1033
Author: Hai Nguyen <[email protected]>
Date:   Fri Dec 10 22:06:44 2021 -0500

    added keychord patch to dwm

diff --git a/dwm.suckless.org/patches/keychord/3 
b/dwm.suckless.org/patches/keychord/3
new file mode 100644
index 00000000..c94071df
--- /dev/null
+++ b/dwm.suckless.org/patches/keychord/3
@@ -0,0 +1,14 @@
+Keychord
+================
+
+Description
+-----------
+
+
+Download
+--------
+* [dwm-keychord-20211210-a786211.diff](dwm-keychord-20211210-a786211.diff)
+
+Authors
+-------
+* Hai Nguyen - <[email protected]>
diff --git 
a/dwm.suckless.org/patches/keychord/dwm-keychord-20211210-a786211.diff 
b/dwm.suckless.org/patches/keychord/dwm-keychord-20211210-a786211.diff
new file mode 100644
index 00000000..879670f6
--- /dev/null
+++ b/dwm.suckless.org/patches/keychord/dwm-keychord-20211210-a786211.diff
@@ -0,0 +1,217 @@
+From e61a957ff8b7e14219b5fbaab9da794b722e7874 Mon Sep 17 00:00:00 2001
+From: Hai Nguyen <[email protected]>
+Date: Fri, 10 Dec 2021 21:45:00 -0500
+Subject: [PATCH] add Keychord struct, change keypress() and grabkeys() to be
+ able to grab a sequence of keystroke
+
+---
+ config.def.h | 67 ++++++++++++++++++++++++++------------------------
+ dwm.c        | 69 ++++++++++++++++++++++++++++++++++++++++------------
+ 2 files changed, 88 insertions(+), 48 deletions(-)
+
+diff --git a/config.def.h b/config.def.h
+index a2ac963..15a3e05 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -46,11 +46,12 @@ static const Layout layouts[] = {
+ 
+ /* key definitions */
+ #define MODKEY Mod1Mask
+-#define TAGKEYS(KEY,TAG) \
+-      { MODKEY,                       KEY,      view,           {.ui = 1 << 
TAG} }, \
+-      { MODKEY|ControlMask,           KEY,      toggleview,     {.ui = 1 << 
TAG} }, \
+-      { MODKEY|ShiftMask,             KEY,      tag,            {.ui = 1 << 
TAG} }, \
+-      { MODKEY|ControlMask|ShiftMask, KEY,      toggletag,      {.ui = 1 << 
TAG} },
++
++#define TAGKEYS(KEY,TAG)                                                      
                                        \
++      {1, {{MODKEY, KEY}},                                                    
        view,           {.ui = 1 << TAG} },     \
++      {1, {{MODKEY|ControlMask, KEY}},                                        
toggleview,     {.ui = 1 << TAG} }, \
++      {1, {{MODKEY|ShiftMask, KEY}},                                          
tag,            {.ui = 1 << TAG} }, \
++      {1, {{MODKEY|ControlMask|ShiftMask, KEY}},                      
toggletag,      {.ui = 1 << TAG} },
+ 
+ /* helper for spawning shell commands in the pre dwm-5.0 fashion */
+ #define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
+@@ -59,32 +60,34 @@ static const Layout layouts[] = {
+ static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in 
spawn() */
+ static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", 
dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", 
col_gray4, NULL };
+ static const char *termcmd[]  = { "st", NULL };
++static const char *emacs[]  = { "emacs", NULL };
+ 
+-static Key keys[] = {
+-      /* modifier                     key        function        argument */
+-      { MODKEY,                       XK_p,      spawn,          {.v = 
dmenucmd } },
+-      { MODKEY|ShiftMask,             XK_Return, spawn,          {.v = 
termcmd } },
+-      { MODKEY,                       XK_b,      togglebar,      {0} },
+-      { MODKEY,                       XK_j,      focusstack,     {.i = +1 } },
+-      { MODKEY,                       XK_k,      focusstack,     {.i = -1 } },
+-      { MODKEY,                       XK_i,      incnmaster,     {.i = +1 } },
+-      { MODKEY,                       XK_d,      incnmaster,     {.i = -1 } },
+-      { MODKEY,                       XK_h,      setmfact,       {.f = -0.05} 
},
+-      { MODKEY,                       XK_l,      setmfact,       {.f = +0.05} 
},
+-      { MODKEY,                       XK_Return, zoom,           {0} },
+-      { MODKEY,                       XK_Tab,    view,           {0} },
+-      { MODKEY|ShiftMask,             XK_c,      killclient,     {0} },
+-      { MODKEY,                       XK_t,      setlayout,      {.v = 
&layouts[0]} },
+-      { MODKEY,                       XK_f,      setlayout,      {.v = 
&layouts[1]} },
+-      { MODKEY,                       XK_m,      setlayout,      {.v = 
&layouts[2]} },
+-      { MODKEY,                       XK_space,  setlayout,      {0} },
+-      { MODKEY|ShiftMask,             XK_space,  togglefloating, {0} },
+-      { MODKEY,                       XK_0,      view,           {.ui = ~0 } 
},
+-      { MODKEY|ShiftMask,             XK_0,      tag,            {.ui = ~0 } 
},
+-      { MODKEY,                       XK_comma,  focusmon,       {.i = -1 } },
+-      { MODKEY,                       XK_period, focusmon,       {.i = +1 } },
+-      { MODKEY|ShiftMask,             XK_comma,  tagmon,         {.i = -1 } },
+-      { MODKEY|ShiftMask,             XK_period, tagmon,         {.i = +1 } },
++static Keychord keychords[] = {
++      /* Keys        function        argument */
++      {1, {{MODKEY, XK_p}},                                                   
spawn,          {.v = dmenucmd } },
++      {1, {{MODKEY|ShiftMask, XK_Return}},                    spawn,          
{.v = termcmd } },
++      {2, {{MODKEY, XK_e}, {MODKEY, XK_e}},                   spawn,          
{.v = termcmd } },
++      {1, {{MODKEY, XK_b}},                                                   
togglebar,      {0} },
++      {1, {{MODKEY, XK_j}},                                                   
focusstack,     {.i = +1 } },
++      {1, {{MODKEY, XK_k}},                                                   
focusstack,     {.i = -1 } },
++      {1, {{MODKEY, XK_i}},                                                   
incnmaster,     {.i = +1 } },
++      {1, {{MODKEY, XK_d}},                                                   
incnmaster,     {.i = -1 } },
++      {1, {{MODKEY, XK_h}},                                                   
setmfact,       {.f = -0.05} },
++      {1, {{MODKEY, XK_l}},                                                   
setmfact,       {.f = +0.05} },
++      {1, {{MODKEY, XK_Return}},                                              
zoom,           {0} },
++      {1, {{MODKEY, XK_Tab}},                                                 
view,           {0} },
++      {1, {{MODKEY|ShiftMask, XK_c}},                                 
killclient,     {0} },
++      {1, {{MODKEY, XK_t}},                                                   
setlayout,      {.v = &layouts[0]} },
++      {1, {{MODKEY, XK_f}},                                                   
setlayout,      {.v = &layouts[1]} },
++      {1, {{MODKEY, XK_m}},                                                   
setlayout,      {.v = &layouts[2]} },
++      {1, {{MODKEY, XK_space}},                                               
setlayout,      {0} },
++      {1, {{MODKEY|ShiftMask, XK_space}},                             
togglefloating, {0} },
++      {1, {{MODKEY, XK_0}},                                                   
view,           {.ui = ~0 } },
++      {1, {{MODKEY|ShiftMask, XK_0}},                                 tag,    
        {.ui = ~0 } },
++      {1, {{MODKEY, XK_comma}},                                               
focusmon,       {.i = -1 } },
++      {1, {{MODKEY, XK_period}},                                              
focusmon,       {.i = +1 } },
++      {1, {{MODKEY|ShiftMask, XK_comma}},                             tagmon, 
        {.i = -1 } },
++      {1, {{MODKEY|ShiftMask, XK_period}},                    tagmon,         
{.i = +1 } },
+       TAGKEYS(                        XK_1,                      0)
+       TAGKEYS(                        XK_2,                      1)
+       TAGKEYS(                        XK_3,                      2)
+@@ -92,9 +95,9 @@ static Key keys[] = {
+       TAGKEYS(                        XK_5,                      4)
+       TAGKEYS(                        XK_6,                      5)
+       TAGKEYS(                        XK_7,                      6)
+-      TAGKEYS(                        XK_8,                      7)
++       TAGKEYS(                        XK_8,                      7)
+       TAGKEYS(                        XK_9,                      8)
+-      { MODKEY|ShiftMask,             XK_q,      quit,           {0} },
++      {1, {{MODKEY|ShiftMask, XK_q}},                                 quit,   
        {0} },
+ };
+ 
+ /* button definitions */
+diff --git a/dwm.c b/dwm.c
+index 5e4d494..56c4661 100644
+--- a/dwm.c
++++ b/dwm.c
+@@ -102,9 +102,14 @@ struct Client {
+ typedef struct {
+       unsigned int mod;
+       KeySym keysym;
++} Key;
++
++typedef struct {
++      unsigned int n;
++      const Key keys[5];
+       void (*func)(const Arg *);
+       const Arg arg;
+-} Key;
++} Keychord;
+ 
+ typedef struct {
+       const char *symbol;
+@@ -268,6 +273,7 @@ static Display *dpy;
+ static Drw *drw;
+ static Monitor *mons, *selmon;
+ static Window root, wmcheckwin;
++unsigned int currentkey = 0;
+ 
+ /* configuration, allows nested code to access above variables */
+ #include "config.h"
+@@ -951,16 +957,16 @@ grabkeys(void)
+ {
+       updatenumlockmask();
+       {
+-              unsigned int i, j;
++              unsigned int i, k;
+               unsigned int modifiers[] = { 0, LockMask, numlockmask, 
numlockmask|LockMask };
+               KeyCode code;
+ 
+               XUngrabKey(dpy, AnyKey, AnyModifier, root);
+-              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);
++              for (i = 0; i < LENGTH(keychords); i++)
++                      if ((code = XKeysymToKeycode(dpy, 
keychords[i].keys[currentkey].keysym)))
++                              for (k = 0; k < LENGTH(modifiers); k++)
++                                      XGrabKey(dpy, code, 
keychords[i].keys[currentkey].mod | modifiers[k], root,
++                                                       True, GrabModeAsync, 
GrabModeAsync);
+       }
+ }
+ 
+@@ -986,17 +992,48 @@ isuniquegeom(XineramaScreenInfo *unique, size_t n, 
XineramaScreenInfo *info)
+ void
+ keypress(XEvent *e)
+ {
+-      unsigned int i;
++      XEvent event = *e;
++      Keychord *keychord;
++      unsigned int ran = 0;
+       KeySym keysym;
+       XKeyEvent *ev;
+-
+-      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)
+-              && keys[i].func)
+-                      keys[i].func(&(keys[i].arg));
++      Keychord *newoptions;
++      Keychord *oldoptions = (Keychord *)malloc(sizeof(keychords));
++
++      memcpy(oldoptions, keychords, sizeof(keychords));
++      size_t numoption = 0;
++      while(!ran){
++              ev = &event.xkey;
++              keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0);
++              newoptions = (Keychord *)malloc(0);
++              numoption = 0;
++              for (keychord = oldoptions; keychord->n != 0 && currentkey < 5; 
keychord = (Keychord *)((char *)keychord + sizeof(Keychord))){
++                      if(keysym == keychord->keys[currentkey].keysym
++                         && CLEANMASK(keychord->keys[currentkey].mod) == 
CLEANMASK(ev->state)
++                         && keychord->func){
++                              if(keychord->n == currentkey +1){
++                                      keychord->func(&(keychord->arg));
++                                      ran = 1;
++                              }else{
++                                      numoption++;
++                                      newoptions = (Keychord 
*)realloc(newoptions, numoption * sizeof(Keychord));
++                                      memcpy((char *)newoptions + (numoption 
-1) * sizeof(Keychord),keychord, sizeof(Keychord));
++                              }
++                      }
++              }
++              currentkey++;
++              if(numoption == 0)
++                      break;
++              grabkeys();
++              while (running && !XNextEvent(dpy, &event) && !ran)
++                      if(event.type == KeyPress)
++                              break;
++              free(oldoptions);
++              oldoptions = newoptions;
++      }
++      free(newoptions);
++      currentkey = 0;
++      grabkeys();
+ }
+ 
+ void
+-- 
+2.34.1
+
diff --git a/dwm.suckless.org/patches/keychord/index.md 
b/dwm.suckless.org/patches/keychord/index.md
new file mode 100644
index 00000000..cb52e4f6
--- /dev/null
+++ b/dwm.suckless.org/patches/keychord/index.md
@@ -0,0 +1,15 @@
+Keychord
+================
+
+Description
+-----------
+A patch that change the Key struct to Keychord, letting user map a sequence of 
key instead of one singular keystroke.
+
+
+Download
+--------
+* [dwm-keychord-20211210-a786211.diff](dwm-keychord-20211210-a786211.diff)
+
+Authors
+-------
+* Hai Nguyen - <[email protected]>


Reply via email to