Skip to content

Commit

Permalink
x11/wayland: fix ctrl-key for latin layouts
Browse files Browse the repository at this point in the history
This is fixing a regression introduced by the fix for #2845.
The resolution for this is relatively straightforward, but took a bit
of effort to plumb.

Previously:
* CTRL/ALT/SUPER-modified keys with no explicit expansion would end
  up just taking the US layout version of the key.  That worked well
  for the intended problem with non-latin layouts, but for eg: German
  layouts it caused expansion to totally the wrong thing

Now:
* CTRL/ALT/SUPER-modified keys which effectively expand to non-ascii
  text (eg: cyrillic "Es") now take the equivalent key press from the
  US layout (which would be "c" in the "Es" case).  For European
  layouts this heuristic seems to avoid unexpected effects, but could
  do with some validation from native users.

To support this, the xkb code splits the `Keyboard` struct out from
some of the higher level logic and introduces a `KeyboardWithFallback`
struct that is built out of the user-selected keyboard layout, and
the fallback keyboard.  Now the fallback keyboard is fed the same
key inputs as the selected keyboard to correctly model the key
combinations.

refs: #3610
refs: #3933
  • Loading branch information
wez committed Jul 9, 2023
1 parent 1bfaf85 commit f09992f
Show file tree
Hide file tree
Showing 5 changed files with 271 additions and 154 deletions.
3 changes: 3 additions & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ As features stabilize some brief notes about them will accumulate here.

* Modals, such as `CharSelect` and `CommandPalette` did not respect alternative
OS-level key maps. #3470
* X11/Wayland: CTRL-key presses for non-US latin keymaps regressed due to
changes to [improve handling of CTRL-key presses for non-latin
layouts](https://github.com/wez/wezterm/issues/2845). #3610
* Numerous issues with the kitty keyboard protocol implementation #2546 #3220
#3315 #3473 #3474 #3476 #3478 #3479 #3484 #3526
* mux: Attempting to spawn into an ad-hoc SSH domain after the last tab could
Expand Down
6 changes: 3 additions & 3 deletions window/src/os/wayland/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use super::window::*;
use crate::connection::ConnectionOps;
use crate::os::wayland::inputhandler::InputHandler;
use crate::os::wayland::output::OutputHandler;
use crate::os::x11::keyboard::Keyboard;
use crate::os::x11::keyboard::KeyboardWithFallback;
use crate::screen::{ScreenInfo, Screens};
use crate::spawn::*;
use crate::{Appearance, Connection, ScreenRect, WindowEvent};
Expand Down Expand Up @@ -56,7 +56,7 @@ pub struct WaylandConnection {
// must be ahead of the rest.
pub(crate) gl_connection: RefCell<Option<Rc<crate::egl::GlConnection>>>,
pub(crate) pointer: RefCell<PointerDispatcher>,
pub(crate) keyboard_mapper: RefCell<Option<Keyboard>>,
pub(crate) keyboard_mapper: RefCell<Option<KeyboardWithFallback>>,
pub(crate) keyboard_window_id: RefCell<Option<usize>>,
pub(crate) surface_to_window_id: RefCell<HashMap<u32, usize>>,
pub(crate) active_surface_id: RefCell<u32>,
Expand Down Expand Up @@ -265,7 +265,7 @@ impl WaylandConnection {
data.pop();
}
let s = String::from_utf8(data)?;
match Keyboard::new_from_string(s) {
match KeyboardWithFallback::new_from_string(s) {
Ok(k) => {
self.keyboard_mapper.replace(Some(k));
}
Expand Down
4 changes: 2 additions & 2 deletions window/src/os/wayland/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use super::pointer::*;
use crate::connection::ConnectionOps;
use crate::os::wayland::connection::WaylandConnection;
use crate::os::wayland::wl_id;
use crate::os::x11::keyboard::Keyboard;
use crate::os::x11::keyboard::KeyboardWithFallback;
use crate::{
Appearance, Clipboard, Connection, Dimensions, MouseCursor, Point, Rect,
RequestedWindowGeometry, ResolvedGeometry, ScreenPoint, Window, WindowEvent, WindowEventSender,
Expand Down Expand Up @@ -484,7 +484,7 @@ impl WaylandWindowInner {
}
}

fn emit_focus(&mut self, mapper: &mut Keyboard, focused: bool) {
fn emit_focus(&mut self, mapper: &mut KeyboardWithFallback, focused: bool) {
// Clear the modifiers when we change focus, otherwise weird
// things can happen. For instance, if we lost focus because
// CTRL+SHIFT+N was pressed to spawn a new window, we'd be
Expand Down
5 changes: 3 additions & 2 deletions window/src/os/x11/connection.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use super::keyboard::Keyboard;
use super::keyboard::{Keyboard, KeyboardWithFallback};
use crate::connection::ConnectionOps;
use crate::os::x11::window::XWindowInner;
use crate::os::x11::xsettings::*;
Expand All @@ -25,7 +25,7 @@ pub struct XConnection {
pub(crate) xsettings: RefCell<XSettingsMap>,
pub screen_num: i32,
pub root: xcb::x::Window,
pub keyboard: Keyboard,
pub keyboard: KeyboardWithFallback,
pub kbd_ev: u8,
pub atom_protocols: Atom,
pub cursor_font_id: xcb::x::Font,
Expand Down Expand Up @@ -639,6 +639,7 @@ impl XConnection {
visual.blue_mask()
);
let (keyboard, kbd_ev) = Keyboard::new(&conn)?;
let keyboard = KeyboardWithFallback::new(keyboard)?;

let cursor_font_id = conn.generate_id();
let cursor_font_name = "cursor";
Expand Down
Loading

0 comments on commit f09992f

Please sign in to comment.