1
1
mirror of https://github.com/wez/wezterm.git synced 2024-12-23 13:21:38 +03:00

x11: add experimental x11_use_passive_key_updates config option

In discussion about the ongoing weirdness with modifier processing,
it sounds like we could/should be using `update_key` rather than
`update_mask` under X11.  (Wayland: has to use `update_mask`,
per the docs:
https://docs.rs/xkbcommon/latest/xkbcommon/xkb/struct.State.html#method.update_key)

I quickly tried out a proof of concept with this and it
doesn't seem to hurt, but since I'm unsure if there are other
nuances to consider, I've put this behind a config option.

`x11_use_passive_key_updates` defaults to true which results
in the use of `update_mask` on X11.

Setting it to false will switch to using `update_key` instead,
and may improve handling of xkb states.

refs: https://github.com/wez/wezterm/issues/4841
refs: https://github.com/ibus/ibus/issues/2600
refs: https://github.com/wez/wezterm/pull/4151
This commit is contained in:
Wez Furlong 2024-01-23 12:19:40 -07:00
parent 02bdd7ed56
commit c7c0cabbb7
No known key found for this signature in database
GPG Key ID: 7A7F66A31EC9B387
2 changed files with 33 additions and 2 deletions

View File

@ -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<String>,
#[dynamic(default)]

View File

@ -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<WindowKeyEvent> {
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 <https://docs.rs/xkbcommon/latest/xkbcommon/xkb/struct.State.html#method.update_key>
/// 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()),