X11: Fix modifiers being reported after release (#1262)
* X11: Fix modifiers being reported after release * Moves `ModifiersChanged` variant from `WindowEvent` to `DeviceEvent` * Add CHANGELOG entry
This commit is contained in:
parent
dba21c06ed
commit
c66784995d
6 changed files with 110 additions and 114 deletions
|
|
@ -25,7 +25,6 @@ pub(super) struct EventProcessor<T: 'static> {
|
|||
pub(super) target: Rc<RootELW<T>>,
|
||||
pub(super) mod_keymap: ModifierKeymap,
|
||||
pub(super) device_mod_state: ModifierKeyState,
|
||||
pub(super) window_mod_state: ModifierKeyState,
|
||||
}
|
||||
|
||||
impl<T: 'static> EventProcessor<T> {
|
||||
|
|
@ -131,7 +130,6 @@ impl<T: 'static> EventProcessor<T> {
|
|||
|
||||
self.mod_keymap.reset_from_x_connection(&wt.xconn);
|
||||
self.device_mod_state.update(&self.mod_keymap);
|
||||
self.window_mod_state.update(&self.mod_keymap);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -547,7 +545,7 @@ impl<T: 'static> EventProcessor<T> {
|
|||
};
|
||||
let virtual_keycode = events::keysym_to_element(keysym as c_uint);
|
||||
|
||||
let modifiers = self.window_mod_state.modifiers();
|
||||
let modifiers = self.device_mod_state.modifiers();
|
||||
|
||||
callback(Event::WindowEvent {
|
||||
window_id,
|
||||
|
|
@ -561,27 +559,6 @@ impl<T: 'static> EventProcessor<T> {
|
|||
},
|
||||
},
|
||||
});
|
||||
|
||||
if let Some(modifier) =
|
||||
self.mod_keymap.get_modifier(xkev.keycode as ffi::KeyCode)
|
||||
{
|
||||
self.window_mod_state.key_event(
|
||||
state,
|
||||
xkev.keycode as ffi::KeyCode,
|
||||
modifier,
|
||||
);
|
||||
|
||||
let new_modifiers = self.window_mod_state.modifiers();
|
||||
|
||||
if modifiers != new_modifiers {
|
||||
callback(Event::WindowEvent {
|
||||
window_id,
|
||||
event: WindowEvent::ModifiersChanged {
|
||||
modifiers: new_modifiers,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if state == Pressed {
|
||||
|
|
@ -894,21 +871,6 @@ impl<T: 'static> EventProcessor<T> {
|
|||
event: Focused(true),
|
||||
});
|
||||
|
||||
// When focus is gained, send any existing modifiers
|
||||
// to the window in a ModifiersChanged event. This is
|
||||
// done to compensate for modifier keys that may be
|
||||
// changed while a window is out of focus.
|
||||
if !self.device_mod_state.is_empty() {
|
||||
self.window_mod_state = self.device_mod_state.clone();
|
||||
|
||||
let modifiers = self.window_mod_state.modifiers();
|
||||
|
||||
callback(Event::WindowEvent {
|
||||
window_id,
|
||||
event: WindowEvent::ModifiersChanged { modifiers },
|
||||
});
|
||||
}
|
||||
|
||||
// The deviceid for this event is for a keyboard instead of a pointer,
|
||||
// so we have to do a little extra work.
|
||||
let pointer_id = self
|
||||
|
|
@ -941,21 +903,6 @@ impl<T: 'static> EventProcessor<T> {
|
|||
.unfocus(xev.event)
|
||||
.expect("Failed to unfocus input context");
|
||||
|
||||
// When focus is lost, send a ModifiersChanged event
|
||||
// containing no modifiers set. This is done to compensate
|
||||
// for modifier keys that may be changed while a window
|
||||
// is out of focus.
|
||||
if !self.window_mod_state.is_empty() {
|
||||
self.window_mod_state.clear();
|
||||
|
||||
callback(Event::WindowEvent {
|
||||
window_id: mkwid(xev.event),
|
||||
event: WindowEvent::ModifiersChanged {
|
||||
modifiers: ModifiersState::default(),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
callback(Event::WindowEvent {
|
||||
window_id: mkwid(xev.event),
|
||||
event: Focused(false),
|
||||
|
|
@ -1068,7 +1015,7 @@ impl<T: 'static> EventProcessor<T> {
|
|||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
let device_id = xev.sourceid;
|
||||
let device_id = mkdid(xev.sourceid);
|
||||
let keycode = xev.detail;
|
||||
if keycode < 8 {
|
||||
return;
|
||||
|
|
@ -1088,6 +1035,18 @@ impl<T: 'static> EventProcessor<T> {
|
|||
|
||||
let virtual_keycode = events::keysym_to_element(keysym as c_uint);
|
||||
|
||||
let modifiers = self.device_mod_state.modifiers();
|
||||
|
||||
callback(Event::DeviceEvent {
|
||||
device_id,
|
||||
event: DeviceEvent::Key(KeyboardInput {
|
||||
scancode,
|
||||
virtual_keycode,
|
||||
state,
|
||||
modifiers,
|
||||
}),
|
||||
});
|
||||
|
||||
if let Some(modifier) =
|
||||
self.mod_keymap.get_modifier(keycode as ffi::KeyCode)
|
||||
{
|
||||
|
|
@ -1096,19 +1055,18 @@ impl<T: 'static> EventProcessor<T> {
|
|||
keycode as ffi::KeyCode,
|
||||
modifier,
|
||||
);
|
||||
|
||||
let new_modifiers = self.device_mod_state.modifiers();
|
||||
|
||||
if modifiers != new_modifiers {
|
||||
callback(Event::DeviceEvent {
|
||||
device_id,
|
||||
event: DeviceEvent::ModifiersChanged {
|
||||
modifiers: new_modifiers,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
let modifiers = self.device_mod_state.modifiers();
|
||||
|
||||
callback(Event::DeviceEvent {
|
||||
device_id: mkdid(device_id),
|
||||
event: DeviceEvent::Key(KeyboardInput {
|
||||
scancode,
|
||||
virtual_keycode,
|
||||
state,
|
||||
modifiers,
|
||||
}),
|
||||
});
|
||||
}
|
||||
|
||||
ffi::XI_HierarchyChanged => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue