X11: Fix incorrect modifiers when events are missed (#1279)
* X11: Fix incorrect modifiers when events are missed * Syncs modifier state with state data in X key/button/motion events. * Fixes modifier state in XWayland, as xinput2 raw input events will not be received when a window does not have focus. * Removes `impl From<_> for ModifiersState` on X11/Wayland API types, replacing them with `pub(crate)` methods. * Cleanup modifier state update using a macro * Remove keys from modifier state when updating
This commit is contained in:
parent
a70ac1531e
commit
a95ebc5ee6
4 changed files with 105 additions and 37 deletions
|
|
@ -120,6 +120,26 @@ impl<T: 'static> EventProcessor<T> {
|
|||
return;
|
||||
}
|
||||
|
||||
// We can't call a `&mut self` method because of the above borrow,
|
||||
// so we use this macro for repeated modifier state updates.
|
||||
macro_rules! update_modifiers {
|
||||
( $state:expr , $modifier:expr ) => {{
|
||||
match ($state, $modifier) {
|
||||
(state, modifier) => {
|
||||
if let Some(modifiers) =
|
||||
self.device_mod_state.update_state(&state, modifier)
|
||||
{
|
||||
let device_id = mkdid(util::VIRTUAL_CORE_KEYBOARD);
|
||||
callback(Event::DeviceEvent {
|
||||
device_id,
|
||||
event: DeviceEvent::ModifiersChanged { modifiers },
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
||||
let event_type = xev.get_type();
|
||||
match event_type {
|
||||
ffi::MappingNotify => {
|
||||
|
|
@ -136,7 +156,7 @@ impl<T: 'static> EventProcessor<T> {
|
|||
.expect("Failed to call XRefreshKeyboardMapping");
|
||||
|
||||
self.mod_keymap.reset_from_x_connection(&wt.xconn);
|
||||
self.device_mod_state.update(&self.mod_keymap);
|
||||
self.device_mod_state.update_keymap(&self.mod_keymap);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -553,6 +573,11 @@ impl<T: 'static> EventProcessor<T> {
|
|||
};
|
||||
let virtual_keycode = events::keysym_to_element(keysym as c_uint);
|
||||
|
||||
update_modifiers!(
|
||||
ModifiersState::from_x11_mask(xkev.state),
|
||||
self.mod_keymap.get_modifier(xkev.keycode as ffi::KeyCode)
|
||||
);
|
||||
|
||||
let modifiers = self.device_mod_state.modifiers();
|
||||
|
||||
callback(Event::WindowEvent {
|
||||
|
|
@ -618,7 +643,8 @@ impl<T: 'static> EventProcessor<T> {
|
|||
return;
|
||||
}
|
||||
|
||||
let modifiers = ModifiersState::from(xev.mods);
|
||||
let modifiers = ModifiersState::from_x11(&xev.mods);
|
||||
update_modifiers!(modifiers, None);
|
||||
|
||||
let state = if xev.evtype == ffi::XI_ButtonPress {
|
||||
Pressed
|
||||
|
|
@ -694,7 +720,8 @@ impl<T: 'static> EventProcessor<T> {
|
|||
let window_id = mkwid(xev.event);
|
||||
let new_cursor_pos = (xev.event_x, xev.event_y);
|
||||
|
||||
let modifiers = ModifiersState::from(xev.mods);
|
||||
let modifiers = ModifiersState::from_x11(&xev.mods);
|
||||
update_modifiers!(modifiers, None);
|
||||
|
||||
let cursor_moved = self.with_window(xev.event, |window| {
|
||||
let mut shared_state_lock = window.shared_state.lock();
|
||||
|
|
@ -897,7 +924,7 @@ impl<T: 'static> EventProcessor<T> {
|
|||
event: CursorMoved {
|
||||
device_id: mkdid(pointer_id),
|
||||
position,
|
||||
modifiers: ModifiersState::from(xev.mods),
|
||||
modifiers: ModifiersState::from_x11(&xev.mods),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue