wezterm
wezterm copied to clipboard
Non-standard modifier keys emit original ANSI characters for that key on keydown
What Operating System(s) are you seeing this problem on?
Linux Wayland
Which Wayland compositor or X11 Window manager(s) are you using?
Mutter
WezTerm version
20240205-070437-39d2b6ca
Did you try the latest nightly build to see if the issue is better (or worse!) than your current version?
Yes, and I updated the version box above to show the version of the nightly that I tried
Describe the bug
My keyboard layout uses non-standard keys as modifiers to add additional layers. For example, if I press Mod3 + m, a % will be inserted. Mod3 is a modifier, comparable to the shift keys. Mod3 is mapped to the keys that are normally Caps Lock (Mod3 Left) or the | \ key (Mod3 Right) on an ANSI QWERTY layout (' # on my German keyboard), Mod4 is mapped to < > | (Mod4 left; no ANSI QWERTY equivalent for key) and right alt (Mod4 right).
If I press a modifier that is on a key that would normally result in a character being inserted (such as | \ for Mod3, but not Caps Lock), wezterm will insert a single character corresponding to the “original” character that would be on that key for ANSI QWERTY. For example, if I press Mod3 Right + m to insert a %, wezterm will insert a \%. So the modifiers work, but an additional character is inserted once upon keydown of the modifier key. If I simultaneously press the shift key, | will be inserted instead of \.
This problem first occurred for me for 20240203-110809-5046fc22, it is not present for 20240128-202157-1e552d76. It happens for the native package (Arch Linux/pacman), AppImage and flatpak.
To Reproduce
Activate keyboard layout with modifier keys on keys that normally print characters (such as Neo or NeoQwertz), start wezterm, press key combination such as Mod3 + m, with Mod3 corresponding to the \ | key. On keydown of the modifier key, the original character on that key will be inserted.
Configuration
no config
Expected Behavior
No characters should be inserted when pressing the modifier keys on their own.
Logs
No response
Anything else?
No response
Please collect some debug info for me by launching wezterm like this, and then pressing the problematic key sequence(s):
WEZTERM_LOG=window::os::x11::keyboard=trace,info wezterm -n --config debug_key_events=true
Pressing Mod3 Right + m, resulting in \% instead of %:
17:25:43.304 INFO wezterm_gui::termwindow > DeadKeyStatus now: None
17:25:43.318 INFO wezterm_gui::termwindow > DeadKeyStatus now: None
17:25:47.308 INFO wezterm_gui::termwindow::keyevent > key_event RawKeyEvent { key: Physical(Backslash), modifiers: NONE, leds: (empty), phys_code: Some(Backslash), raw_code: 51, repeat_count: 1, key_is_down: true, handled: Handled(false) }
17:25:47.309 TRACE window::os::x11::keyboard > Compose::feed(fallback) XK_backslash -> result=Accepted status=Nothing
17:25:47.309 TRACE window::os::x11::keyboard > Compose::feed(selected) XK_ISO_Level3_Shift -> result=Ignored status=Nothing
17:25:47.309 TRACE window::os::x11::keyboard > process_key_event: RawKeyEvent FeedResult::Nothing: "", XK_ISO_Level3_Shift. kc -> None fallback_feed=Nothing("\\", XK_backslash)
17:25:47.309 TRACE window::os::x11::keyboard > process_key_event: RawKeyEvent using fallback sym XK_backslash because layout did not expand to anything
17:25:47.309 INFO wezterm_gui::termwindow::keyevent > key_event KeyEvent { key: Char('\\'), modifiers: NONE, leds: (empty), repeat_count: 1, key_is_down: true, raw: Some(RawKeyEvent { key: Physical(Backslash), modifiers: NONE, leds: (empty), phys_code: Some(Backslash), raw_code: 51, repeat_count: 1, key_is_down: true, handled: Handled(false) }) }
17:25:47.309 INFO wezterm_gui::termwindow::keyevent > send to pane DOWN key=Char('\\') mods=NONE
17:25:47.309 INFO wezterm_term::terminalstate::keyboard > key_down: sending "\\", Char('\\') NONE
17:25:47.315 INFO wezterm_gui::termwindow > DeadKeyStatus now: None
17:25:47.661 INFO wezterm_gui::termwindow::keyevent > key_event RawKeyEvent { key: Physical(M), modifiers: NONE, leds: (empty), phys_code: Some(M), raw_code: 58, repeat_count: 1, key_is_down: true, handled: Handled(false) }
17:25:47.661 TRACE window::os::x11::keyboard > Compose::feed(fallback) XK_m -> result=Accepted status=Nothing
17:25:47.661 TRACE window::os::x11::keyboard > Compose::feed(selected) XK_percent -> result=Accepted status=Nothing
17:25:47.661 TRACE window::os::x11::keyboard > process_key_event: RawKeyEvent FeedResult::Nothing: "%", XK_percent. kc -> Some(Char('%')) fallback_feed=Nothing("m", XK_m)
17:25:47.661 INFO wezterm_gui::termwindow::keyevent > key_event KeyEvent { key: Char('%'), modifiers: NONE, leds: (empty), repeat_count: 1, key_is_down: true, raw: Some(RawKeyEvent { key: Physical(M), modifiers: NONE, leds: (empty), phys_code: Some(M), raw_code: 58, repeat_count: 1, key_is_down: true, handled: Handled(false) }) }
17:25:47.661 INFO wezterm_gui::termwindow::keyevent > send to pane DOWN key=Char('%') mods=NONE
17:25:47.661 INFO wezterm_term::terminalstate::keyboard > key_down: sending "%", Char('%') NONE
17:25:47.666 INFO wezterm_gui::termwindow > DeadKeyStatus now: None
17:25:47.740 INFO wezterm_gui::termwindow::keyevent > key_event KeyEvent { key: Char('%'), modifiers: NONE, leds: (empty), repeat_count: 1, key_is_down: false, raw: Some(RawKeyEvent { key: Physical(M), modifiers: NONE, leds: (empty), phys_code: Some(M), raw_code: 58, repeat_count: 1, key_is_down: false, handled: Handled(false) }) }
17:25:47.740 INFO wezterm_gui::termwindow::keyevent > send to pane UP key=Char('%') mods=NONE
17:25:47.860 TRACE window::os::x11::keyboard > keysym_to_keycode for XK_ISO_Level3_Shift and XK_ISO_Level3_Shift -> None
Pressing Mod4 Left + m, resulting in <1 instead of 1:
17:28:48.376 INFO wezterm_gui::termwindow > DeadKeyStatus now: None
17:28:48.390 INFO wezterm_gui::termwindow > DeadKeyStatus now: None
17:28:52.314 INFO wezterm_gui::termwindow::keyevent > key_event RawKeyEvent { key: RawCode(94), modifiers: NONE, leds: (empty), phys_code: None, raw_code: 94, repeat_count: 1, key_is_down: true, handled: Handled(false) }
17:28:52.315 TRACE window::os::x11::keyboard > Compose::feed(fallback) XK_less -> result=Accepted status=Nothing
17:28:52.315 TRACE window::os::x11::keyboard > Compose::feed(selected) XK_ISO_Level5_Shift -> result=Accepted status=Nothing
17:28:52.315 TRACE window::os::x11::keyboard > process_key_event: RawKeyEvent FeedResult::Nothing: "", XK_ISO_Level5_Shift. kc -> None fallback_feed=Nothing("<", XK_less)
17:28:52.315 TRACE window::os::x11::keyboard > process_key_event: RawKeyEvent using fallback sym XK_less because layout did not expand to anything
17:28:52.315 INFO wezterm_gui::termwindow::keyevent > key_event KeyEvent { key: Char('<'), modifiers: NONE, leds: (empty), repeat_count: 1, key_is_down: true, raw: Some(RawKeyEvent { key: RawCode(94), modifiers: NONE, leds: (empty), phys_code: None, raw_code: 94, repeat_count: 1, key_is_down: true, handled: Handled(false) }) }
17:28:52.315 INFO wezterm_gui::termwindow::keyevent > send to pane DOWN key=Char('<') mods=NONE
17:28:52.315 INFO wezterm_term::terminalstate::keyboard > key_down: sending "<", Char('<') NONE
17:28:52.320 INFO wezterm_gui::termwindow > DeadKeyStatus now: None
17:28:52.706 INFO wezterm_gui::termwindow::keyevent > key_event RawKeyEvent { key: Physical(M), modifiers: NONE, leds: (empty), phys_code: Some(M), raw_code: 58, repeat_count: 1, key_is_down: true, handled: Handled(false) }
17:28:52.706 TRACE window::os::x11::keyboard > Compose::feed(fallback) XK_m -> result=Accepted status=Nothing
17:28:52.706 TRACE window::os::x11::keyboard > Compose::feed(selected) XK_KP_1 -> result=Accepted status=Nothing
17:28:52.706 TRACE window::os::x11::keyboard > process_key_event: RawKeyEvent FeedResult::Nothing: "1", XK_KP_1. kc -> Some(Char('1')) fallback_feed=Nothing("m", XK_m)
17:28:52.706 INFO wezterm_gui::termwindow::keyevent > key_event KeyEvent { key: Char('1'), modifiers: NONE, leds: (empty), repeat_count: 1, key_is_down: true, raw: Some(RawKeyEvent { key: Physical(M), modifiers: NONE, leds: (empty), phys_code: Some(M), raw_code: 58, repeat_count: 1, key_is_down: true, handled: Handled(false) }) }
17:28:52.706 INFO wezterm_gui::termwindow::keyevent > send to pane DOWN key=Char('1') mods=NONE
17:28:52.706 INFO wezterm_term::terminalstate::keyboard > key_down: sending "1", Char('1') NONE
17:28:52.711 INFO wezterm_gui::termwindow > DeadKeyStatus now: None
17:28:52.793 INFO wezterm_gui::termwindow::keyevent > key_event KeyEvent { key: Char('1'), modifiers: NONE, leds: (empty), repeat_count: 1, key_is_down: false, raw: Some(RawKeyEvent { key: Physical(M), modifiers: NONE, leds: (empty), phys_code: Some(M), raw_code: 58, repeat_count: 1, key_is_down: false, handled: Handled(false) }) }
17:28:52.793 INFO wezterm_gui::termwindow::keyevent > send to pane UP key=Char('1') mods=NONE
17:28:52.953 TRACE window::os::x11::keyboard > keysym_to_keycode for XK_ISO_Level5_Lock and XK_ISO_Level5_Lock -> None
17:29:21.165 INFO wezterm_gui::termwindow > DeadKeyStatus now: None
I can confirm that I'm running into the same issue with wezterm 20240203-110809-5046fc22.
I downgraded wezterm to 20240128.202157.1e552d76-1 and with this version the issue is not present. So any of the change in the two releases introduced the regression.
Edit: scanning through the diff brought this block into my attention:
// Not sure if this is a good idea, see
// <https://github.com/wez/wezterm/issues/4910> for context.
match fallback_feed {
FeedResult::Nothing(_fb_utf8, fb_sym) => {
log::trace!(
"process_key_event: RawKeyEvent using fallback \
sym {fb_sym:?} because layout did not expand to \
anything"
);
fb_sym
}
_ => sym,
}
At first glance that seems to be related.
Confirmed. If I comment out the aforementioned block (see this comment), it works as before.
It looks like this also was a problem last summer (https://github.com/wez/wezterm/issues/3913). It got fixed there but I don't know if the cause of the problem is the same here.
@JakobSteinberg, do you know which commit fixed #3913? I couldn't find it right away and I was wondering if this commit could provide some insights that I can take into account for #4991.
@schrieveslaach sadly no. I am pretty new to wezterm and got the character printing issue after my last update, because I also use the bone layout, like https://github.com/wez/wezterm/issues/4978. https://github.com/wez/wezterm/issues/3913 was the first search result I found and it looked like it was the same problem, but I have no further information.
neo was broken by #4910. Reverting the commit there fixes the problem.
I can confirm that reverting #4910 fixes the problem for me.