diff --git a/docs/keyd.scdoc b/docs/keyd.scdoc index 4468a481..6107a69c 100644 --- a/docs/keyd.scdoc +++ b/docs/keyd.scdoc @@ -694,6 +694,10 @@ A key may optionally be bound to an _action_ which accepts zero or more argument *clearm()* Identical to *clear*, but executes the supplied macro before clearing layers. +*togglekey()* + Toggle whether the key is pressed. Effectively holds the key down until + togglekey is performed again. + ## Key overloading *overload(, )* diff --git a/src/config.c b/src/config.c index 6f5555a8..9e3bea95 100644 --- a/src/config.c +++ b/src/config.c @@ -74,12 +74,14 @@ static struct { ARG_TIMEOUT, ARG_SENSITIVITY, ARG_DESCRIPTOR, + ARG_KEYCODE, } args[MAX_DESCRIPTOR_ARGS]; } actions[] = { { "swap", NULL, OP_SWAP, { ARG_LAYER } }, { "clear", NULL, OP_CLEAR, {} }, { "oneshot", NULL, OP_ONESHOT, { ARG_LAYER } }, { "toggle", NULL, OP_TOGGLE, { ARG_LAYER } }, + { "togglekey", NULL, OP_TOGGLEKEY, { ARG_KEYCODE } }, { "clearm", NULL, OP_CLEARM, { ARG_MACRO } }, { "swapm", NULL, OP_SWAPM, { ARG_LAYER, ARG_MACRO } }, @@ -753,6 +755,13 @@ static int parse_descriptor(char *s, arg->idx = config->nr_macros; config->nr_macros++; + break; + case ARG_KEYCODE: + arg->code = lookup_keycode(argstr); + if (arg->code == 0) { + err("%s is not a valid keycode", argstr); + return -1; + } break; default: assert(0); diff --git a/src/config.h b/src/config.h index ca3e70ad..6725be9b 100644 --- a/src/config.h +++ b/src/config.h @@ -44,6 +44,7 @@ enum op { OP_OVERLOAD_IDLE_TIMEOUT, OP_TOGGLE, OP_TOGGLEM, + OP_TOGGLEKEY, OP_MACRO, OP_MACRO2, diff --git a/src/keyboard.c b/src/keyboard.c index 546e985d..5a00284f 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -729,6 +729,17 @@ static long process_descriptor(struct keyboard *kbd, uint8_t code, clear_oneshot(kbd); } + break; + case OP_TOGGLEKEY: + new_code = d->args[0].code; + + if (pressed) { + if (kbd->keystate[new_code]) { + send_key(kbd, new_code, 0); + } else { + send_key(kbd, new_code, 1); + } + } break; case OP_TIMEOUT: struct pending_timeout *pt = &kbd->pending_timeout; diff --git a/t/test.conf b/t/test.conf index d6cec40d..2eff9418 100644 --- a/t/test.conf +++ b/t/test.conf @@ -33,6 +33,7 @@ p = layerm(shift, macro(on)) 1+2 = oneshot(test) l = layer(test) m = macro(C-h one) +n = togglekey(q) c = oneshot(control) s = layer(shift) o = overloadt(control, a, 10) diff --git a/t/togglekey.t b/t/togglekey.t new file mode 100644 index 00000000..c0907897 --- /dev/null +++ b/t/togglekey.t @@ -0,0 +1,11 @@ +n down +n up +a down +a up +n down +n up + +q down +a down +a up +q up