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

[Question] Mapping Question. #154

Open
TaivasJumala opened this issue Apr 16, 2023 · 8 comments
Open

[Question] Mapping Question. #154

TaivasJumala opened this issue Apr 16, 2023 · 8 comments
Labels
question Further information is requested

Comments

@TaivasJumala
Copy link

Question
I use PowerToys' keyborad manager to switch with , so they change function with each.

Now that I try to use win-vind, what confused me is that I press in the keyboard to change mode at the same time the status of Capslock changed either. But when I press , it seems that it's not equiv ant to as what I set in PowerToys. Nothing changed.

Is it because win-vind listen to the low level of keyboard, but PowerToys done his job in a higher level?

@pit-ray
Copy link
Owner

pit-ray commented Apr 17, 2023

@TaivasJumala
Thanks for using it.

In win-vind, the low-level mapping performs when the external mapping is key-to-key or key-to-keyset.
This specification may be confusible but makes sense.

win-vind has two-type mappings internal and external.
The internal mapping can be defined with vim-like syntaxes, such as imap <capslock> <ctrl>, but the effects range within win-vind. In other words, this mapping is only a shortcut.
The external mapping can be defined with { and } braces, such as imap <capslock> {<ctrl>}. This mapping affects the other applications via keyboard emulation. In this case, it generates a real key message of <ctrl> if the <capslock> is pressed.

Since the low-level mapping connects to target keys without sending any messages for trigger-key pressing to other applications, so is always external mapping, which affects the other applications.

To perform low-level mapping, the mapping should be solved at one time.
The following examples work low-level.

imap <capslock> {<ctrl>}  " one to one
imap <capslock> {<ctrl-s>} " one to two

The next mapping generates key messages sequentially, not low-level.

imap <capslock> {<ctrl>abc}  " sequential output keys
imap <alt-h> {<ctrl>}  " sequential input keys

Therefore, if you call some function with low-level, you can use the next techniques.

imap <capslock> {<f20>}
imap <f20> <to_gui_normal>

This tips the capslock maps to the other key low-level at once, and the desired mapping is called with the mapped key.

I hope this is helpful.

@pit-ray pit-ray added the question Further information is requested label Apr 17, 2023
@TaivasJumala
Copy link
Author

TaivasJumala commented Apr 19, 2023

I tried your method, and imap <capslock> {<ctrl>} in README's .vindrc sample session, seems not work. There is nothing behaviors looks like a <ctrl> will do when I press Caps Lock from my observation.

