diff --git a/docs/changelog.md b/docs/changelog.md index 74fdcff46..8dc5e3407 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -28,6 +28,7 @@ As features stabilize some brief notes about them will accumulate here. #### Fixed * Flush after replying to XTGETTCAP. [#1850](https://github.com/wez/wezterm/issues/1850) * macOS: CMD-. was treated as CTRL-ESC [#1867](https://github.com/wez/wezterm/issues/1867) +* macOS: CTRL-Backslash on German layouts was incorrect [#1891](https://github.com/wez/wezterm/issues/1891) * `nf-mdi-contacts` nerdfont symbol treated as zero-width [#1864](https://github.com/wez/wezterm/issues/1864) * X11/Wayland: CTRL-i, CTRL-j, CTRL-m misinterpreted as CTRL-Tab, CTRL-Enter, CTRL-Return [#1851](https://github.com/wez/wezterm/issues/1851) * Scrollbar stopped working after a lot of output scrolled outside of the scrollback limit. Thanks to [@davidrios](https://github.com/davidrios)! [#1866](https://github.com/wez/wezterm/pull/1866) diff --git a/wezterm-input-types/src/lib.rs b/wezterm-input-types/src/lib.rs index 5d753374e..b7554800e 100644 --- a/wezterm-input-types/src/lib.rs +++ b/wezterm-input-types/src/lib.rs @@ -1038,6 +1038,16 @@ fn normalize_shift(key: KeyCode, modifiers: Modifiers) -> (KeyCode, Modifiers) { } } +pub fn is_ascii_control(c: char) -> Option { + let c = c as u32; + if c < 0x20 { + let de_ctrl = ((c as u8) | 0x40) as char; + Some(de_ctrl.to_ascii_lowercase()) + } else { + None + } +} + fn normalize_ctrl(key: KeyCode, modifiers: Modifiers) -> (KeyCode, Modifiers) { if modifiers.contains(Modifiers::CTRL) { if let KeyCode::Char(c) = key { diff --git a/window/src/os/macos/window.rs b/window/src/os/macos/window.rs index 152397003..c3712050a 100644 --- a/window/src/os/macos/window.rs +++ b/window/src/os/macos/window.rs @@ -42,6 +42,7 @@ use std::rc::Rc; use std::str::FromStr; use std::time::Instant; use wezterm_font::FontConfiguration; +use wezterm_input_types::is_ascii_control; #[allow(non_upper_case_globals)] const NSViewLayerContentsPlacementTopLeft: NSInteger = 11; @@ -2159,11 +2160,6 @@ impl WindowView { let array: id = msg_send![class!(NSArray), arrayWithObject: nsevent]; let _: () = msg_send![this, interpretKeyEvents: array]; - /* - let input_context: id = msg_send![this, inputContext]; - let res: BOOL = msg_send![input_context, handleEvent: nsevent]; - if res == YES { - */ if let Some(myself) = Self::get_this(this) { let mut inner = myself.inner.borrow_mut(); log::trace!( @@ -2276,8 +2272,16 @@ impl WindowView { let raw = key_string_to_key_code(unmod); match (&key, &raw) { // Avoid eg: \x01 when we can use CTRL-A. - // This also helps to keep the correct sequence for backspace/delete - (KeyCode::Char(c), Some(raw)) if c.is_ascii_control() => (raw.clone(), None), + // This also helps to keep the correct sequence for backspace/delete. + // But take care: on German layouts CTRL-Backslash has unmod="/" + // but chars="\x1c"; we only want to do this transformation when + // chars and unmod have that base ASCII relationship. + // + (KeyCode::Char(c), Some(KeyCode::Char(raw))) + if is_ascii_control(*c) == Some(raw.to_ascii_lowercase()) => + { + (KeyCode::Char(*raw), None) + } _ => (key, raw), } };