jtroo / kanata

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

hanguel key works wierd with interception #127

Closed code4rain closed 1 year ago

code4rain commented 2 years ago

Test with below scenario

env: window11

kanata.kdb

(defcfg
)
(defsrc
 lctl hangeul
)
(deflayer default
 @han hangeul
)
(defalias
  han (tap-hold 200 200 hangeul lctl)
)

Test with release build

  1. Install with interception
  2. run kanata with --debug(which build latest code with release build(cargo build --release --features=interception)
  3. press and release the lctl key shortly
    12:27:44 [DEBUG] (1) kanata::kanata::windows::interception: got stroke Keyboard { code: LeftControl, state: DOWN, information: 0 }
    12:27:44 [DEBUG] (1) kanata::kanata::windows::interception: sending KeyEvent { code: KEY_LEFTCTRL, value: Press } to processing loop
    12:27:44 [DEBUG] (1) kanata::kanata::windows::interception: got stroke Keyboard { code: LeftControl, state: UP, information: 0 }
    12:27:44 [DEBUG] (1) kanata::kanata::windows::interception: sending KeyEvent { code: KEY_LEFTCTRL, value: Release } to processing loop
    12:27:44 [DEBUG] (2) kanata::kanata: key press     Lang1
    thread '<unnamed>' panicked at 'kanata only sends mapped `OsCode`s: ()', src\oskbd\windows\interception.rs:17:49
    note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

    it does not work.

Also

  1. press and release the hangeul key
    12:33:10 [DEBUG] (1) kanata::kanata::windows::interception: code is not mapped
    12:33:11 [DEBUG] (1) kanata::kanata::windows::interception: got stroke Keyboard { code: Esc, state: UP, information: 0 }
    12:33:11 [DEBUG] (1) kanata::kanata::windows::interception: code is not mapped

    the hangeul key does not work. (English <-> Korean does not transfer.)

Test with debug build (same kanata.kdb)

  1. Install with interception
  2. run kanata with --debug(which build latest code with debug build(cargo build --features=interception)
  3. press and release the lctrl key shortly
    12:35:19 [DEBUG] (1) kanata::kanata::windows::llhook: event loop: KeyEvent { code: KEY_LEFTCTRL, value: Press }
    12:35:19 [DEBUG] (1) kanata::kanata::windows::llhook: event loop: KeyEvent { code: KEY_LEFTCTRL, value: Release }
    12:35:19 [DEBUG] (2) kanata::kanata: key press     Lang1
    12:35:19 [DEBUG] (2) kanata::kanata: key release   Lang1

    it works

Also

  1. press and release the hangeul key
    12:38:29 [DEBUG] (1) kanata::kanata::windows::llhook: event loop: KeyEvent { code: KEY_HANGEUL, value: Press }
    12:38:29 [DEBUG] (2) kanata::kanata: key press     Lang1

    it just press only and the press and release again

    12:38:36 [DEBUG] (1) kanata::kanata::windows::llhook: event loop: KeyEvent { code: KEY_HANGEUL, value: Release }
    12:38:36 [DEBUG] (2) kanata::kanata: key release   Lang1

    haneul key work with press/release twice.

jtroo commented 2 years ago

It looks like there's missing logs in this case for the first set of tests:

  1. press and release the hangeul key

Can do the test again and make sure to add the log message containing the state: DOWN part?

The second set of tests actually use the llhook mechanism, the feature name is interception_driver. Still, that's definitely odd. It looks like hook never received the release event. That's doesn't seem easily fixable.

As an aside as well, the debug vs. release cargo build shouldn't change any behaviour when compiling with the same feature flags. It's just the level of optimizations used for compiling.

code4rain commented 2 years ago

It looks like there's missing logs in this case for the first set of tests:

press and release the hangeul key Can do the test again and make sure to add the log message containing the state: DOWN part?

I found one thing. This is happend only after lctrl presss and release like below

09:50:02 [INFO] kanata v1.0.7 starting
09:50:02 [INFO] NOTE: kanata was compiled to never allow cmd
09:50:02 [INFO] config parsed
09:50:02 [INFO] Asking Windows to improve timer precision
09:50:02 [INFO] Sleeping for 2s. Please release all keys and don't press additional ones.
09:50:04 [INFO] entering the processing loop
09:50:04 [INFO] Init: catching only releases and sending immediately
09:50:05 [INFO] Starting kanata proper
09:50:09 [DEBUG] (1) kanata::kanata::windows::llhook: event loop: KeyEvent { code: KEY_LEFTCTRL, value: Press }
09:50:09 [DEBUG] (1) kanata::kanata::windows::llhook: event loop: KeyEvent { code: KEY_LEFTCTRL, value: Release }
09:50:09 [DEBUG] (2) kanata::kanata: key press     Lang1
09:50:09 [DEBUG] (2) kanata::kanata: key release   Lang1               << End of lctrl release
09:50:12 [DEBUG] (1) kanata::kanata::windows::llhook: event loop: KeyEvent { code: KEY_HANGEUL, value: Press }     << press 
and release hangeul first time
09:50:12 [DEBUG] (2) kanata::kanata: key press     Lang1                
09:50:18 [DEBUG] (1) kanata::kanata::windows::llhook: event loop: KeyEvent { code: KEY_HANGEUL, value: Release }   << press and release hangeul second time
09:50:18 [DEBUG] (2) kanata::kanata: key release   Lang1

The second set of tests actually use the llhook mechanism, the feature name is interception_driver. Still, that's definitely odd. It looks like hook never received the release event. That's doesn't seem easily fixable.

As an aside as well, the debug vs. release cargo build shouldn't change any behaviour when compiling with the same feature flags. It's just the level of optimizations used for compiling.

YES, you're right. That is my mistake. Debug build does not work same as release build when I build with cargo build --features=interception_driver

09:54:56 [DEBUG] (1) kanata::kanata::windows::interception: got stroke Keyboard { code: LeftControl, state: DOWN, information: 0 }
09:54:56 [DEBUG] (1) kanata::kanata::windows::interception: sending KeyEvent { code: KEY_LEFTCTRL, value: Press } to processing loop
09:54:56 [DEBUG] (1) kanata::kanata::windows::interception: got stroke Keyboard { code: LeftControl, state: UP, information: 0 }
09:54:56 [DEBUG] (1) kanata::kanata::windows::interception: sending KeyEvent { code: KEY_LEFTCTRL, value: Release } to processing loop
09:54:56 [DEBUG] (2) kanata::kanata: key press     Lang1
thread '<unnamed>' panicked at 'kanata only sends mapped `OsCode`s: ()', src\oskbd\windows\interception.rs:17:49
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
jtroo commented 2 years ago

Unfortunately it looks like there's an issue with using the llhook mechanism to read the hangeul key. The issue looks similar to the issues discussed in #55.

For the tests with the interception driver, can you clarify if you're actually pressing lctl or hangeul? If you're pressing lctl, can you send the logs for pressing hangeul so that we can see what the interception Stroke::Keyboard values are? If you're already pressing hangeul, then that would be very weird to me.

code4rain commented 2 years ago

@jtroo Thank you for information. I will check #55.

And for the Hangeul with interception driver. It show the ESC key when I press and release Hangeul key as below.

PS C:\tools\kanata> .\kanata_debug.exe --debug
20:51:10 [INFO] kanata v1.0.7 starting
20:51:10 [INFO] NOTE: kanata was compiled to never allow cmd
20:51:10 [INFO] config parsed
20:51:10 [INFO] Asking Windows to improve timer precision
20:51:10 [INFO] Sleeping for 2s. Please release all keys and don't press additional ones.
20:51:12 [INFO] entering the processing loop
20:51:12 [INFO] Init: catching only releases and sending immediately
20:51:13 [INFO] Starting kanata proper
20:51:16 [DEBUG] (1) kanata::kanata::windows::interception: got stroke Keyboard { code: Esc, state: UP, information: 0 }
20:51:16 [DEBUG] (1) kanata::kanata::windows::interception: code is not mapped
20:51:20 [DEBUG] (1) kanata::kanata::windows::interception: got stroke Keyboard { code: Esc, state: UP, information: 0 }
20:51:20 [DEBUG] (1) kanata::kanata::windows::interception: code is not mapped
20:51:21 [DEBUG] (1) kanata::kanata::windows::interception: got stroke Keyboard { code: Esc, state: UP, information: 0 }
20:51:21 [DEBUG] (1) kanata::kanata::windows::interception: code is not mapped
20:51:22 [DEBUG] (1) kanata::kanata::windows::interception: got stroke Keyboard { code: Esc, state: UP, information: 0 }
20:51:22 [DEBUG] (1) kanata::kanata::windows::interception: code is not mapped

Anther weird point is that there is only UP state without DOWN.

FYI. I press and relase ESC key then,

20:54:47 [INFO] kanata v1.0.7 starting
20:54:47 [INFO] NOTE: kanata was compiled to never allow cmd
20:54:47 [INFO] config parsed
20:54:47 [INFO] Asking Windows to improve timer precision
20:54:47 [INFO] Sleeping for 2s. Please release all keys and don't press additional ones.
20:54:49 [INFO] entering the processing loop
20:54:49 [INFO] Init: catching only releases and sending immediately
20:54:50 [INFO] Starting kanata proper
20:54:51 [DEBUG] (1) kanata::kanata::windows::interception: got stroke Keyboard { code: Esc, state: DOWN, information: 0 }
20:54:51 [DEBUG] (1) kanata::kanata::windows::interception: code is not mapped
20:54:51 [DEBUG] (1) kanata::kanata::windows::interception: got stroke Keyboard { code: Esc, state: UP, information: 0 }
20:54:51 [DEBUG] (1) kanata::kanata::windows::interception: code is not mapped
jtroo commented 2 years ago

@code4rain unfortunately it seems like the interception driver can't properly support the hangeul key in its current state. That's very unfortunate, especially considering the llhook mechanism isn't perfect either.

And frustratingly, the interception driver isn't open source so I can't poke around and try to fix it myself 🙁

code4rain commented 2 years ago

@jtroo I understand the situation. And this is the log when I pressed lctrl which mapped tap-hold hanguel and lctl Is it related with interception driver also?

PS C:\tools\kanata> .\kanata_inteception_release.exe --debug
08:42:46 [INFO] kanata v1.0.7 starting
08:42:46 [INFO] NOTE: kanata was compiled to never allow cmd
08:42:46 [INFO] config parsed
08:42:46 [INFO] Asking Windows to improve timer precision
08:42:46 [INFO] Sleeping for 2s. Please release all keys and don't press additional ones.
08:42:48 [INFO] entering the processing loop
08:42:48 [INFO] Init: catching only releases and sending immediately
08:42:49 [INFO] Starting kanata proper
08:42:51 [DEBUG] (1) kanata::kanata::windows::interception: got stroke Keyboard { code: LeftControl, state: DOWN, information: 0 }
08:42:51 [DEBUG] (1) kanata::kanata::windows::interception: sending KeyEvent { code: KEY_LEFTCTRL, value: Press } to processing loop
08:42:52 [DEBUG] (1) kanata::kanata::windows::interception: got stroke Keyboard { code: LeftControl, state: UP, information: 0 }
08:42:52 [DEBUG] (1) kanata::kanata::windows::interception: sending KeyEvent { code: KEY_LEFTCTRL, value: Release } to processing loop
08:42:52 [DEBUG] (2) kanata::kanata: key press     Lang1
thread '<unnamed>' panicked at 'kanata only sends mapped `OsCode`s: ()', src\oskbd\windows\interception.rs:17:49
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
08:43:02 [DEBUG] (1) kanata::kanata::windows::interception: got stroke Keyboard { code: LeftControl, state: DOWN, information: 0 }
08:43:02 [DEBUG] (1) kanata::kanata::windows::interception: sending KeyEvent { code: KEY_LEFTCTRL, value: Press } to processing loop
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: "SendError(..)"', src\kanata\windows\interception.rs:75:40
PS C:\tools\kanata>
jtroo commented 2 years ago

Yea the panic is there because kanata doesn't know what interception codes to send for hangeul. I asked for the logs when you tap the physical hangeul key so I could see if it would output something useful that I could put into the code, but unfortunately it didn't.