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`.
  • Loading branch information
bew committed Aug 15, 2023
1 parent 0f1ffac commit 38048bb
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 8 deletions.
4 changes: 2 additions & 2 deletions window/src/os/wayland/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -467,12 +467,12 @@ impl WaylandWindowInner {
} => {
mapper.update_modifier_state(mods_depressed, mods_latched, mods_locked, group);

let mods = mapper.get_key_modifiers();
let mods = mapper.get_key_modifiers(None);
let leds = mapper.get_led_status();

let changed = (mods != self.modifiers) || (leds != self.leds);

self.modifiers = mapper.get_key_modifiers();
self.modifiers = mapper.get_key_modifiers(None);
self.leds = mapper.get_led_status();

if changed {
Expand Down
36 changes: 30 additions & 6 deletions window/src/os/x11/keyboard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ 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, None, pressed, events, want_repeat)
}

pub fn process_key_press_event(
Expand All @@ -175,7 +175,8 @@ impl KeyboardWithFallback {
events: &mut WindowEventSender,
) {
let xcode = xkb::Keycode::from(xcb_ev.detail());
self.process_key_event_impl(xcode, true, events, false);
let xmods = Some(xcb_ev.state()); // modifiers from event
self.process_key_event_impl(xcode, xmods, true, events, false);
}

pub fn process_key_release_event(
Expand All @@ -184,18 +185,20 @@ impl KeyboardWithFallback {
events: &mut WindowEventSender,
) {
let xcode = xkb::Keycode::from(xcb_ev.detail());
self.process_key_event_impl(xcode, false, events, false);
let xmods = Some(xcb_ev.state()); // modifiers from event
self.process_key_event_impl(xcode, xmods, false, events, false);
}

fn process_key_event_impl(
&self,
xcode: xkb::Keycode,
xmods: Option<xcb::x::KeyButMask>,
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(xmods);
let leds = self.get_led_status();

let xsym = self.selected.state.borrow().key_get_one_sym(xcode);
Expand Down Expand Up @@ -380,7 +383,7 @@ impl KeyboardWithFallback {
leds
}

pub fn get_key_modifiers(&self) -> Modifiers {
pub fn get_key_modifiers(&self, fallback_xmods: Option<xcb::x::KeyButMask>) -> Modifiers {
let mut res = Modifiers::default();

if self.mod_is_active(xkb::MOD_NAME_SHIFT) {
Expand All @@ -397,6 +400,27 @@ impl KeyboardWithFallback {
// Mod4
res |= Modifiers::SUPER;
}

// 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.
if let (true, Some(event_xmods)) = (res.is_empty(), fallback_xmods) {
if event_xmods.contains(xcb::x::KeyButMask::SHIFT) {
res |= Modifiers::SHIFT;
}
if event_xmods.contains(xcb::x::KeyButMask::CONTROL) {
res |= Modifiers::CTRL;
}
if event_xmods.contains(xcb::x::KeyButMask::MOD1) {
res |= Modifiers::ALT;
}
if event_xmods.contains(xcb::x::KeyButMask::MOD4) {
res |= Modifiers::SUPER;
}
}

res
}

Expand All @@ -419,7 +443,7 @@ impl KeyboardWithFallback {
_ => {}
}

let after = (self.get_key_modifiers(), self.get_led_status());
let after = (self.get_key_modifiers(None), self.get_led_status());
if after != before {
*self.selected.mods_leds.borrow_mut() = after.clone();
Ok(Some(after))
Expand Down

0 comments on commit 38048bb

Please sign in to comment.