diff --git a/config/src/config.rs b/config/src/config.rs index aaf44bf8a..1344d9672 100644 --- a/config/src/config.rs +++ b/config/src/config.rs @@ -657,6 +657,8 @@ pub struct Config { #[dynamic(default = "default_true")] pub use_ime: bool, + #[dynamic(default = "default_true")] + pub x11_use_passive_key_updates: bool, #[dynamic(default)] pub xim_im_name: Option, #[dynamic(default)] diff --git a/window/src/os/x11/keyboard.rs b/window/src/os/x11/keyboard.rs index 678204363..59c0a610d 100644 --- a/window/src/os/x11/keyboard.rs +++ b/window/src/os/x11/keyboard.rs @@ -12,6 +12,7 @@ use std::os::unix::ffi::OsStrExt; use wezterm_input_types::{KeyboardLedStatus, PhysKeyCode}; use xkb::compose::Status as ComposeStatus; use xkbcommon::xkb; +use xkbcommon::xkb::KeyDirection; pub struct Keyboard { context: xkb::Context, @@ -223,6 +224,12 @@ impl KeyboardWithFallback { events: &mut WindowEventSender, want_repeat: bool, ) -> Option { + let x11_use_passive_key_updates = config::configuration().x11_use_passive_key_updates; + + if !x11_use_passive_key_updates { + self.update_key(xcode, pressed); + } + let phys_code = self.selected.phys_code_map.borrow().get(&xcode).copied(); let modifiers_from_state = self.get_key_modifiers(); @@ -235,7 +242,7 @@ impl KeyboardWithFallback { // This also happens intermittently for wez on an Ubuntu system where // the XServer clears the mask state seemingly at the wrong time via // a call into process_xkb_event that zeroes out all the modifier states. - let raw_modifiers = if modifiers_from_state.is_empty() { + let raw_modifiers = if modifiers_from_state.is_empty() && x11_use_passive_key_updates { modifiers_from_event } else { modifiers_from_state @@ -454,7 +461,9 @@ impl KeyboardWithFallback { match event { xcb::Event::Xkb(xcb::xkb::Event::StateNotify(e)) => { - self.update_state(e); + if config::configuration().x11_use_passive_key_updates { + self.update_state(e); + } } xcb::Event::Xkb( xcb::xkb::Event::MapNotify(_) | xcb::xkb::Event::NewKeyboardNotify(_), @@ -486,6 +495,15 @@ impl KeyboardWithFallback { .update_modifier_state(mods_depressed, mods_latched, mods_locked, group); } + /// Use either this method OR update_state, not both! + pub fn update_key(&self, xcode: xkb::Keycode, pressed: bool) { + self.selected.update_key(xcode, pressed); + self.fallback.update_key(xcode, pressed); + } + + /// Use either this method OR update_key, not both! + /// Per + /// you MUST call this method on Wayland. pub fn update_state(&self, ev: &xcb::xkb::StateNotifyEvent) { self.selected.update_state(ev); self.fallback.update_state(ev); @@ -664,6 +682,17 @@ impl Keyboard { ); } + pub fn update_key(&self, xcode: xkb::Keycode, pressed: bool) { + self.state.borrow_mut().update_key( + xcode, + if pressed { + KeyDirection::Down + } else { + KeyDirection::Up + }, + ); + } + pub fn update_state(&self, ev: &xcb::xkb::StateNotifyEvent) { self.state.borrow_mut().update_mask( xkb::ModMask::from(ev.base_mods().bits()),