rvaiya / keyd

A key remapping daemon for linux.
MIT License
2.58k stars 156 forks source link

Layer binding affected by modifier #765

Open dwrz opened 1 month ago

dwrz commented 1 month ago

I have the following configuration:

include layouts/dvorak

[ids]
*

[global]
default_layout = dvorak
layer_indicator = 1

[dvorak]
rightalt = layer(control)
leftalt = layer(meta)
meta = layer(alt)
a = overloadt(nav, a, 150)
s = overloadt(sym, o, 150)
d = overloadt(num, e, 150)
capslock = noop

[nav]
k = left
l = down
o = up
; = right
i = home
p = end
[ = pageup
' = pagedown

[sym]
, = !
. = @
/ = #
k = $
l = %
; = ^
i = &
o = *
p = (
[ = )

[num]
m = 0
, = 1
. = 2
/ = 3
k = 4
l = 5
; = 6
i = 7
o = 8
p = 9
[ = 0

When I press a to activate the arrow nav layer, pressing shift and one of the layer arrows does not result in shift+arrow, but in a capitalized letter. Is this expected behavior, or am I doing something wrong?

dwrz commented 1 month ago

The man page states:

Note that bindings are not affected by the modifiers of the layer in which they are defined. 
Thus capslock+j will produce an unmodified down keypress, while shift+control+j will produce shift+down as expected.

Does this not apply to overloadt?

rvaiya commented 1 month ago

The problem is that the dvorak layout ships with a shift layer which overrides any bindings defined in [dvorak] (it is a modifier layer with bindings which override the shift modifier).

You can solve this problem in one of two ways:

  1. By explicitly overriding the binding defined in the shift layer:

    [dvorak_shift]
    a = overloadt(nav, A, 150)
  2. By omitting the dvorak_shift layer altogther (i.e by copying the [dvorak] section from /usr/local/keyd/layouts/dvorak)

And before you ask, this exists for reasons to do with layout generation :P. Many layout map shifted symbols to things which don't correspond to keycodes, so the generation logic creates a dedicated shift layer for each layout. This is admittedly unnecessary in the case of simple english layouts since qwerty and dvorak shifted symbols are identical.

dwrz commented 1 month ago

Thank you! I am trying to replace a QMK keyboard with keyd and I really appreciate all your work on this project.

The solution you've provided works, but I seem to run into a limitation: if I press shift, then a, it works, but if I press and hold a, and then press shift, I get capitalized letters instead of the nav layer. Is there anything I'm missing?

rvaiya commented 1 month ago

The solution you've provided works, but I seem to run into a limitation: if I press shift, then a, it works, but if I press and hold a, and then press shift, I get capitalized letters instead of the nav layer. Is there anything I'm missing?

The problem is that dvorak_shift gets applied after the nav layer and masks it. This is just a byproduct of how layers work, and can observed using keyd listen. In this case the best solution is to bypass [dvorak_shift] altogether which can be achieve by adding:

[dvorak]

shift = layer(shift)

to your config. It probably makes sense to make this the default for English letter layouts with standard qwerty shift values.

dwrz commented 1 month ago

Amazing. It works much better now -- thank you.

I still have one small issue -- if I press and release the shift key quickly on the keys with an overloadt action, I get a lowercase key instead of the shifted key.

For example, if I press shift+a very quickly, I get a lowercase a instead of A.

I tried to record a video, though I'm not sure how helpful that is without seeing the keyboard.

https://github.com/rvaiya/keyd/assets/21134999/6d42235c-1619-48b2-b51f-3eb0d8d9e26f