cajhin / capsicain

Powerful low-level keyboard remapping tool for Windows
349 stars 18 forks source link

hang after pressing Pause key in debug mode #19

Closed bitoj closed 3 years ago

bitoj commented 3 years ago

Capsicain and all Windows keyboard processing stops after pressing the Pause key in debug mode with the Capsicain Window active. After closing the program using the mouse, it appears that Windows thinks a control key is being pressed. Tapping LCTRL restores proper Windows keyboard responses.

This can be reproduced using the following minimal configuration.

GLOBAL IniVersion test-pause
GLOBAL ActiveConfigOnStartup 9

[CONFIG_9]
OPTION ConfigName test
OPTION debug

After tapping Pause in debug mode, something like the following is shown as the last output.

(242015824 ms) [   LCTRL%p =1d 4] [M:2]          (2 ms) -- {LCTRLv #1}.
(    2 ms) [ NUMLOCKv =45 0] [M:2]       (0 ms) -- {NUMLOCKv #2}

Tapping Pause a second time, or tapping LCTRL while capsicain is still running, does not help.

In this situation Windows does not even receive input from a second attached keyboard (with OPTION ProcessOnlyFirstKeyboard; not shown in the minimal configuration above).

This is not a significant issue for me, because

cajhin commented 3 years ago

This is a Windows feature that (I think) cannot be disabled. When you press pause with a console windows active, Windows pauses the process running in it. Which means that Capsicain stops, and all keyboard processing stops. The same happens when you mark text in the console.

update: just tested it with a big keyboard, there's a bug somewhere. Looking into it...

cajhin commented 3 years ago

oh my, this is a bizarre hackfest straight from the 70's...

LCtrl + NumLock triggers "Pause" in Windows. You resume with Ctrl+Z (which of course does not work when keyboard input is paused)

The Pause key actually sends: superduperspecialEscapeCode "E2" LCtrl down NumLock down <- at this point Windows pauses an active console LCtrl up NumLock up

Not sure how to handle this.

I'm using tenkeyless keyboards that don't even have those keys... but I don't like it when my code is flawed.

bitoj commented 3 years ago

There is no useful software without flaws. You could always document it as a known limitation, that is relevant only in a particular situation.

The only reason I reported it, is that I saw you are rightly proud of your work and you might not like it when people new to the program and examining all their key labels could encounter a hanging system, like I did. Providing a warning might prevent that. I do not really consider this a practical limitation.

Funny thing about the different choices keyboard manufacturers make. I have 3 different TKL boards with a Pause key in the top right corner. That extreme position is the main reason I started using the key at all, and then only to remap it (in AHK) to something I might need when I am not typing. I mainly use it to change context when I am working on a drawing tablet with a pen in my right hand, or for test mappings.

When you do continue with some fix, might I suggest taking the following into account.

If I were the developer, I think I would choose to

cajhin commented 3 years ago

fixed with v83 beta

Same PAUSE label as before, you can actually rewire from and to that 'pseudo-key'. What happens behind the curtain is very different from other keys, but users don't need to know that.

Pause is now discarded if capsicain is the foreground window.... AND it is not disabled (it doesn't check any keys while it's disabled, so I cannot protect it from a user who pauses it while it is disabled or on layer 0).

The common case should be your case, though, you have the window in the foreground only while actively working on a config.

bitoj commented 3 years ago

No more hanging capsicain and keyboard processing, so the real problem is solved. Closing the issue might be appropriate.

However, I noticed a regression in handling the real NumLock key. This is now also blocked in combination with Ctrl, even when that combination was not a problem.

I also see a few minor inconsistencies in response to physical Pause and a key that is rewired to Pause, which might probably be expected because of the peculiar status of the Pause key.

With Pause I see some effects of a Ctrl that was not really pressed, but part of the strange scan code sequence for the Pause key. Those effects are only noticeable outside capsicain, though.

I tested with the following configuration and systematically tried all combinations.

[CONFIG_3]
OPTION ConfigName numlock
OPTION debug
combo numlock [^.^^] > moddedkey(0 + .)
combo numlock [^.^&] > moddedkey(1 + .)
combo numlock [^.&^] > moddedkey(2 + .)
combo numlock [^.&&] > moddedkey(3 + .)
combo numlock [&.^^] > moddedkey(8 + .)
combo numlock [&.^&] > moddedkey(9 + .)
combo numlock [&.&^] > moddedkey(A + .)
combo numlock [&.&&] > moddedkey(B + .)

[CONFIG_4]
OPTION ConfigName pause
OPTION debug
rewire scrlock pause
combo pause [^.^^] > moddedkey(0 + .)
combo pause [^.^&] > moddedkey(1 + .)
combo pause [^.&^] > moddedkey(2 + .)
combo pause [^.&&] > moddedkey(3 + .)
combo pause [&.^^] > moddedkey(8 + .)
combo pause [&.^&] > moddedkey(9 + .)
combo pause [&.&^] > moddedkey(A + .)
combo pause [&.&&] > moddedkey(B + .)

Would you like me to submit new issues? The old and new limitations are not really limiting my enjoyment of the program, so it would purely be of use in pursuit of perfection.

cajhin commented 3 years ago

Thanks for systematically testing it, I really appreciate your efforts.

Let's keep this issue open. Pause, LCtrl+NumLock (and the SysReq key aka PRINT) are still 'surprising'.

The issue with LCTRL+NumLock is that this triggers the "Windows signal Pause". When I see that sequence, I immediately map it to PAUSE. Then your Combo rule does not see the NumLock. This is done only as protection against "Pause signal on foreground Capsicain", which is kind of "just don't do that, please". I could remove the check, then your Combo works.

The real solution for those issues would be to move capsicain from the console framework to a Windows forms framework. I'm considering that, even though I want nothing to do with Windows (more complexity less reliability).

The issue with Ctrl+Pause is that, again for some druid's decision, your keyboard actually sends completely different sequences for 'Pause key' and 'LCtrl+Pause key'. I should probably catch both sequences, just to be correct.

cajhin commented 3 years ago

The testcases with NumLock and Pause combos work now with v86.

The foreground console is mostly protected about Pause and Break signals (exceptions: 1. you produce the signals yourself with combos 2. you use PAUSE as ON/OFF toggle and press it until it autorepeats)

bitoj commented 3 years ago

Confirmed. Other tests using combinations with the messy keys I coult think of also work, including using Pause as a modifier.

My tests did not include sending the messy keys, however.

Nice job.