Comments (21)
It's also worth mentioning that I use Alt Gr frequently when programming, and have not seen the same error in Ubuntu and NixOS (using kmonad). So my guess is that this is a Windows-only issue.
from kanata.
You r right ,same scancode. I found this link by tweaking registry. https://www.getdroidtips.com/remap-alt-gr-key-windows-10
from kanata.
@jtroo built and tested and it seems to work. Both new optional configurations avoids the hanging ctl for me. I think it's nice to keep both options, but I am using cancel-lctl-press
atm.
Thank you so much for fixing this, will "test-drive" this version for a few days to make sure everything is working smoothly.
from kanata.
I see, this goes deeper than I initially thought. Could not make it work with for other applications using the config above. The only solution I have is to disable handling of lctl and ralt in Kanata, as it is working properly without Kanata enabled. This is however not a major problem for me, as my setup does not need Kanata to handle / remap lctl and ralt.
Thank you so much for investigating this! Kanata is working great for me. You can close this issue and merge the pull request, the initial problem with hanging lctl is solved and working.
from kanata.
Thanks for filing the bug! I'll have to look into the specifics of the altgr key.
from kanata.
So according to this link on Windows, altgr is somehow mapped to ctl+alt which makes sense for what you're observing for the press. What I'm not sure about is why both don't get released when you release altgr. It's not clear to me if kanata is doing something wrong or the Windows event hook is. I'll try looking at other projects to see if they've encountered and solved this issue.
from kanata.
Thanks for looking into this!
Was using kmonad previously on my Linux machine, but Windows issues led me to kanata. Just testet the same config with kmonad, and it seems like it also suffers from the same issue. I then found kmonad/kmonad#530.
from kanata.
The problem is that Alt Gr is not defined in the kanata keycode. Although you put ralt in defrc, you are not pressing ralt. I believe Alt gr should be added as a key.
from kanata.
So it partly seems like this is a Windows problem. Even a project with waaaay more resources than kanata or kmonad is punting on this problem in some ways:
https://github.com/microsoft/PowerToys/issues?q=is%3Aissue+is%3Aopen+altgr
But it's worth thinking about ways to mitigate this.
@13minutes-yt from my understanding the USB scancode for ralt and altgr are actually the same. It's the OS keyboard configuration or maybe the locale that changes the behaviour. I could be wrong, but this is what I think based on what I've been reading up on.
from kanata.
Sidenote, I can remove every key in my config except lctl and the problem still perist. Which makes sense if AltGr is mapped to alt+ctl. Heres the minimal config:
(defcfg
)
(defsrc
lctl
)
(deflayer homerowmods
lctl
)
This results in the following when pressing AltGr:
20:34:23 [DEBUG] (1) kanata::kanata: event loop: KeyEvent { code: KEY_LEFTCTRL, value: Press }
20:34:23 [DEBUG] (2) kanata::kanata: press LCtrl
from kanata.
@storvik would you be able to build and test #65 to see if either of the new optional configurations are useful in fixing this issue?
My guess would be that something like the configuration below would be the most useful. This keeps the functionality of altgr
on tap but if double-tapped and held it can do something different.
(defcfg
windows-altgr cancel-lctl-press ;; remove the lctl press that comes as a combo with ralt
)
(defsrc
lctl ralt
)
(defalias
ralt (tap-dance (C-ralt (layer-toggle other_layer)))
)
(deflayer default_layer
lctl @ralt
)
(deflayer other_layer
XX XX
)
I think that windows-altgr add-lctl-release ;; add an lctl release when ralt is released
is not too helpful because the kanata interception for this mitigation happens for OS inputs as opposed to at the state machine level. This means that remapping lctl
to something else might break altgr
functionality.
I'm just guessing here though; I don't use a layout that makes use of altgr
.
from kanata.
@jtroo for some reason I am experiencing another issue with Windows, Alt Gr, GWSL and kanata. While everything related to Alt Gr seems to work fine in Windows now, I cannot get keys requiring Alt Gr to work in GWSL applications. For instance when I run Emacs from WSL I cannot input @{[]}$
. When closing Kanata they are working again. Verified this behavior in other applications too, so it's not Emacs specific.
from kanata.
What's the kanata configuration of ralt
? E.g. is it only sending ralt
due to cancel-lctl-press
or is it sending both ralt+lctl
? Do both optional configurations exhibit the same behaviour?
from kanata.
Seems like this issue is present in the main branch too, so it's probably not related to these changes. Both configurations causes the same behavior. It also seems like this issue is present in kmonad too.
If I remove both lctl and ralt from my config it works correctly, but if one of them is present programs running on xserver does not interpret Alt Gr as it should.
from kanata.
I wonder if GWSL is also using the low level keyboard hook that kanata is and kanata is somehow interfering with how GWSL operates.
I'll poke around that codebase and maybe file a ticket to see if they know anything.
from kanata.
That's possible. I think GWSL uses, or relies on, vcxsrv which seems to be a popular xserver for Windows. It's mentioned in the kmonad issue I sent above too. Please let me know if I can help with anything.
from kanata.
Reading through some source code in my lunch break, I've understood the following points:
vcxsrv
does indeed use the low level keyboard hook. It looks like it has flags to either disable or enable this, but my guess is that it's enabled in GWSL- On window focus, seems that
vcxsrv
registers itself as a hook handler and unregisters itself when it's no longer in focus
case WM_SETFOCUS:
...
if (g_fKeyboardHookLL)
g_fKeyboardHookLL = winInstallKeyboardHookLL();
return 0;
case WM_KILLFOCUS:
...
/* Remove our keyboard hook if it is installed */
winRemoveKeyboardHookLL();
return 0;
- According to Microsoft documentation, hooks will be put at the beginning of the chain when registered. So any keyboard input handling by
vcxsrv
will occur beforekanata
.
Reading the Microsoft documentation, it seems kanata is returning an incorrect value -1
instead of some positive non-zero (e.g. 1
) when other hooks should not process the event. I'm not sure if this is important to the problem though.
if handled {
-1
} else {
CallNextHookEx(ptr::null_mut(), code, wparam, lparam)
}
from kanata.
Interesting. I tried to edit the config file for GWSL. Adding the -nokeyhook
option to VcXsrv command did not make a difference.
Verified that new settings were picked up by VcXsrv by adding -swcursor
which changes the cursor in all x windows.
from kanata.
What GWSL configuration do you use? I've tried installing it to test myself but I'm not sure what to add to the configuration change the X apps to use an international layout.
from kanata.
Playing around with kanata some more and adding logging, I've found that there are some peculiarities with the values in the keyboard hook that differ between injected and non-injected events. The boolean at the end of the log messages states if the event is injected or not.
Logs when not intercepting:
05:13:24 [TRACE] (1) kanata::oskbd::windows: [src\oskbd\windows.rs:110] 0, 260, false
05:13:24 [TRACE] (1) kanata::oskbd::windows: [src\oskbd\windows.rs:110] 0, 260, false
05:13:24 [TRACE] (1) kanata::oskbd::windows: [src\oskbd\windows.rs:110] 0, 257, false
05:13:24 [TRACE] (1) kanata::oskbd::windows: [src\oskbd\windows.rs:110] 0, 257, false
Logs when intercepting lalt/lctl:
05:12:08 [TRACE] (1) kanata::oskbd::windows: [src\oskbd\windows.rs:110] 0, 260, false
05:12:08 [DEBUG] (1) kanata::kanata: event loop: KeyEvent { code: KEY_LEFTCTRL, value: Press }
05:12:08 [TRACE] (1) kanata::oskbd::windows: [src\oskbd\windows.rs:110] 0, 260, false
05:12:08 [DEBUG] (1) kanata::kanata: event loop: KeyEvent { code: KEY_RIGHTALT, value: Press }
05:12:08 [DEBUG] (2) kanata::kanata: press LCtrl
05:12:08 [TRACE] (1) kanata::oskbd::windows: [src\oskbd\windows.rs:110] 0, 256, true
05:12:08 [DEBUG] (2) kanata::kanata: press RAlt
05:12:08 [TRACE] (1) kanata::oskbd::windows: [src\oskbd\windows.rs:110] 0, 256, true
05:12:08 [TRACE] (1) kanata::oskbd::windows: [src\oskbd\windows.rs:110] 0, 257, false
05:12:08 [DEBUG] (1) kanata::kanata: event loop: KeyEvent { code: KEY_RIGHTALT, value: Release }
05:12:08 [DEBUG] (3) kanata::kanata: altgr add: adding lctl release
05:12:08 [DEBUG] (2) kanata::kanata: release RAlt
05:12:08 [TRACE] (1) kanata::oskbd::windows: [src\oskbd\windows.rs:110] 0, 257, true
05:12:08 [DEBUG] (2) kanata::kanata: release LCtrl
05:12:08 [TRACE] (1) kanata::oskbd::windows: [src\oskbd\windows.rs:110] 0, 257, true
It appears that Windows has a concept of SYSKEY_UP/DOWN when pressing specific buttons like Alt/RAlt. This might be the source of the weirdness with GWSL. It also reveals a bit about why the LCtrl release gets missed
However, I'm not sure how to fix the discrepancy. Looking at SendInput, there doesn't seem to be a way to simulate the SYSKEY
states. SendInput
can only differentiate between up
or down
.
from kanata.
Ah, so it seems that vcxsrv
is being extremely strict about checking for exactly the type of sequence that Windows generates so that it doesn't send lctl+ralt to the X application and instead only sends ralt.
Interestingly I found that sending only lalt
via ralt
to a GWSL xterm
instance makes AltGr work properly in an xterm GWSL window, but then it fails for Windows apps because Windows apps need alt+ctl to handle the AltGr layer. Not sure if this would work for other GWSL apps though.
E.g. with:
(defcfg
windows-altgr cancel-lctl-press ;; remove the lctl press that comes as a combo with ralt
)
(defsrc
1 lctl ralt del
)
(deflayer default
1 _ lalt lrld
)
Side note: in Windows you can actually use LAlt+LCtrl to achieve the same thing as AltGr as it turns out.
Unfortunately, I think fixing this issue for GWSL/vcxsrv will be quite the challenge so I'm not up to the task. This was an interesting investigation for sure though.
You could try this as a workaround for GWSL apps if you find that other apps are also fine with the weird ralt
->lalt
thing that I found xterm
was:
(defcfg
windows-altgr cancel-lctl-press ;; remove the lctl press that comes as a combo with ralt
)
(defsrc
1 lctl ralt del
)
(deflayer default
1 _ (tap-dance 200 (C-ralt lalt)) lrld ;; double-tap ralt for using it in GWSL apps
)
from kanata.
Related Issues (20)
- MacOS privilege violation error
- Feature request: intercept all mice in Wintercept build HOT 1
- defoverrides is ignored in unmod and unshift HOT 2
- Directional Keys Not Working in Windows Task View HOT 6
- Bug: Home row mods advanced issue with block-unmapped-keys HOT 3
- Bug: unable to globally swap caps and esc HOT 2
- Feature request: modular per-platform config.adoc HOT 9
- Feature request: togglable `caps-word` HOT 2
- Bug: In WSL space is inserted after shift or control when running kanata in host HOT 1
- Bug: windows iconbar icon isn't removed when app is killed HOT 1
- Bug: Dead keys cause keyboard modifier state to get corrupt - witnessed on colemak HOT 7
- Feature request: support platform-specific IPC which has greater convenience than TCP
- Feature request: Auto Mouse Keys layer HOT 2
- Feature request: support BSD HOT 5
- Unable to send key input due to key having not been physically released yet. HOT 3
- Bug: Release 1.6.1 macos_x86_64 executable isn't what it says. HOT 6
- Feature request: Show keystroke or can let other app know the real key is stroked. HOT 2
- Feature request: Can we have a more flexible unmod? HOT 1
- See if windows shift workaround can be compiled out for winiov2 HOT 1
- Bug: kanata does not work properly with listary HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from kanata.