Page 1 of 1

Ctrl gets stuck when IME on

Posted: 01 Oct 2015, 17:53
by Aupperle
I have a script that remaps Caps Lock to Ctrl. When I am not using an IME (Input Method Editor, used to type some foreign languages, like Japanese), the remapping works perfectly. Once I turn on an IME (either Google's Japanese IME or the Microsoft Japanese IME), pressing Caps Lock (which is mapped to Ctrl) causes Ctrl to get stuck down until I press the Ctrl key. This is extremely frustrating to me, because I use Caps Lock as my only Ctrl key in Linux and almost always hit it instead of Ctrl. Then when I start typing all manner of things happen (recently, I was typing an assignment into a text box, Ctrl+Tabbed away, came back and pressed w, which closed the tab. I lost my work). Is there a fix for this?
?

Re: Ctrl gets stuck when IME on

Posted: 22 Dec 2016, 05:52
by Guest
Hello, I'm having the same problem!
Just searching for "IME" on this board reveals that the question has been asked several times (e.g. https://www.autohotkey.com/boards/viewt ... E#p103066), but I've not seen any answer or confirmation.
In my very limited understanding, Autohotkey uses the WH_KEYBOARD_LL hook to intercept and substitute the keys. And that hook does not seem to capture some functional keys when in the IME mode.
Steps to reproduce:
[*]Open Notepad
[*]Choose the Japanese layout (https://www.coscom.co.jp/learnjapanese8 ... 0_en2.html)
[*]Run the following script:

Code: Select all

CapsLock::Control
[*]Type "^h". That should open the substitution dialog, and it does.
[*]Type "s". That should have shown "s" on the screen, but instead the Notepad will try to save your file!
This, to me personally, makes me have to avoid AHK since sometimes it may result in some extremely unpleasant and unexpected things like closing the window instead of typing "w" or accidentally submitting an unfinished forum post (just like I did with this one!) instead of starting a new line.

Re: Ctrl gets stuck when IME on

Posted: 22 Dec 2016, 12:56
by sitagi
(I wrote the previous post, but it marked me as a guest somehow)
To add to what I wrote, I am almost fully certain it has to do with the Ctrl+CapsLock shortcut that emulates the Hiragana key (present on Japanese keyboards) when the IME is active. From my understanding, a similar problem exists with all other languages that employ IME on Windows.
It is also worth noting that this particular problem with Ctrl and CapsLock can be solved with the scancode map. I have a suspicion that in a more general case, a workaround for the user would be to remap the needed system keys with "hidden" system-level shortcuts to some other key that doesn't even exist on the keyboard. For instance, remap CapsLock to theSuper key or some other non-existent key, and operate with that without any unwanted side effects.

Re: Ctrl gets stuck when IME on

Posted: 11 May 2020, 06:58
by ktra
Thanks to https://autohotkey.com/board/topic/70019-keyboard-layout-switcher-for-many-layouts/ I have come up with an ad hoc solution to this problem:

Code: Select all

; This should be replaced by whatever your native language is. See 
; http msdn.microsoft.com /en-us/library/dd318693%28v=vs.85%29.aspx  Broken Link for safety
; for the language identifiers list.
; ja := DllCall("LoadKeyboardLayout", "Str", "00000411", "Int", 1)
en := DllCall("LoadKeyboardLayout", "Str", "00000409", "Int", 1)
global currHkl := en

*CapsLock::
w := DllCall("GetForegroundWindow")
pid := DllCall("GetWindowThreadProcessId", "UInt", w, "Ptr", 0)
hkl := DllCall("GetKeyboardLayout", "UInt", pid)
if (hkl <> en)
{
    currHkl := hkl
}
PostMessage 0x50, 0, %en%,, A
SetKeyDelay -1
Send {Blind}{LCtrl DownR}
return

*CapsLock Up::
SetKeyDelay -1
Send {Blind}{LCtrl Up}
if (currHkl <> en)
{
    PostMessage 0x50, 0, %currHkl%,, A
    currHkl := en
}
return
When the IME is in a mode other than ENG, it is turned to ENG mode temporally while holding down the Caps key, but it appears to work anyway.

Re: Ctrl gets stuck when IME on

Posted: 24 May 2020, 01:01
by lexikos
I don't understand how you're even using CapsLock. With Microsoft IME on my Windows 10 system, CapsLock is not even recognizable as CapsLock. The only way I can trigger a CapsLock hotkey with IME active is to hold Shift and press CapsLock. In that case, CapsLock::Control changes the logical modifier state, so it is understandable that the system gets confused and will not "release" CapsLock.

Re: Ctrl gets stuck when IME on

Posted: 02 Jun 2020, 21:31
by quyleanh
lexikos wrote:
24 May 2020, 01:01
I don't understand how you're even using CapsLock. With Microsoft IME on my Windows 10 system, CapsLock is not even recognizable as CapsLock. The only way I can trigger a CapsLock hotkey with IME active is to hold Shift and press CapsLock. In that case, CapsLock::Control changes the logical modifier state, so it is understandable that the system gets confused and will not "release" CapsLock.
You didn't read and reprocedure whole first post, dit you? We don't mention to using CapsLock key.
The problem is when you map Ctrl to Capslock, and you use Capslock + C key to copy in IME, the Ctrl signal is not released. Then if you press S in notepad, the save dialog will appear.
Please refer to this https://www.autohotkey.com/boards/viewtopic.php?f=14&t=76771

Re: Ctrl gets stuck when IME on

Posted: 03 Jun 2020, 03:52
by lexikos
@quyleanh, are you Aupperle? Why did you start a second topic for the same issue?

"I have a script that remaps Caps Lock to Ctrl" -> Clearly this is for using CapsLock as Ctrl.
"pressing Caps Lock" -> "Pressing" is a way of "using".
"I use Caps Lock as my only Ctrl key" -> How is not using CapsLock when you use Caps Lock?
"The problem is when [...] you use Capslock"

Clearly, "we" mentioned using CapsLock key.


If I use the script CapsLock::Ctrl, it does absolutely nothing when I'm using Japanese IME.

When I'm using Japanese IME, pressing the key on my keyboard that says "Caps Lock"...
  • Toggles between kana and alphanumeric modes.
  • Does not toggle Caps Lock mode.
  • Does not trigger the remapping (Ctrl is not sent).
  • Does not trigger the hotkey *CapsLock::.
  • Does not cause "CapsLock" to appear in KeyHistory, only "not found".
When I'm using Japanese IME, it is like my CapsLock key ceases to exist and something else takes its place. It behaves as I explained in the topic Names for Japanese special keys.

Re: Ctrl gets stuck when IME on

Posted: 03 Jun 2020, 04:26
by quyleanh
@lexikos No, I am not Aupperle. The newest topic is made before I find this topic.
Sorry for not read carefully and thank you for your kind explanation.
Actually it's a bit hard for a beginner like me to follow your post in Names for Japanese special keys topic (I have read), but could you please summarize a conclusion for that?
Thank you very much.

Re: Ctrl gets stuck when IME on

Posted: 04 Jun 2020, 02:34
by lexikos
To summarize,
1) Japanese IME on Windows 10 does "special things" with CapsLock. You may consider it incompatible with AutoHotkey for this key.
2) I do not understand the "Ctrl sticks down" problem because CapsLock does not cause Ctrl to be sent in the first place on my system.

Re: Ctrl gets stuck when IME on

Posted: 04 Jun 2020, 21:08
by quyleanh
lexikos wrote:
04 Jun 2020, 02:34
To summarize,
1) Japanese IME on Windows 10 does "special things" with CapsLock. You may consider it incompatible with AutoHotkey for this key.
2) I do not understand the "Ctrl sticks down" problem because CapsLock does not cause Ctrl to be sent in the first place on my system.
So there is only solution is I have to use ad hoc solution in this post?
I have already added an issue on PowerToys Github repo. Hope Microsoft can fix this.
Thank you for your kind support.

