diff --git a/data/keyd-application-mapper.1.gz b/data/keyd-application-mapper.1.gz index 8c11f22..c08f74c 100644 Binary files a/data/keyd-application-mapper.1.gz and b/data/keyd-application-mapper.1.gz differ diff --git a/data/keyd.1.gz b/data/keyd.1.gz index b78ee49..c4fb035 100644 Binary files a/data/keyd.1.gz and b/data/keyd.1.gz differ diff --git a/docs/keyd.scdoc b/docs/keyd.scdoc index 37e2bdb..9c60112 100644 --- a/docs/keyd.scdoc +++ b/docs/keyd.scdoc @@ -66,7 +66,7 @@ the form _[section_name]_ followed by a set of _bindings_. Lines beginning with a hash are ignored. Config files are stored in _/etc/keyd/_ and loaded upon initialization. -The reload command can be used to update the working set of config +The reload command can be used to update the working set of config files (e.g sudo keyd reload). A valid config file has the extension _.conf_ and *must* begin with an _[ids]_ @@ -253,7 +253,7 @@ the full config actually looks something like this: j = down ``` -If multiple bindings for the same key are present, the most recent one takes precedence. +If multiple bindings for the same key are present, the most recent one takes precedence. A layer heading may also appear multiple times, in which case the layer will contain the sum of all bindings. Note that the layer type may not be reassigned. @@ -620,9 +620,11 @@ A key may optionally be bound to an _action_ which accepts zero or more argument If tapped, activate the supplied layer for the duration of the next keypress. *swap()* - Swap the currently active layer with the supplied one. The - supplied layer is active for the duration of the depression of the - current layer's activation key. + Swap the currently active layer with the supplied one. If the current + layer is toggled, it is deactivated and the supplied layer is toggled + instead. Otherwise, the active layer is deactivated and the supplied + layer remains active for the duration of the depression of the + activating key. ``` [control] @@ -635,6 +637,13 @@ A key may optionally be bound to an _action_ which accepts zero or more argument b = S-insert ``` + NOTE: + + You probably don't need to use this unless you are trying to do something quite + involved. Think hard about whether or not what you are trying to achieve + can be done by other means, as it is easy to end up in states which + are impossible to exit. + *setlayout()* Set the current layout. diff --git a/src/keyboard.c b/src/keyboard.c index 9168c7b..3a698ce 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -709,28 +709,44 @@ static long process_descriptor(struct keyboard *kbd, uint8_t code, size_t i; struct cache_entry *ce = NULL; - for (i = 0; i < CACHE_SIZE; i++) { - uint8_t code = kbd->cache[i].code; - int layer = kbd->cache[i].layer; - int type = kbd->config.layers[layer].type; - - if (code && layer == dl && type == LT_NORMAL && layer != 0) { - ce = &kbd->cache[i]; - break; + if (kbd->layer_state[dl].toggled) { + deactivate_layer(kbd, dl); + kbd->layer_state[dl].toggled = 0; + + activate_layer(kbd, 0, idx); + kbd->layer_state[idx].toggled = 1; + update_mods(kbd, -1, 0); + } else if (kbd->layer_state[dl].oneshot) { + deactivate_layer(kbd, dl); + kbd->layer_state[dl].oneshot = 0; + + activate_layer(kbd, 0, idx); + kbd->layer_state[idx].oneshot = 1; + update_mods(kbd, -1, 0); + } else { + for (i = 0; i < CACHE_SIZE; i++) { + uint8_t code = kbd->cache[i].code; + int layer = kbd->cache[i].layer; + int type = kbd->config.layers[layer].type; + + if (code && layer == dl && type == LT_NORMAL && layer != 0) { + ce = &kbd->cache[i]; + break; + } } - } - if (ce) { - ce->d.op = OP_LAYER; - ce->d.args[0].idx = idx; + if (ce) { + ce->d.op = OP_LAYER; + ce->d.args[0].idx = idx; - deactivate_layer(kbd, dl); - activate_layer(kbd, ce->code, idx); + deactivate_layer(kbd, dl); + activate_layer(kbd, ce->code, idx); - if (macro) - execute_macro(kbd, dl, macro); + if (macro) + execute_macro(kbd, dl, macro); - update_mods(kbd, -1, 0); + update_mods(kbd, -1, 0); + } } } else { if (macro && diff --git a/t/swap-oneshot.t b/t/swap-oneshot.t new file mode 100644 index 0000000..eab3c0c --- /dev/null +++ b/t/swap-oneshot.t @@ -0,0 +1,10 @@ +1 down +2 down +300ms +1 up +2 up +a down +a up + +b down +b up diff --git a/t/swap-toggle.t b/t/swap-toggle.t new file mode 100644 index 0000000..8b09918 --- /dev/null +++ b/t/swap-toggle.t @@ -0,0 +1,15 @@ +4 down +4 up +s down +s up +s down +s up +x down +x up +s down +s up + +a down +a up +shift down +shift up diff --git a/t/test.conf b/t/test.conf index af38603..a8ed1e8 100644 --- a/t/test.conf +++ b/t/test.conf @@ -31,6 +31,7 @@ p = layerm(shift, macro(on)) 7 = overload(meta, oneshot(control)) 8 = timeout(overload(control, a), 1, b) 9 = M-C-S-x +1+2 = oneshot(test) l = layer(test) m = macro(C-h one) c = oneshot(control) @@ -69,11 +70,17 @@ b = macro(leftcontrol+n) c = macro(leftcontrol n) x = overload(meta, swap(shift)) +[test2] + +s = a +x = toggle(test2) + [test] o = oneshot(o) a = b b = toggle(test) +s = swap(test2) c = clear() [o:C]