mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2024-12-24 06:11:30 +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`,
|
- Add `is_synthetic` field to `WindowEvent` variant `KeyboardInput`,
|
||||||
indicating that the event is generated by winit.
|
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, 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)
|
# 0.20.0 Alpha 4 (2019-10-18)
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,9 @@ use util::modifiers::{ModifierKeyState, ModifierKeymap};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
dpi::{LogicalPosition, LogicalSize},
|
dpi::{LogicalPosition, LogicalSize},
|
||||||
event::{DeviceEvent, ElementState, Event, KeyboardInput, ModifiersState, WindowEvent},
|
event::{
|
||||||
|
DeviceEvent, ElementState, Event, KeyboardInput, ModifiersState, TouchPhase, WindowEvent,
|
||||||
|
},
|
||||||
event_loop::EventLoopWindowTarget as RootELW,
|
event_loop::EventLoopWindowTarget as RootELW,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -25,6 +27,9 @@ pub(super) struct EventProcessor<T: 'static> {
|
||||||
pub(super) target: Rc<RootELW<T>>,
|
pub(super) target: Rc<RootELW<T>>,
|
||||||
pub(super) mod_keymap: ModifierKeymap,
|
pub(super) mod_keymap: ModifierKeymap,
|
||||||
pub(super) device_mod_state: ModifierKeyState,
|
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> {
|
impl<T: 'static> EventProcessor<T> {
|
||||||
|
@ -620,7 +625,7 @@ impl<T: 'static> EventProcessor<T> {
|
||||||
ElementState::{Pressed, Released},
|
ElementState::{Pressed, Released},
|
||||||
MouseButton::{Left, Middle, Other, Right},
|
MouseButton::{Left, Middle, Other, Right},
|
||||||
MouseScrollDelta::LineDelta,
|
MouseScrollDelta::LineDelta,
|
||||||
Touch, TouchPhase,
|
Touch,
|
||||||
WindowEvent::{
|
WindowEvent::{
|
||||||
AxisMotion, CursorEntered, CursorLeft, CursorMoved, Focused, MouseInput,
|
AxisMotion, CursorEntered, CursorLeft, CursorMoved, Focused, MouseInput,
|
||||||
MouseWheel,
|
MouseWheel,
|
||||||
|
@ -962,10 +967,27 @@ impl<T: 'static> EventProcessor<T> {
|
||||||
let dpi_factor =
|
let dpi_factor =
|
||||||
self.with_window(xev.event, |window| window.hidpi_factor());
|
self.with_window(xev.event, |window| window.hidpi_factor());
|
||||||
if let Some(dpi_factor) = dpi_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(
|
let location = LogicalPosition::from_physical(
|
||||||
(xev.event_x as f64, xev.event_y as f64),
|
(xev.event_x as f64, xev.event_y as f64),
|
||||||
dpi_factor,
|
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 {
|
callback(Event::WindowEvent {
|
||||||
window_id,
|
window_id,
|
||||||
event: WindowEvent::Touch(Touch {
|
event: WindowEvent::Touch(Touch {
|
||||||
|
@ -973,7 +995,7 @@ impl<T: 'static> EventProcessor<T> {
|
||||||
phase,
|
phase,
|
||||||
location,
|
location,
|
||||||
force: None, // TODO
|
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,
|
xi2ext,
|
||||||
mod_keymap,
|
mod_keymap,
|
||||||
device_mod_state: Default::default(),
|
device_mod_state: Default::default(),
|
||||||
|
num_touch: 0,
|
||||||
|
first_touch: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Register for device hotplug events
|
// Register for device hotplug events
|
||||||
|
|
Loading…
Reference in a new issue