diff --git a/patches/chainkeys/README.md b/patches/chainkeys/README.md index fa6d185..fc6ec2b 100644 --- a/patches/chainkeys/README.md +++ b/patches/chainkeys/README.md @@ -7,9 +7,18 @@ Mod+chain is pressed. A subsequent keypress will be matched against bindings for that chain key. If it is configured the action will be triggered, otherwise the keypress will be ignored. +To use chainkeys, append the key after the argument in the keybindings. Example usage: +```c + { MODKEY, XKB_KEY_d, incnmaster, {.i = -1} }, + { MODKEY, XKB_KEY_s, setmfact, {.f = -0.05f}, XKB_KEY_h }, + { MODKEY, XKB_KEY_s, setmfact, {.f = +0.05f}, XKB_KEY_l }, +``` +Here, `MODKEY+i` triggers incnmaster to decrease nmaster, while `MODKEY+s` triggers a chain. After triggering the chain, pressing `h` or `l` changes the monitor's mfact and resets the chain. + ### Download -- [git branch](https://codeberg.org/bencc/dwl/src/branch/chainkeys) -- [2024-05-20](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/chainkeys/chainkeys.patch) +- [chainkeys.patch](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/chainkeys/chainkeys.patch) Latest version, applies to main branch, tested on commit dwl/dwl@e2038450f2 +- [chainkeys_2024-05-20.patch](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/chainkeys/chainkeys_2024-05-20.patch) Legacy version from 2024-05-20 ### Authors +- [atourist](https://codeberg.org/atourist) - [Ben Collerson](https://codeberg.org/bencc) diff --git a/patches/chainkeys/chainkeys.patch b/patches/chainkeys/chainkeys.patch index a0daefd..d86f782 100644 --- a/patches/chainkeys/chainkeys.patch +++ b/patches/chainkeys/chainkeys.patch @@ -1,157 +1,74 @@ -From 226e204ec7fb6d6840a984ef8e8ec1d2514e985f Mon Sep 17 00:00:00 2001 -From: Ben Collerson -Date: Tue, 2 Jan 2024 10:33:59 +1000 -Subject: [PATCH] chainkeys - ---- - config.def.h | 62 ++++++++++++++++++++++++++-------------------------- - dwl.c | 23 ++++++++++++++++++- - 2 files changed, 53 insertions(+), 32 deletions(-) - -diff --git a/config.def.h b/config.def.h -index 8f498d2f..1c182547 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -105,10 +105,10 @@ static const enum libinput_config_tap_button_map button_map = LIBINPUT_CONFIG_TA - #define MODKEY WLR_MODIFIER_ALT +diff --git a/Makefile b/Makefile +index 8304245..836cb87 100644 +--- a/Makefile ++++ b/Makefile +@@ -9,7 +9,7 @@ DWLCPPFLAGS = -I. -DWLR_USE_UNSTABLE -D_POSIX_C_SOURCE=200809L \ + DWLDEVCFLAGS = -g -Wpedantic -Wall -Wextra -Wdeclaration-after-statement \ + -Wno-unused-parameter -Wshadow -Wunused-macros -Werror=strict-prototypes \ + -Werror=implicit -Werror=return-type -Werror=incompatible-pointer-types \ +- -Wfloat-conversion ++ -Wfloat-conversion -Wno-missing-field-initializers - #define TAGKEYS(KEY,SKEY,TAG) \ -- { MODKEY, KEY, view, {.ui = 1 << TAG} }, \ -- { MODKEY|WLR_MODIFIER_CTRL, KEY, toggleview, {.ui = 1 << TAG} }, \ -- { MODKEY|WLR_MODIFIER_SHIFT, SKEY, tag, {.ui = 1 << TAG} }, \ -- { MODKEY|WLR_MODIFIER_CTRL|WLR_MODIFIER_SHIFT,SKEY,toggletag, {.ui = 1 << TAG} } -+ { MODKEY, -1, KEY, view, {.ui = 1 << TAG} }, \ -+ { MODKEY|WLR_MODIFIER_CTRL, -1, KEY, toggleview, {.ui = 1 << TAG} }, \ -+ { MODKEY|WLR_MODIFIER_SHIFT, -1, SKEY, tag, {.ui = 1 << TAG} }, \ -+ { MODKEY|WLR_MODIFIER_CTRL|WLR_MODIFIER_SHIFT,-1,SKEY,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 } } -@@ -119,30 +119,30 @@ static const char *menucmd[] = { "wmenu-run", NULL }; - - static const Key keys[] = { - /* Note that Shift changes certain key codes: c -> C, 2 -> at, etc. */ -- /* modifier key function argument */ -- { MODKEY, XKB_KEY_p, spawn, {.v = menucmd} }, -- { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Return, spawn, {.v = termcmd} }, -- { MODKEY, XKB_KEY_j, focusstack, {.i = +1} }, -- { MODKEY, XKB_KEY_k, focusstack, {.i = -1} }, -- { MODKEY, XKB_KEY_i, incnmaster, {.i = +1} }, -- { MODKEY, XKB_KEY_d, incnmaster, {.i = -1} }, -- { MODKEY, XKB_KEY_h, setmfact, {.f = -0.05f} }, -- { MODKEY, XKB_KEY_l, setmfact, {.f = +0.05f} }, -- { MODKEY, XKB_KEY_Return, zoom, {0} }, -- { MODKEY, XKB_KEY_Tab, view, {0} }, -- { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_C, killclient, {0} }, -- { MODKEY, XKB_KEY_t, setlayout, {.v = &layouts[0]} }, -- { MODKEY, XKB_KEY_f, setlayout, {.v = &layouts[1]} }, -- { MODKEY, XKB_KEY_m, setlayout, {.v = &layouts[2]} }, -- { MODKEY, XKB_KEY_space, setlayout, {0} }, -- { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_space, togglefloating, {0} }, -- { MODKEY, XKB_KEY_e, togglefullscreen, {0} }, -- { MODKEY, XKB_KEY_0, view, {.ui = ~0} }, -- { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_parenright, tag, {.ui = ~0} }, -- { MODKEY, XKB_KEY_comma, focusmon, {.i = WLR_DIRECTION_LEFT} }, -- { MODKEY, XKB_KEY_period, focusmon, {.i = WLR_DIRECTION_RIGHT} }, -- { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_less, tagmon, {.i = WLR_DIRECTION_LEFT} }, -- { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_greater, tagmon, {.i = WLR_DIRECTION_RIGHT} }, -+ /* modifier chain, key function argument */ -+ { MODKEY, -1, XKB_KEY_p, spawn, {.v = menucmd} }, -+ { MODKEY|WLR_MODIFIER_SHIFT, -1, XKB_KEY_Return, spawn, {.v = termcmd} }, -+ { MODKEY, -1, XKB_KEY_j, focusstack, {.i = +1} }, -+ { MODKEY, -1, XKB_KEY_k, focusstack, {.i = -1} }, -+ { MODKEY, -1, XKB_KEY_i, incnmaster, {.i = +1} }, -+ { MODKEY, -1, XKB_KEY_d, incnmaster, {.i = -1} }, -+ { MODKEY, -1, XKB_KEY_h, setmfact, {.f = -0.05f} }, -+ { MODKEY, -1, XKB_KEY_l, setmfact, {.f = +0.05f} }, -+ { MODKEY, -1, XKB_KEY_Return, zoom, {0} }, -+ { MODKEY, -1, XKB_KEY_Tab, view, {0} }, -+ { MODKEY|WLR_MODIFIER_SHIFT, -1, XKB_KEY_C, killclient, {0} }, -+ { MODKEY, -1, XKB_KEY_t, setlayout, {.v = &layouts[0]} }, -+ { MODKEY, -1, XKB_KEY_f, setlayout, {.v = &layouts[1]} }, -+ { MODKEY, -1, XKB_KEY_m, setlayout, {.v = &layouts[2]} }, -+ { MODKEY, -1, XKB_KEY_space, setlayout, {0} }, -+ { MODKEY|WLR_MODIFIER_SHIFT, -1, XKB_KEY_space, togglefloating, {0} }, -+ { MODKEY, -1, XKB_KEY_e, togglefullscreen, {0} }, -+ { MODKEY, -1, XKB_KEY_0, view, {.ui = ~0} }, -+ { MODKEY|WLR_MODIFIER_SHIFT, -1, XKB_KEY_parenright, tag, {.ui = ~0} }, -+ { MODKEY, -1, XKB_KEY_comma, focusmon, {.i = WLR_DIRECTION_LEFT} }, -+ { MODKEY, -1, XKB_KEY_period, focusmon, {.i = WLR_DIRECTION_RIGHT} }, -+ { MODKEY|WLR_MODIFIER_SHIFT, -1, XKB_KEY_less, tagmon, {.i = WLR_DIRECTION_LEFT} }, -+ { MODKEY|WLR_MODIFIER_SHIFT, -1, XKB_KEY_greater, tagmon, {.i = WLR_DIRECTION_RIGHT} }, - TAGKEYS( XKB_KEY_1, XKB_KEY_exclam, 0), - TAGKEYS( XKB_KEY_2, XKB_KEY_at, 1), - TAGKEYS( XKB_KEY_3, XKB_KEY_numbersign, 2), -@@ -152,14 +152,14 @@ static const Key keys[] = { - TAGKEYS( XKB_KEY_7, XKB_KEY_ampersand, 6), - TAGKEYS( XKB_KEY_8, XKB_KEY_asterisk, 7), - TAGKEYS( XKB_KEY_9, XKB_KEY_parenleft, 8), -- { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Q, quit, {0} }, -+ { MODKEY|WLR_MODIFIER_SHIFT, -1, XKB_KEY_Q, quit, {0} }, - - /* Ctrl-Alt-Backspace and Ctrl-Alt-Fx used to be handled by X server */ -- { WLR_MODIFIER_CTRL|WLR_MODIFIER_ALT,XKB_KEY_Terminate_Server, quit, {0} }, -+ { WLR_MODIFIER_CTRL|WLR_MODIFIER_ALT,-1,XKB_KEY_Terminate_Server, quit, {0} }, - /* Ctrl-Alt-Fx is used to switch to another VT, if you don't know what a VT is - * do not remove them. - */ --#define CHVT(n) { WLR_MODIFIER_CTRL|WLR_MODIFIER_ALT,XKB_KEY_XF86Switch_VT_##n, chvt, {.ui = (n)} } -+#define CHVT(n) { WLR_MODIFIER_CTRL|WLR_MODIFIER_ALT,-1,XKB_KEY_XF86Switch_VT_##n, chvt, {.ui = (n)} } - CHVT(1), CHVT(2), CHVT(3), CHVT(4), CHVT(5), CHVT(6), - CHVT(7), CHVT(8), CHVT(9), CHVT(10), CHVT(11), CHVT(12), - }; + # CFLAGS / LDFLAGS + PKGS = wayland-server xkbcommon libinput $(XLIBS) diff --git a/dwl.c b/dwl.c -index bf763dfc..05e667f8 100644 +index 216deb5..af011ea 100644 --- a/dwl.c +++ b/dwl.c -@@ -143,6 +143,7 @@ typedef struct { - - typedef struct { - uint32_t mod; -+ int chain; +@@ -166,6 +166,7 @@ typedef struct { xkb_keysym_t keysym; void (*func)(const Arg *); const Arg arg; -@@ -353,6 +354,7 @@ static const char broken[] = "broken"; ++ xkb_keysym_t chain; + } Key; + + typedef struct { +@@ -378,6 +379,7 @@ static void zoom(const Arg *arg); + /* variables */ static pid_t child_pid = -1; static int locked; - static void *exclusive_focus; -+static int chainkey = -1; ++static xkb_keysym_t chainkey = 0; + static Client *focused_client; static struct wl_display *dpy; - static struct wlr_backend *backend; - static struct wlr_scene *scene; -@@ -1438,11 +1440,30 @@ keybinding(uint32_t mods, xkb_keysym_t sym) + static struct wl_event_loop *event_loop; +@@ -1735,9 +1737,21 @@ keybinding(uint32_t mods, xkb_keysym_t sym) + * processing. + */ const Key *k; ++ if (chainkey) { ++ for (k = keys; k < END(keys); k++) { ++ if (chainkey == k->keysym && sym == k->chain) { ++ chainkey = 0; ++ return k; ++ } ++ } ++ chainkey = 0; ++ return NULL; ++ } for (k = keys; k < END(keys); k++) { - if (CLEANMASK(mods) == CLEANMASK(k->mod) -- && sym == k->keysym && k->func) { -+ && sym == k->keysym -+ && chainkey == -1 -+ && k->chain == -1 -+ && k->func) { - k->func(&k->arg); - return 1; - } -+ else if (sym == k->keysym -+ && chainkey != -1 -+ && k->chain == chainkey -+ && k->func) { -+ k->func(&k->arg); -+ chainkey = -1; -+ return 1; -+ } -+ else if (CLEANMASK(mods) == CLEANMASK(k->mod) -+ && k->chain == (int)sym -+ && chainkey == -1 -+ && k->func) { -+ chainkey = sym; -+ return 1; -+ } +- if (CLEANMASK(mods) == CLEANMASK(k->mod) && sym == k->keysym && k->func) ++ if (CLEANMASK(mods) == CLEANMASK(k->mod) && sym == k->keysym && k->func) { ++ if (k->chain) chainkey = k->keysym; + return k; ++ } } -+ chainkey = -1; - return 0; + return NULL; } - --- -2.43.0 - +@@ -1771,7 +1785,7 @@ keypress(struct wl_listener *listener, void *data) + const Key *key = keybinding(group->mods, group->keysyms[i]); + if (key) { + consumed[event->keycode] = 1; +- key->func(&key->arg); ++ if (!chainkey) key->func(&key->arg); + handled = 1; + break; + } +@@ -1827,7 +1841,7 @@ keyrepeat(void *data) + for (int i = 0; i < 2; i++) { + const Key *key = keybinding(group->mods, group->keysyms[i]); + if (key) { +- key->func(&key->arg); ++ if (!chainkey) key->func(&key->arg); + break; + } + } diff --git a/patches/chainkeys/chainkeys_2024-05-20.patch b/patches/chainkeys/chainkeys_2024-05-20.patch new file mode 100644 index 0000000..a0daefd --- /dev/null +++ b/patches/chainkeys/chainkeys_2024-05-20.patch @@ -0,0 +1,157 @@ +From 226e204ec7fb6d6840a984ef8e8ec1d2514e985f Mon Sep 17 00:00:00 2001 +From: Ben Collerson +Date: Tue, 2 Jan 2024 10:33:59 +1000 +Subject: [PATCH] chainkeys + +--- + config.def.h | 62 ++++++++++++++++++++++++++-------------------------- + dwl.c | 23 ++++++++++++++++++- + 2 files changed, 53 insertions(+), 32 deletions(-) + +diff --git a/config.def.h b/config.def.h +index 8f498d2f..1c182547 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -105,10 +105,10 @@ static const enum libinput_config_tap_button_map button_map = LIBINPUT_CONFIG_TA + #define MODKEY WLR_MODIFIER_ALT + + #define TAGKEYS(KEY,SKEY,TAG) \ +- { MODKEY, KEY, view, {.ui = 1 << TAG} }, \ +- { MODKEY|WLR_MODIFIER_CTRL, KEY, toggleview, {.ui = 1 << TAG} }, \ +- { MODKEY|WLR_MODIFIER_SHIFT, SKEY, tag, {.ui = 1 << TAG} }, \ +- { MODKEY|WLR_MODIFIER_CTRL|WLR_MODIFIER_SHIFT,SKEY,toggletag, {.ui = 1 << TAG} } ++ { MODKEY, -1, KEY, view, {.ui = 1 << TAG} }, \ ++ { MODKEY|WLR_MODIFIER_CTRL, -1, KEY, toggleview, {.ui = 1 << TAG} }, \ ++ { MODKEY|WLR_MODIFIER_SHIFT, -1, SKEY, tag, {.ui = 1 << TAG} }, \ ++ { MODKEY|WLR_MODIFIER_CTRL|WLR_MODIFIER_SHIFT,-1,SKEY,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 } } +@@ -119,30 +119,30 @@ static const char *menucmd[] = { "wmenu-run", NULL }; + + static const Key keys[] = { + /* Note that Shift changes certain key codes: c -> C, 2 -> at, etc. */ +- /* modifier key function argument */ +- { MODKEY, XKB_KEY_p, spawn, {.v = menucmd} }, +- { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Return, spawn, {.v = termcmd} }, +- { MODKEY, XKB_KEY_j, focusstack, {.i = +1} }, +- { MODKEY, XKB_KEY_k, focusstack, {.i = -1} }, +- { MODKEY, XKB_KEY_i, incnmaster, {.i = +1} }, +- { MODKEY, XKB_KEY_d, incnmaster, {.i = -1} }, +- { MODKEY, XKB_KEY_h, setmfact, {.f = -0.05f} }, +- { MODKEY, XKB_KEY_l, setmfact, {.f = +0.05f} }, +- { MODKEY, XKB_KEY_Return, zoom, {0} }, +- { MODKEY, XKB_KEY_Tab, view, {0} }, +- { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_C, killclient, {0} }, +- { MODKEY, XKB_KEY_t, setlayout, {.v = &layouts[0]} }, +- { MODKEY, XKB_KEY_f, setlayout, {.v = &layouts[1]} }, +- { MODKEY, XKB_KEY_m, setlayout, {.v = &layouts[2]} }, +- { MODKEY, XKB_KEY_space, setlayout, {0} }, +- { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_space, togglefloating, {0} }, +- { MODKEY, XKB_KEY_e, togglefullscreen, {0} }, +- { MODKEY, XKB_KEY_0, view, {.ui = ~0} }, +- { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_parenright, tag, {.ui = ~0} }, +- { MODKEY, XKB_KEY_comma, focusmon, {.i = WLR_DIRECTION_LEFT} }, +- { MODKEY, XKB_KEY_period, focusmon, {.i = WLR_DIRECTION_RIGHT} }, +- { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_less, tagmon, {.i = WLR_DIRECTION_LEFT} }, +- { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_greater, tagmon, {.i = WLR_DIRECTION_RIGHT} }, ++ /* modifier chain, key function argument */ ++ { MODKEY, -1, XKB_KEY_p, spawn, {.v = menucmd} }, ++ { MODKEY|WLR_MODIFIER_SHIFT, -1, XKB_KEY_Return, spawn, {.v = termcmd} }, ++ { MODKEY, -1, XKB_KEY_j, focusstack, {.i = +1} }, ++ { MODKEY, -1, XKB_KEY_k, focusstack, {.i = -1} }, ++ { MODKEY, -1, XKB_KEY_i, incnmaster, {.i = +1} }, ++ { MODKEY, -1, XKB_KEY_d, incnmaster, {.i = -1} }, ++ { MODKEY, -1, XKB_KEY_h, setmfact, {.f = -0.05f} }, ++ { MODKEY, -1, XKB_KEY_l, setmfact, {.f = +0.05f} }, ++ { MODKEY, -1, XKB_KEY_Return, zoom, {0} }, ++ { MODKEY, -1, XKB_KEY_Tab, view, {0} }, ++ { MODKEY|WLR_MODIFIER_SHIFT, -1, XKB_KEY_C, killclient, {0} }, ++ { MODKEY, -1, XKB_KEY_t, setlayout, {.v = &layouts[0]} }, ++ { MODKEY, -1, XKB_KEY_f, setlayout, {.v = &layouts[1]} }, ++ { MODKEY, -1, XKB_KEY_m, setlayout, {.v = &layouts[2]} }, ++ { MODKEY, -1, XKB_KEY_space, setlayout, {0} }, ++ { MODKEY|WLR_MODIFIER_SHIFT, -1, XKB_KEY_space, togglefloating, {0} }, ++ { MODKEY, -1, XKB_KEY_e, togglefullscreen, {0} }, ++ { MODKEY, -1, XKB_KEY_0, view, {.ui = ~0} }, ++ { MODKEY|WLR_MODIFIER_SHIFT, -1, XKB_KEY_parenright, tag, {.ui = ~0} }, ++ { MODKEY, -1, XKB_KEY_comma, focusmon, {.i = WLR_DIRECTION_LEFT} }, ++ { MODKEY, -1, XKB_KEY_period, focusmon, {.i = WLR_DIRECTION_RIGHT} }, ++ { MODKEY|WLR_MODIFIER_SHIFT, -1, XKB_KEY_less, tagmon, {.i = WLR_DIRECTION_LEFT} }, ++ { MODKEY|WLR_MODIFIER_SHIFT, -1, XKB_KEY_greater, tagmon, {.i = WLR_DIRECTION_RIGHT} }, + TAGKEYS( XKB_KEY_1, XKB_KEY_exclam, 0), + TAGKEYS( XKB_KEY_2, XKB_KEY_at, 1), + TAGKEYS( XKB_KEY_3, XKB_KEY_numbersign, 2), +@@ -152,14 +152,14 @@ static const Key keys[] = { + TAGKEYS( XKB_KEY_7, XKB_KEY_ampersand, 6), + TAGKEYS( XKB_KEY_8, XKB_KEY_asterisk, 7), + TAGKEYS( XKB_KEY_9, XKB_KEY_parenleft, 8), +- { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Q, quit, {0} }, ++ { MODKEY|WLR_MODIFIER_SHIFT, -1, XKB_KEY_Q, quit, {0} }, + + /* Ctrl-Alt-Backspace and Ctrl-Alt-Fx used to be handled by X server */ +- { WLR_MODIFIER_CTRL|WLR_MODIFIER_ALT,XKB_KEY_Terminate_Server, quit, {0} }, ++ { WLR_MODIFIER_CTRL|WLR_MODIFIER_ALT,-1,XKB_KEY_Terminate_Server, quit, {0} }, + /* Ctrl-Alt-Fx is used to switch to another VT, if you don't know what a VT is + * do not remove them. + */ +-#define CHVT(n) { WLR_MODIFIER_CTRL|WLR_MODIFIER_ALT,XKB_KEY_XF86Switch_VT_##n, chvt, {.ui = (n)} } ++#define CHVT(n) { WLR_MODIFIER_CTRL|WLR_MODIFIER_ALT,-1,XKB_KEY_XF86Switch_VT_##n, chvt, {.ui = (n)} } + CHVT(1), CHVT(2), CHVT(3), CHVT(4), CHVT(5), CHVT(6), + CHVT(7), CHVT(8), CHVT(9), CHVT(10), CHVT(11), CHVT(12), + }; +diff --git a/dwl.c b/dwl.c +index bf763dfc..05e667f8 100644 +--- a/dwl.c ++++ b/dwl.c +@@ -143,6 +143,7 @@ typedef struct { + + typedef struct { + uint32_t mod; ++ int chain; + xkb_keysym_t keysym; + void (*func)(const Arg *); + const Arg arg; +@@ -353,6 +354,7 @@ static const char broken[] = "broken"; + static pid_t child_pid = -1; + static int locked; + static void *exclusive_focus; ++static int chainkey = -1; + static struct wl_display *dpy; + static struct wlr_backend *backend; + static struct wlr_scene *scene; +@@ -1438,11 +1440,30 @@ keybinding(uint32_t mods, xkb_keysym_t sym) + const Key *k; + for (k = keys; k < END(keys); k++) { + if (CLEANMASK(mods) == CLEANMASK(k->mod) +- && sym == k->keysym && k->func) { ++ && sym == k->keysym ++ && chainkey == -1 ++ && k->chain == -1 ++ && k->func) { + k->func(&k->arg); + return 1; + } ++ else if (sym == k->keysym ++ && chainkey != -1 ++ && k->chain == chainkey ++ && k->func) { ++ k->func(&k->arg); ++ chainkey = -1; ++ return 1; ++ } ++ else if (CLEANMASK(mods) == CLEANMASK(k->mod) ++ && k->chain == (int)sym ++ && chainkey == -1 ++ && k->func) { ++ chainkey = sym; ++ return 1; ++ } + } ++ chainkey = -1; + return 0; + } + +-- +2.43.0 +