Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug] Can't map <capslock> #40

Open
mrjackphil opened this issue Nov 12, 2021 · 14 comments
Open

[Bug] Can't map <capslock> #40

mrjackphil opened this issue Nov 12, 2021 · 14 comments
Labels
accepted Requirement understood and waiting implementation. bug Something isn't working help wanted Extra attention is needed

Comments

@mrjackphil
Copy link

Describe the bug
As an example, I'm trying to remap <capslock> by doing:

imap <capslock> <f15>
inoremap <f15> to_edi_normal

Also, I tried to remap <capslock> in other modes without success:

gnnoremap <capslock> j

I can remap all other keys except capslock.

Environment (please complete the following information):

  • Windows 11 Home Single Language
  • OS Type: 64bit
  • OS Version: 21H2
  • OS Build: 21H2
  • win-vind Version: 4.2.1
  • win-vind Type: installer
  • Is it reproducible?: Yes
@pit-ray
Copy link
Owner

pit-ray commented Nov 12, 2021

Thanks for using it.

I have not been able to reproduce it. However, I am using a multi-language IME, so the keycode of <capslock> recognized by Windows may be different from the single language.

I will first build a single language environment and try it. Please wait for a while.

@pit-ray
Copy link
Owner

pit-ray commented Nov 17, 2021

I have installed and tested Windows 10 Home Single Language 21H1 Build19043.1348 and found the same behavior. I will now work on fixing the bug.

Thanks for the report.

@pit-ray pit-ray added the bug Something isn't working label Nov 17, 2021
@pit-ray
Copy link
Owner

pit-ray commented Nov 20, 2021

Hi.

I found the factor of the problem, but I didn't know its solution.

