wezterm icon indicating copy to clipboard operation
wezterm copied to clipboard

Non-standard modifier keys emit original ANSI characters for that key on keydown

Open op3 opened this issue 1 year ago • 5 comments

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

op3 avatar Feb 06 '24 14:02 op3

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

wez avatar Feb 06 '24 15:02 wez

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

op3 avatar Feb 06 '24 16:02 op3

I can confirm that I'm running into the same issue with wezterm 20240203-110809-5046fc22.

schrieveslaach avatar Feb 06 '24 20:02 schrieveslaach

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.

schrieveslaach avatar Feb 08 '24 06:02 schrieveslaach

Confirmed. If I comment out the aforementioned block (see this comment), it works as before.

schrieveslaach avatar Feb 08 '24 06:02 schrieveslaach

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 avatar Feb 28 '24 11:02 JakobSteinberg

@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 avatar Mar 01 '24 08:03 schrieveslaach

@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.

JakobSteinberg avatar Mar 01 '24 10:03 JakobSteinberg

neo was broken by #4910. Reverting the commit there fixes the problem.

Flakebi avatar Mar 27 '24 16:03 Flakebi

I can confirm that reverting #4910 fixes the problem for me.

stefanfrede avatar May 23 '24 06:05 stefanfrede