jtroo / kanata

Improve keyboard comfort and usability with advanced customization
GNU Lesser General Public License v3.0
3.21k stars 131 forks source link

Bug: Dead keys cause keyboard modifier state to get corrupt - witnessed on colemak #1077

Closed DanielFabian closed 6 months ago

DanielFabian commented 6 months ago

Requirements

Describe the bug

When working with colemak as a system layout, when I try entering ü, it hangs the input entirely until I restart kanata.

ü is entered in colemak as the sequence AltGr-d (dead key for umlaut) followed by u. (On a qwerty keyboard it's AltGr-c followed by i).

I'm using the winiov2 version based off the current master branch.

The keyboard is not entirely dead, but rather it looks like some modifier key is probably stuck or similar.

Relevant kanata config

(defcfg
  process-unmapped-keys yes
)

(defsrc
  grv   1    2    3    4    5    6    7    8    9    0    -    =    bspc
  tab   q    w    e    r    t    y    u    i    o    p    [    ]    ret
  esc   a    s    d    f    g    h    j    k    l    ;    '    \
  lsft lsgt  z    x    c    v    b    n    m    ,    .    /    rsft
  lctl lmet lalt            spc                 ralt rmet cmp  rctl
)

(deflayermap (default)
  esc (tap-hold 200 200 esc (layer-while-held symbols))
  '   (tap-hold 200 200 apo (layer-while-held symbols))
)

(deflayer symbols
  _     _    _    _    _    _    _    _    _    _    _    _    _    _
  _     _    _    _    _    _    _    S-p  ▲    _    _    _    _    _
  _     _    S-[  [    S-9  _    _    ◀    ▼    ▶    _    _    _
  _     _    S-]  ]    S-0  _    _    _    S-6  S-4  _    _    _
  _     _    _              _                   _    _    _    _ 
)

To Reproduce

  1. set up colemak as the system layout in windows
  2. start entering AltGr-d to start the dead key
  3. press u.
  4. try typing anything else, it looks like maybe the layer is stuck in a key-combo or something similar.

Expected behavior

the key sequence AltGr-d followed by u types ü without changing the keyboard state. I don't even think my config is meant to handle this particular combo at all.

Kanata version

kanata 1.7.0-prerelease

Debug logs

10:24:03.2050 [INFO] kanata v1.7.0-prerelease starting
10:24:03.2051 [INFO] using LLHOOK+SendInput for keyboard IO
10:24:03.2112 [INFO] process unmapped keys: true
10:24:03.2115 [DEBUG] (1) kanata_parser::cfg::alloc: freeing allocations of length 0
10:24:03.2118 [INFO] config file is valid
10:24:03.2119 [INFO] Asking Windows to improve timer precision
10:24:03.2120 [INFO] Asking Windows to increase process priority
10:24:03.2121 [INFO] Sleeping for 2s. Please release all keys and don't press additional ones. Run kanata with --help to see how understand more and how to disable this sleep.
10:24:05.2128 [INFO] entering the processing loop
10:24:05.2131 [INFO] Init: catching only releases and sending immediately
10:24:05.9432 [INFO] Starting kanata proper
10:24:05.9434 [INFO] You may forcefully exit kanata by pressing lctl+spc+esc at any time. These keys refer to defsrc input, meaning BEFORE kanata remaps keys.
10:24:07.5872 [DEBUG] (1) kanata_state_machine::kanata::windows::llhook: event loop: KeyEvent { code: KEY_LEFTCTRL, value: Press }
10:24:07.5875 [DEBUG] (2) kanata_state_machine::kanata: process recv ev KeyEvent { code: KEY_LEFTCTRL, value: Press }
10:24:07.5876 [DEBUG] (2) kanata_state_machine::kanata: key press     LCtrl
10:24:07.5878 [DEBUG] (1) kanata_state_machine::kanata::windows::llhook: event loop: KeyEvent { code: KEY_RIGHTALT, value: Press }
10:24:07.5885 [DEBUG] (2) kanata_state_machine::kanata: process recv ev KeyEvent { code: KEY_RIGHTALT, value: Press }
10:24:07.5886 [DEBUG] (2) kanata_state_machine::kanata: key press     RAlt
10:24:07.6540 [DEBUG] (1) kanata_state_machine::kanata::windows::llhook: event loop: KeyEvent { code: KEY_C, value: Press }
10:24:07.6550 [DEBUG] (2) kanata_state_machine::kanata: process recv ev KeyEvent { code: KEY_C, value: Press }
10:24:07.6551 [DEBUG] (2) kanata_state_machine::kanata: key press     C
10:24:07.7621 [DEBUG] (1) kanata_state_machine::kanata::windows::llhook: event loop: KeyEvent { code: KEY_RIGHTALT, value: Release }
10:24:07.7629 [DEBUG] (2) kanata_state_machine::kanata: process recv ev KeyEvent { code: KEY_RIGHTALT, value: Release }
10:24:07.7630 [DEBUG] (2) kanata_state_machine::kanata: key release   RAlt
10:24:07.7689 [DEBUG] (1) kanata_state_machine::kanata::windows::llhook: event loop: KeyEvent { code: KEY_C, value: Release }
10:24:07.7701 [DEBUG] (2) kanata_state_machine::kanata: process recv ev KeyEvent { code: KEY_C, value: Release }
10:24:07.7703 [DEBUG] (2) kanata_state_machine::kanata: key release   C
10:24:08.6921 [DEBUG] (1) kanata_state_machine::kanata::windows::llhook: event loop: KeyEvent { code: KEY_I, value: Press }
10:24:08.6924 [DEBUG] (2) kanata_state_machine::kanata: process recv ev KeyEvent { code: KEY_I, value: Press }
10:24:08.6925 [DEBUG] (2) kanata_state_machine::kanata: key press     I
10:24:08.7561 [DEBUG] (1) kanata_state_machine::kanata::windows::llhook: event loop: KeyEvent { code: KEY_I, value: Release }
10:24:08.7572 [DEBUG] (2) kanata_state_machine::kanata: process recv ev KeyEvent { code: KEY_I, value: Release }
10:24:08.7573 [DEBUG] (2) kanata_state_machine::kanata: key release   I
10:24:12.0631 [DEBUG] (1) kanata_state_machine::kanata::windows::llhook: event loop: KeyEvent { code: KEY_LEFTCTRL, value: Press }
10:24:12.0643 [DEBUG] (2) kanata_state_machine::kanata: process recv ev KeyEvent { code: KEY_LEFTCTRL, value: Repeat }
10:24:12.0644 [DEBUG] (2) kanata_state_machine::kanata::key_repeat: empty layer-while-held outputs, probably transparent
10:24:12.0645 [DEBUG] (2) kanata_state_machine::kanata::key_repeat: checking defsrc output
10:24:12.2310 [DEBUG] (1) kanata_state_machine::kanata::windows::llhook: event loop: KeyEvent { code: KEY_X, value: Press }
10:24:12.2321 [DEBUG] (2) kanata_state_machine::kanata: process recv ev KeyEvent { code: KEY_X, value: Press }
10:24:12.2322 [DEBUG] (2) kanata_state_machine::kanata: key press     X

Operating system

Windows 11

Additional context

On colemak, I expect probably it's got more something to do with the combination of dead keys and scan codes than colemak, specifically, but it's my repro.

jtroo commented 6 months ago

https://github.com/jtroo/kanata/blob/main/docs/platform-known-issues.adoc#windows-1011-llhook

Please have a look at "AltGr can misbehave"

DanielFabian commented 6 months ago

oh, I see, so a mitigation, I can just dump the alt! Thanks.

DanielFabian commented 6 months ago

But that apparently doesn't seem to help. It still catches the altgr and gets confused. So is the comment not accurate, then?

DanielFabian commented 6 months ago

alright, so it looks like not having altgr does not help. But adding the mitigation according to the comment helps.

I.e. maybe update the comment, because it looks like it hijacks the altgr regardless of whether or not it's in the defsrc.

jtroo commented 6 months ago

But that apparently doesn't seem to help. It still catches the altgr and gets confused. So is the comment not accurate, then?

That would be because of process-unmapped-keys. Could you quote the bit of text that suggested to remove altgr/ralt so I can add more info there?

DanielFabian commented 6 months ago

image When I read that, this implied to me that if I were to remove ralt from my config it'd be fine. Which is just as well, since I didn't need to rebind it. But I think it really means if I want ralt to not work at all, which is not what I want.

In my case, I have a normal keyboard with a number block but I don't mention it because I don't need to rebind anything with it. That said, the keys are supposed to continue working. That's why I was using process-unmapped-keys.

That's what I found confusing. I think it's pretty usual that you'd want the keys on your keyboard to work, even if you don't need to remap them? And if so, that's a general problem for ISO keyboards that don't have a right alt, but rather an altgr.

jtroo commented 6 months ago

Improved the docs in: 75b845c393a7a1ef0f128f8f7e8b8d616ce039e3