In Windows10, if absorb the input message of some toggle keys (e.g. <CapsLock>, <Kana>) to low-level, these state is always pressing. Thus, win-vind periodically releases the state of such toggle keys with SendInput function (https://github.com/pit-ray/win-vind/blob/master/src/core/key_absorber.cpp#L197-L219). However, in Single Language Edition, the key-up message via SendInput does not seem to work and it was left pressed. Therefore, it seems that it cannot be remapped. This can be reproduced visually by writing like imap <CapsLock> a.

This is due to the API not working, so I don't know the solution. If there is an open-source remapping tool that can handle CapsLock, let me know. I will refer them for a solution.

Thanks.

@pit-ray pit-ray added the help wanted Extra attention is needed label Nov 20, 2021
@pit-ray pit-ray pinned this issue Nov 20, 2021
pit-ray added a commit that referenced this issue Dec 4, 2021
@canelhasmateus
Copy link

I've seen to have hit a similar issue.
Currently trying to map AltGr + ' as a to_command. It works, but when i come back, windows seems to think that AltGr is in KeyDown position.

In regards to refering to another solution: Maybe AutoHotkeys can shed a light in this? I use it to implement Extend-Layer, as seen in https://dreymar.colemak.org/.

That means that my pressing my caps-lock key acts just as another keyboard layer. It works pretty well. Maybe you could refer to othem? Attached, the piece of AHK code that enables the caps-lock remapping.

image

@pit-ray
Copy link
Owner

pit-ray commented Apr 5, 2022

Thanks for sponsoring and information.

Is the problem with AltGr, in Single Language Edition? Otherwise, AltGr may be caused by another fact that AltGr is LCtrl + RAlt compound key code internally.

I am not familiar with extend-layer, in other words, AHK can disable the original function of CapsLock with SetCapsLockState, AlwaysOff even if Single Language Edition? If so, I'll refer SetCapsLockState implementation.

Thanks.

@canelhasmateus
Copy link

canelhasmateus commented Apr 5, 2022

I am not sure if it would work in the single-language edition: i wasn't even aware it existed until now.
I believe i do not use the single language edition. How could i confirm?

exploring further : this "AltGr stuck" Doesn't happen in every mode transition, strangely.
Those are the keybinds i'm using to test. Mind that ralt here is representing the AltGr key. I also tried doing <ralt-rctrl-*> but that didn't trigger.

inoremap <ralt-'> to_gui_normal
inoremap <ralt-v> to_gui_visual
gnnoremap <ralt-esc> to_insert
gnnoremap <esc> to_insert

In more details:

going from insert_mode to gui_normal , using AltGr + ' ; then immediately < esc > to come back to insert_mode triggers the problem: Some applications start to dispatch the commands as if i was holding the alt key. Pressing AltGr takes us back to normal functionality. I will call this condition as "stuck" from now on.

What i tested was: doing commands while in stuck mode.
Doing this inside sublime text meant that pressing the up and down keys triggered the alt+up and alt+down commands.
Doing this inside vscode meant that pressing the up and down keys did not trigger the alt up and alt down commands, just up and down.
This is probably due to differences on how each program handles its modifiers.

To further explore, i turned on the trace-level logging on vscode, to inspect what he was dispatching on , as well as the screencast mode. On a side screen, i turned KeyboardStateViewer on.

While in stuck mode, doing the following keystrokes result in the following actions :

Keystroke Vscode Log Vscode Screencast KeyState Viewer
UP Up Key Up Key Up Key
Alt + UP Up alt + Up alt + up
Ctrl + UP Up Ctrl + UP Ctrl + UP
Shift + UP Shift + UP Shift + up Shift + UP

From this point of view, it looks like the problem is the way programs handle the KeyDown -> Key Up transition. However, and this is the place where i got very confused.

going from insert_mode to visual, using AltGr + v ; then immediately < esc > to come back to insert_mode does not trigger stuck mode.

Some other observations:

I also have other altgr shortcuts mapped by autohotkeys ( switches desktops, for example ), and they don't trigger stuck mode either. From my testing, this is because autohotkeys stops the propagation of key-events as soon as it hits a mapped shortcut, while you seen to only stop propagating after. That is:

Keypress Win-Vind VSCode Screencast AHK VSCode Screencast
AltGr < no match > Alt < no match > Alt
AltGr + ' < Match to_gui > Alt + ' < match > Alt

( While testing these out, i found a similar bug in autohotkeys. Won't post now because this post is already long enough. We can discuss it below, if you want to. )

Pressing altgr + esc to exit insert mode works as a way of preventing stuck mode from happening. This is likely due to the ergonomics: when pressing altgr i most likely do the sequence altgr down -> esc down -> esc up -> altgr up. If this is the case , altgr down -> esc down -> esc up would come back to insert_mode, allowing the active window to just receive altgr up, ending stuck mode ( just like pressing altgr does ).

TLDR:

  • Not sure what my windows edition is
  • Stuck happens while transitioning between some modes, but not all.
  • Autohotkeys seems to handle things different.

@pit-ray
Copy link
Owner

pit-ray commented Apr 12, 2022

Sorry for my late reply.

As discussed above, I assume that imap <CapsLock> does not work well because of the differences in the API specification for the Single Language Edition.

If you are using the Single Language Edition, it will be shown as such in the log files.
If win-vind is not a portable, there are in ~/.win-vind/log.

Like this.

========== System Infomation ==========
[Windows]
      Edition: Windows 10 Home Single Language
      Version: 21H2
Build Numbers: 10.0.19044
 Architecture: x64

[win-vind]
      Version: 4.3.3
=======================================

I am trying to reproduce what you call AltGr stuck. I will let you know when I can confirm it.

Just to be sure, is your keyboard French or something else?

Thanks for your contribution.

@canelhasmateus
Copy link

After verifying, i do not use the single language edition.
My physical keyboard uses US QWERTY.
My Layout is usually configured as Portuguese ABNT 2 , or as Standard Colemak.
I have tested this interaction only on the abnt layout ( '0409:00010416' as in the Get-WinUserLanguageList InputMethodTips )

@pukkancsanyo
Copy link

Hi,

Probably just a small addition, but I'm having the same issue, although I'm not on a single-language edition.
I'm copying the log file below. I'm on a Hungarian system with Hungarian keyboard layout.

On a side note, I also tried to remap jk to to_edi_normal, and it kind of worked, but the problem was that it also wrote out the two characters. The same happened with Tab: pressing it caused the program to go to normal mode, but it also meant that the system reacted as if I wanted to press Tab.

I tried to swap CapsLock and Insert with PowerToys, but to no avail.

As a temporary solution, Insert without remapping seems to work now, but it is, of course, less comfy.

By the way, the log also shows a different kind of problem; there seems to be a bug with switch character case in my system.

========== System Infomation ==========
[Windows]
Edition: Windows 10 Home
Version: 21H2
Build Numbers: 10.0.19044
Architecture: x64

[win-vind]
Version: 4.3.3

[Message] E: Not a command

[Error] switch_char_case failed. An runtime exception occurred from bool __cdecl vind::bind::SmartClipboard::get_as_str(class std::basic_string<char,struct std::char_traits,class std::allocator > &). the current clipboard data is not supported unicode (void __cdecl vind::bind::BindedFunc::error_process(const class std::exception &) const)

[Error] switch_char_case failed. An runtime exception occurred from bool __cdecl vind::bind::SmartClipboard::get_as_str(class std::basic_string<char,struct std::char_traits,class std::allocator > &). the current clipboard data is not supported unicode (void __cdecl vind::bind::BindedFunc::error_process(const class std::exception &) const)

@pit-ray
Copy link
Owner

pit-ray commented Apr 17, 2022

@canelhasmateus
Hi. I was able to reproduce AltGr Stuck.
This happens with noremap mapping using <ralt> regardless of system language or keyboard layout.

Key states observed from win-vind

I inserted code in the source code of win-vind to check the status of the key code, and after rebuilding, I did the following mapping.

inoremap <ralt> to_gui_normal

At that time, I found that win-vind recognizes <alt> and <ralt> keys and sends key-up messages with SendInput function to release <alt> and <ralt> just before transitioning to GUI Normal. Thus, it may be the same problem in Single Lang Edition where the SendInput function for CapsLock does not work.

win-vind does not stop key propagation?

Internally, win-vind performs three types of mapping.
ref. https://pit-ray.github.io/win-vind/usage/#3-customize-win-vind

  • {mode}noremap {in-cmd} {out-cmd}
    It is performed after key input is recognized. Thus, if noremap is used in insert mode, the triggering key is propagated to other applications.

  • {mode}map {in-cmd} {out-cmd}
    It recognizes the command matching with {in-cmd} and then generates commands for {out-cmd}. The triggering {in-cmd} and generated {out-cmd} commands are propagated to other applications.
    For example, imap ab <ctrl-s>.

  • {mode}map {in-key} {out-keyset}
    If the trigger is a standalone key and the output is key or keyset, the mapping is done without propagating the trigger to other applications.
    For example, in imap a <shift-b>, a is not propagated to other applications.

In the specification, noremap is for internal mapping and map is for external mapping, so the former does not result in a recursive mapping, the latter may result in a recursive mapping.

Solution for mapping AltGr

{mode}map {in-key} {out-keyset} can be used to disable the trigger message. If you won't use AltGr's original feature, the following mapping works.

imap <ralt> <f20>
inoremap <f20-'> to_gui_normal
gnnoremap <ralt-esc> to_insert
gnnoremap <esc> to_insert

Thanks.

@pit-ray
Copy link
Owner

pit-ray commented Apr 17, 2022

@pukkancsanyo
As mentioned above, mapping jk, etc. in inoremap will propagate to other applications.

About the log, it seems that switch_char_case was used for an application where Unicode is not available, so the character could not be read. Various encodings can be supported with patches.

You seem to want to map something about Insert mode, can you be more specific?
Thanks.

@pukkancsanyo
Copy link

@pit-ray
OK, thanks, I see now why jk cannot work for going back to normal mode. Switch_char_case does not work in other applications, either, but maybe it is because the Hungarian layout I use (~ can only be typed with AltGr).

Sorry if I was not specific enough with the core of my comment. I wanted to map CapsLock as an alternative way to have to_edi_normal when I am in Insert mode (Esc + arrows feel a bit unergonomic for me on my keyboard). I wanted to apply something that was mentioned in the original comment:

imap
inoremap to_edi_normal

However, it does not seem to work; it is as if CapsLock were not be pressed at all, and I cant switch back to edi_normal this way, although I am not on a single-language edition.

So I just wanted to added this observation of mine to the thread that maybe not only single-language editions are affected by this issue.

@pit-ray pit-ray added the accepted Requirement understood and waiting implementation. label Oct 1, 2022
@serranomorante
Copy link

My edition from win-vind logs says Edition: Windows 10 Pro and I'm also facing this issue.

@imshenwei
Copy link

On a side note, I also tried to remap jk to to_edi_normal, and it kind of worked, but the problem was that it also wrote out the two characters. The same happened with Tab: pressing it caused the program to go to normal mode, but it also meant that the system reacted as if I wanted to press Tab.

for 'jk', i use 'imap jk <to_edi_normal>hhxx' to

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
accepted Requirement understood and waiting implementation. bug Something isn't working help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

6 participants