mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2024-12-23 22:01:31 +11:00
X11: Report CursorMoved
when touch event occurs (#1297)
* X11: Report `CursorMoved` when touch event occurs * Only trigger CursorMoved events for the first touch ID * Fix testing for current touch events * Fix first touch logic
This commit is contained in:
parent
e5291c9e28
commit
1f81e5c872
|
@ -15,6 +15,8 @@
|
|||
- Add `is_synthetic` field to `WindowEvent` variant `KeyboardInput`,
|
||||
indicating that the event is generated by winit.
|
||||
- On X11, generate synthetic key events for keys held when a window gains or loses focus.
|
||||
- On X11, issue a `CursorMoved` event when a `Touch` event occurs,
|
||||
as X11 implicitly moves the cursor for such events.
|
||||
|
||||
# 0.20.0 Alpha 4 (2019-10-18)
|
||||
|
||||
|
|
|
@ -12,7 +12,9 @@ use util::modifiers::{ModifierKeyState, ModifierKeymap};
|
|||
|
||||
use crate::{
|
||||
dpi::{LogicalPosition, LogicalSize},
|
||||
event::{DeviceEvent, ElementState, Event, KeyboardInput, ModifiersState, WindowEvent},
|
||||
event::{
|
||||
DeviceEvent, ElementState, Event, KeyboardInput, ModifiersState, TouchPhase, WindowEvent,
|
||||
},
|
||||
event_loop::EventLoopWindowTarget as RootELW,
|
||||
};
|
||||
|
||||
|
@ -25,6 +27,9 @@ pub(super) struct EventProcessor<T: 'static> {
|
|||
pub(super) target: Rc<RootELW<T>>,
|
||||
pub(super) mod_keymap: ModifierKeymap,
|
||||
pub(super) device_mod_state: ModifierKeyState,
|
||||
// Number of touch events currently in progress
|
||||
pub(super) num_touch: u32,
|
||||
pub(super) first_touch: Option<u64>,
|
||||
}
|
||||
|
||||
impl<T: 'static> EventProcessor<T> {
|
||||
|
@ -620,7 +625,7 @@ impl<T: 'static> EventProcessor<T> {
|
|||
ElementState::{Pressed, Released},
|
||||
MouseButton::{Left, Middle, Other, Right},
|
||||
MouseScrollDelta::LineDelta,
|
||||
Touch, TouchPhase,
|
||||
Touch,
|
||||
WindowEvent::{
|
||||
AxisMotion, CursorEntered, CursorLeft, CursorMoved, Focused, MouseInput,
|
||||
MouseWheel,
|
||||
|
@ -962,10 +967,27 @@ impl<T: 'static> EventProcessor<T> {
|
|||
let dpi_factor =
|
||||
self.with_window(xev.event, |window| window.hidpi_factor());
|
||||
if let Some(dpi_factor) = dpi_factor {
|
||||
let id = xev.detail as u64;
|
||||
let modifiers = self.device_mod_state.modifiers();
|
||||
let location = LogicalPosition::from_physical(
|
||||
(xev.event_x as f64, xev.event_y as f64),
|
||||
dpi_factor,
|
||||
);
|
||||
|
||||
// Mouse cursor position changes when touch events are received.
|
||||
// Only the first concurrently active touch ID moves the mouse cursor.
|
||||
if is_first_touch(&mut self.first_touch, &mut self.num_touch, id, phase)
|
||||
{
|
||||
callback(Event::WindowEvent {
|
||||
window_id,
|
||||
event: WindowEvent::CursorMoved {
|
||||
device_id: mkdid(util::VIRTUAL_CORE_POINTER),
|
||||
position: location,
|
||||
modifiers,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
callback(Event::WindowEvent {
|
||||
window_id,
|
||||
event: WindowEvent::Touch(Touch {
|
||||
|
@ -973,7 +995,7 @@ impl<T: 'static> EventProcessor<T> {
|
|||
phase,
|
||||
location,
|
||||
force: None, // TODO
|
||||
id: xev.detail as u64,
|
||||
id,
|
||||
}),
|
||||
})
|
||||
}
|
||||
|
@ -1216,3 +1238,23 @@ impl<T: 'static> EventProcessor<T> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn is_first_touch(first: &mut Option<u64>, num: &mut u32, id: u64, phase: TouchPhase) -> bool {
|
||||
match phase {
|
||||
TouchPhase::Started => {
|
||||
if *num == 0 {
|
||||
*first = Some(id);
|
||||
}
|
||||
*num += 1;
|
||||
}
|
||||
TouchPhase::Cancelled | TouchPhase::Ended => {
|
||||
if *first == Some(id) {
|
||||
*first = None;
|
||||
}
|
||||
*num = num.saturating_sub(1);
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
|
||||
*first == Some(id)
|
||||
}
|
||||
|
|
|
@ -199,6 +199,8 @@ impl<T: 'static> EventLoop<T> {
|
|||
xi2ext,
|
||||
mod_keymap,
|
||||
device_mod_state: Default::default(),
|
||||
num_touch: 0,
|
||||
first_touch: None,
|
||||
};
|
||||
|
||||
// Register for device hotplug events
|
||||
|
|
Loading…
Reference in a new issue