Re: Ctrl gets stuck when IME on

Posted: 06 Jun 2020, 19:30
by lexikos
I worked out why I was seeing different behaviour to everyone else:
I currently have the hardware keyboard layout set to "Japanese keyboard (106/109) key", but my actual keyboard is an ordinary US keyboard.
I hadn't tried changing it because:
(Changing the setting requires a reboot.)
I have changed it to "English keyboard (101/102 key)" and can now reproduce the issue.

The workaround presented by Microsoft does not work, for the reasons I described on GitHub. However, it's only because they're sending the wrong key. Use this with AutoHotkey v1.1.26 or later:

Code: Select all

*CapsLock::
    Send {Blind}{LCtrl DownR}
    ; Send a suppressed LCtrl-up to fool the IME.
    SendSuppressedKeyUp("LCtrl")
    return
*CapsLock up::
    Send {Blind}{LCtrl Up}
    return

SendSuppressedKeyUp(key) {
    ; AutoHotkey v1.1.26+ uses this arbitrary value to signal its own hook
    ; to suppress the event.  This exists because the technique of sending
    ; and suppressing a key is already used to prevent Alt from activating
    ; the window menu in some specific cases.
    static KEY_BLOCK_THIS := 0xFFC3D450
    DllCall("keybd_event"
        , "char", GetKeyVK(key)
        , "char", GetKeySC(key)
        , "uint", 0x2
        , "uptr", KEY_BLOCK_THIS)
}
I'm not sure whether it is appropriate to add a built-in workaround, or how that would be done. If someone uses Tab::Ctrl, for instance, it would be legitimate to expect Tab+CapsLock to change the IME mode, and therefore inappropriate for AutoHotkey to fool the IME into thinking Ctrl isn't down.

