Skip to content

Commit

Permalink
x11: Use modifiers from X event if non were detected by XKB
Browse files Browse the repository at this point in the history
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
  • Loading branch information
bew authored and wez committed Jan 11, 2024
1 parent 90d8fea commit 0466898
Showing 1 changed file with 43 additions and 4 deletions.
47 changes: 43 additions & 4 deletions window/src/os/x11/keyboard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,33 @@ impl KeyboardWithFallback {
events: &mut WindowEventSender,
) -> Option<WindowKeyEvent> {
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(
Expand All @@ -175,7 +201,13 @@ impl KeyboardWithFallback {
events: &mut WindowEventSender,
) {
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(
Expand All @@ -184,18 +216,25 @@ impl KeyboardWithFallback {
events: &mut WindowEventSender,
) {
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(
&self,
xcode: xkb::Keycode,
additional_x_raw_modifiers: Modifiers,
pressed: bool,
events: &mut WindowEventSender,
want_repeat: bool,
) -> Option<WindowKeyEvent> {
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 xsym = self.selected.state.borrow().key_get_one_sym(xcode);
Expand Down

0 comments on commit 0466898

Please sign in to comment.