1
1
mirror of https://github.com/wez/wezterm.git synced 2024-11-27 02:25:28 +03:00

x11: Use modifiers from X event if non were detected by XKB

This is a working tentative at fixing text expansion/injection done by
Espanso by default, where XKB doesn't seem to detect the pressed
modifiers `Ctrl+Shift` before pressing `v`.

refs: #3840
This commit is contained in:
Benoit de Chezelles 2023-08-15 19:28:33 +02:00 committed by Wez Furlong
parent 90d8feaf6d
commit 0466898af7
No known key found for this signature in database
GPG Key ID: 7A7F66A31EC9B387

View File

@ -166,7 +166,33 @@ impl KeyboardWithFallback {
events: &mut WindowEventSender, events: &mut WindowEventSender,
) -> Option<WindowKeyEvent> { ) -> Option<WindowKeyEvent> {
let want_repeat = self.selected.wayland_key_repeats(code); let want_repeat = self.selected.wayland_key_repeats(code);
self.process_key_event_impl(code + 8, pressed, events, want_repeat) self.process_key_event_impl(code + 8, Modifiers::default(), pressed, events, want_repeat)
}
/// When XKB doesn't have modifiers in its state but there are modifiers given in the X
/// event, use these as fallback.
///
/// This can happen (FIXME: WHY) for example when Espanso (a text expander/injector)
/// simulate inputs.
///
/// 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.
fn modifiers_from_btn_mask(mask: xcb::x::KeyButMask) -> Modifiers {
let mut res = Modifiers::default();
if mask.contains(xcb::x::KeyButMask::SHIFT) {
res |= Modifiers::SHIFT;
}
if mask.contains(xcb::x::KeyButMask::CONTROL) {
res |= Modifiers::CTRL;
}
if mask.contains(xcb::x::KeyButMask::MOD1) {
res |= Modifiers::ALT;
}
if mask.contains(xcb::x::KeyButMask::MOD4) {
res |= Modifiers::SUPER;
}
res
} }
pub fn process_key_press_event( pub fn process_key_press_event(
@ -175,7 +201,13 @@ impl KeyboardWithFallback {
events: &mut WindowEventSender, events: &mut WindowEventSender,
) { ) {
let xcode = xkb::Keycode::from(xcb_ev.detail()); let xcode = xkb::Keycode::from(xcb_ev.detail());
self.process_key_event_impl(xcode, true, events, false); self.process_key_event_impl(
xcode,
Self::modifiers_from_btn_mask(xcb_ev.state()),
true,
events,
false,
);
} }
pub fn process_key_release_event( pub fn process_key_release_event(
@ -184,18 +216,25 @@ impl KeyboardWithFallback {
events: &mut WindowEventSender, events: &mut WindowEventSender,
) { ) {
let xcode = xkb::Keycode::from(xcb_ev.detail()); let xcode = xkb::Keycode::from(xcb_ev.detail());
self.process_key_event_impl(xcode, false, events, false); self.process_key_event_impl(
xcode,
Self::modifiers_from_btn_mask(xcb_ev.state()),
false,
events,
false,
);
} }
fn process_key_event_impl( fn process_key_event_impl(
&self, &self,
xcode: xkb::Keycode, xcode: xkb::Keycode,
additional_x_raw_modifiers: Modifiers,
pressed: bool, pressed: bool,
events: &mut WindowEventSender, events: &mut WindowEventSender,
want_repeat: bool, want_repeat: bool,
) -> Option<WindowKeyEvent> { ) -> Option<WindowKeyEvent> {
let phys_code = self.selected.phys_code_map.borrow().get(&xcode).copied(); let phys_code = self.selected.phys_code_map.borrow().get(&xcode).copied();
let raw_modifiers = self.get_key_modifiers(); let raw_modifiers = self.get_key_modifiers() | additional_x_raw_modifiers;
let leds = self.get_led_status(); let leds = self.get_led_status();
let xsym = self.selected.state.borrow().key_get_one_sym(xcode); let xsym = self.selected.state.borrow().key_get_one_sym(xcode);