Re: Ctrl gets stuck when IME on

Posted: 25 Sep 2020, 22:01
by ritsu
@lexikos
Thanks for the suppressed key workaround. However, when I try it on my system, it also seems to fool the OS into thinking the Ctrl key has been released, so combos like Ctrl-A, etc. no longer work. Is that intended, or am I missing something? Is there a solution that allows the remapped CapsLock key to still work with other key combinations while in Japanese IME?

Edit:
I checked GetKeyState("LCtrl") before and after the call to SendSuppressedKeyUp("LCtrl"), and it appears to be set to 1 before the call and 0 after the call.
If I understand the intent of the fix, GetKeyState("LCtrl") is supposed to still be 1 after the call to SendSuppressedKeyUp("LCtrl"), is that correct?

Code: Select all

*CapsLock::
    Send {Blind}{LCtrl DownR}
    CtrlState := GetKeyState("LCtrl")   ; 1
    Tooltip %CtrlState%, 100, 30, 1
    
    SendSuppressedKeyUp("LCtrl")
    CtrlState := GetKeyState("LCtrl")   ; 0
    Tooltip %CtrlState%, 100, 60, 2
    return
As an aside, I also noticed *CapsLock:: was being repeatedly called while holding down the CapsLock key. Not sure if that would cause issues. I tried adding a state flag to disable the repeated calls, but that didn't seem to make any difference.

Re: Ctrl gets stuck when IME on

Posted: 28 Sep 2020, 03:14
by lexikos
That would mean the event is not being suppressed. The event generated by the code I posted should always be suppressed if there is an instance of AutoHotkey v1.1.26 or later running with a keyboard hook installed.

Re: Ctrl gets stuck when IME on

Posted: 28 Sep 2020, 09:31
by ritsu
Ah, I'm an idiot. I was using an older version of Autohotkey. Updated to the latest version, and it's working now. Sorry about that.

By the way, I don't know if it's undesirable to have repeated calls to *CapsLock:: (and subsequently sending the suppressed key event repeatedly) while holding down the CapsLock key. But in case it is, I replaced *CapsLock up:: with KeyWait, CapsLock inside *CapsLock::, as in the following:

Code: Select all

; *CapsLock up::   ; No longer need this

*CapsLock::
    Send {Blind}{LCtrl DownR}
    SendSuppressedKeyUp("LCtrl")
    KeyWait, CapsLock
    Send {Blind}{LCtrl Up}
    return
This avoids the repeated calls to *CapsLock:: when the key is held down.