More over, I found logs in my ~/.win-vind/log/*.log says:

========== System Infomation ==========
[Windows]
      Edition: Windows 10 Pro
      Version: 22H2
Build Numbers: 10.0.22621
 Architecture: x64

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

But I'm actually using Windows 11, I don't know if it's Microsoft's problem because they differ 11 with 10 by judging whether the Build Numbers is greater than 22000 or not in many places as I know.

And when I put my eye on <capslock> not working, this guy's comment jingled me that we may facing the same problem (We got same Edition: Windows 10 Pro).

#40 (comment)

@pit-ray
Copy link
Owner

pit-ray commented Apr 30, 2023

@TaivasJumala
I confirmed that win-vind works on Windows 10 Pro, Windows 10 Home, and Windows 11 upgraded from Windows 10 Home.
Hence, this problem may cause another factor rather than versions of OS/API.

For debugging, we should watch key message flags in the low-level hook.
Location:

LRESULT CALLBACK InputGate::hook_proc(int n_code, WPARAM w_param, LPARAM l_param) {
if(n_code < HC_ACTION) { //not processed
return CallNextHookEx(NULL, n_code, w_param, l_param) ;
}
auto& self = get_instance() ;
auto kbd = reinterpret_cast<KBDLLHOOKSTRUCT*>(l_param) ;
auto code = static_cast<unsigned char>(kbd->vkCode) ;
auto mode = get_global_mode() ;
if(!(kbd->flags & LLKHF_INJECTED)) {
// The message is not generated with SendInput.
auto state = !(w_param & KEYUP_MASK) ;
self.pimpl->lowlevel_state_[code] = state ;
self.pimpl->timestamps_[code] = std::chrono::system_clock::now() ;
core::KeyCode keycode(code) ;
if(auto repcode = keycode.to_representative()) {
if(self.map_syncstate(repcode, state, mode) \
|| self.map_syncstate(keycode, state, mode)) {
return 1 ;
}
self.pimpl->real_state_[repcode.to_code()] = state ;
self.pimpl->state_[repcode.to_code()] = state ;
}
else if(self.map_syncstate(keycode, state, mode)) {
return 1 ;
}
self.pimpl->real_state_[code] = state ;
self.pimpl->state_[code] = state ;
}
if(self.pimpl->port_state_[code] \
|| self.pimpl->identity_map_[static_cast<int>(mode)][code]) {
return CallNextHookEx(NULL, HC_ACTION, w_param, l_param) ;
}
if(self.pimpl->absorb_state_) {
return 1 ;
}
return CallNextHookEx(NULL, HC_ACTION, w_param, l_param) ;
}

Therefore, I plan to try to reproduce this issue in the same environment as yours, including even the build number.
Thanks.

@TaivasJumala
Copy link
Author

I would love to do so, to clarify, use as same environment as possible and not disturbed by other applications, I will reproduce it on Windows Sandbox.

winver

图片
It's a Windows 11 pro with build number 22621.1555 which is same with my real machine. The language here is Simplified Chinese.

  1. To reproduce exactly, I need a winget which is not in Windows Sandbox, so I followed this guide:
    install-winget-on-windows-sandbox, if not going to reproduce it in sandbox, it's not necessary.

  2. Then, I install PowerToys use:

winget install Microsoft.PowerToys --source winget
  1. and then remap keys using its keyboard manager function:
    图片

There is a wierd thing happened here. I use PowerToys to remap ESC and CapsLocks in my real Windows(who host Windows) too. When I try to select a key by press a physical key in my keboard and I press the physical ESC it detects that I input a ESC key. But when I press the physical CapsLock, it flash a CapsLocks too then it detects my pressing as ESC.
So, to reproduce, I'll kill my PowerToys in real machine.

  1. Install win-vind by winget:
winget install win-vind

A. PowerToys is now running(with keyboard manager enabled like what I set before) and win-vind is not running or in resident mode.

Because the PowerToys' Keyboard Manager, the physical ESC now work as CapsLock and physical CapsLock is ESC. I use notepad to test that it actually did its job (to let me type capitalized characters and do what ESC do).

B. Launch win-vind. (now both PowerToys and win-vind are working)

C. now I still have to use physical ESC to change win-vind's different mode. At the same time, because PowerToys, windows recognized a CapsLocks was pressed too. So every time I use ESC to change modes, status of CapsLock changed too. Meanwhile CapsLock done nothing. Neither work like ESC to change win-vind mode or change status of CapsLock.

"the status of CapsLock" which we can tell from the light on the physical CapsLock key, or type something to see if they are capitalized.

D.

imap <capslock> <esc>

This is not working whatever PowerToys is running.

imap <capslock> {<f20>}
imap <f20> <esc>

This trick don't works too. And when PowerToys is running, I can't change mode of win-vind with physical ESC.

@pit-ray
Copy link
Owner

pit-ray commented Apr 30, 2023

@TaivasJumala
Thanks for detailed enough procedures to reproduce.
I'll try as soon as possible.

@pit-ray
Copy link
Owner

pit-ray commented May 1, 2023

@TaivasJumala
I am still testing.
Howevere, the 5-D procedure only changes the recognitions of win-vind and is not reflected in Windows.
The correct way to do it is to put the following.

imap <capslock> {<esc>}    " sandwich in {} brackets

@Kayzels
Copy link

Kayzels commented Mar 5, 2024

Unfortunately, this doesn't seem to work.

Did you ever find a solution @TaivasJumala?

@TaivasJumala
Copy link
Author

@Kayzels
I complied this AutoHotkey Script to executable and added it to startup.
nocaoper/CapsLockCtrlEscape.ahk

Have NOT test it if ok as a workaround. If you have extra time, you may want to test it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

3 participants