From c5f77c595172d27165f88c2baee869bf5cd0ed59 Mon Sep 17 00:00:00 2001 From: Raheman Vaiya Date: Mon, 24 Jan 2022 14:30:30 -0500 Subject: [PATCH] Allow mapping to modifier keycodes --- src/descriptor.c | 7 +++---- src/keyd.c | 25 +++++++++++++------------ t/layer4.t | 13 +++++++++++++ t/run.sh | 2 +- t/test.conf | 1 + 5 files changed, 31 insertions(+), 17 deletions(-) create mode 100644 t/layer4.t diff --git a/src/descriptor.c b/src/descriptor.c index ef0baa8..4b17aa8 100644 --- a/src/descriptor.c +++ b/src/descriptor.c @@ -236,10 +236,9 @@ int parse_descriptor(char *s, if (!parse_key_sequence(s, &seq)) { desc->op = OP_KEYSEQ; - if (keycode_to_mod(seq.code)) { - err("modifier keycodes are not directly mappable, you probably want layer() (e.g layer(alt))"); - return -1; - } + if (keycode_to_mod(seq.code)) + fprintf(stderr, + "WARNING: mapping modifier keycodes directly may produce unintended results, you probably want layer() instead\n"); desc->args[0].sequence = seq; } else if (!parse_macro_fn(&config->macros[macro_idx], s)) { diff --git a/src/keyd.c b/src/keyd.c index f622190..3e05b11 100644 --- a/src/keyd.c +++ b/src/keyd.c @@ -226,22 +226,23 @@ static void send_repetitions() void set_mods(uint16_t mods) { + static uint16_t state = 0; size_t i; - for (i = 0; i < sizeof modifier_table / sizeof modifier_table[0]; i++) { - struct modifier_table_ent *m = &modifier_table[i]; + uint16_t diff = mods ^ state; - if (m->mask & mods) { - if (!keystate[m->code1] && !keystate[m->code2]) - send_key(m->code1, 1); - } else { - if (keystate[m->code1]) - send_key(m->code1, 0); + if (MOD_CTRL & diff) + send_key(KEY_LEFTCTRL, !!(MOD_CTRL & mods)); + if (MOD_ALT_GR & diff) + send_key(KEY_RIGHTALT, !!(MOD_ALT_GR & mods)); + if (MOD_SHIFT & diff) + send_key(KEY_LEFTSHIFT, !!(MOD_SHIFT & mods)); + if (MOD_SUPER & diff) + send_key(KEY_LEFTMETA, !!(MOD_SUPER & mods)); + if (MOD_ALT & diff) + send_key(KEY_LEFTALT, !!(MOD_ALT & mods)); - if (keystate[m->code2]) - send_key(m->code2, 0); - } - } + state = mods; } /* Block on the given keyboard nodes until no keys are depressed. */ diff --git a/t/layer4.t b/t/layer4.t new file mode 100644 index 0000000..02a7ef8 --- /dev/null +++ b/t/layer4.t @@ -0,0 +1,13 @@ +s down +meta down +c down +c up +meta up +s up + +shift down +meta down +c down +c up +meta up +shift up diff --git a/t/run.sh b/t/run.sh index ced6f21..cb1f958 100755 --- a/t/run.sh +++ b/t/run.sh @@ -4,7 +4,7 @@ cleanup() { sudo pkill keyd - sleep .5s + sleep 1s sudo systemctl restart keyd trap - EXIT diff --git a/t/test.conf b/t/test.conf index 0a3b6db..b01133d 100644 --- a/t/test.conf +++ b/t/test.conf @@ -23,6 +23,7 @@ l = layer(test) t = overload(o, esc, 2) m = macro(C-h one) - = layout(layout2) +s = leftshift [layout2:layout]