api: move primary from FingerId to Pointer events
Whether the pointer event is primary or not generally matters for the context where all input is done by the same event, so users can _ignore_ non-primary events since they are likely from users clicking something else with their other fingers. Having it only on a FingerId made it useless, since it's usually used to avoid multi-touch, but if you start mapping on touch event you already can track things like that yourself. Fixes #3943. Co-authored-by: daxpedda <daxpedda@gmail.com>
This commit is contained in:
parent
d3207a8d76
commit
c8c1eca3c7
19 changed files with 346 additions and 176 deletions
|
|
@ -67,8 +67,8 @@ changelog entry.
|
|||
- On macOS, add `WindowExtMacOS::set_unified_titlebar` and `WindowAttributesExtMacOS::with_unified_titlebar`
|
||||
to use a larger style of titlebar.
|
||||
- Add `WindowId::into_raw()` and `from_raw()`.
|
||||
- Add `PointerKind`, `PointerSource`, `ButtonSource`, `FingerId` and `position` to all pointer
|
||||
events as part of the pointer event overhaul.
|
||||
- Add `PointerKind`, `PointerSource`, `ButtonSource`, `FingerId`, `primary` and `position` to all
|
||||
pointer events as part of the pointer event overhaul.
|
||||
- Add `DeviceId::into_raw()` and `from_raw()`.
|
||||
|
||||
### Changed
|
||||
|
|
@ -138,6 +138,8 @@ changelog entry.
|
|||
- Rename `CursorEntered` to `PointerEntered`.
|
||||
- Rename `CursorLeft` to `PointerLeft`.
|
||||
- Rename `MouseInput` to `PointerButton`.
|
||||
- Add `primary` to every `PointerEvent` as a way to identify discard non-primary pointers in a
|
||||
multi-touch interaction.
|
||||
- Add `position` to every `PointerEvent`.
|
||||
- `PointerMoved` is **not sent** after `PointerEntered` anymore.
|
||||
- Remove `Touch`, which is folded into the `Pointer*` events.
|
||||
|
|
@ -150,8 +152,6 @@ changelog entry.
|
|||
type to a generic mouse button.
|
||||
- New `FingerId` added to `PointerKind::Touch` and `PointerSource::Touch` able to uniquely
|
||||
identify a finger in a multi-touch interaction. Replaces the old `Touch::id`.
|
||||
- On Web and Windows, add `FingerIdExt*::is_primary()`, exposing a way to determine
|
||||
the primary finger in a multi-touch interaction.
|
||||
- In the same spirit rename `DeviceEvent::MouseMotion` to `PointerMotion`.
|
||||
- Remove `Force::Calibrated::altitude_angle`.
|
||||
|
||||
|
|
|
|||
29
src/event.rs
29
src/event.rs
|
|
@ -245,6 +245,12 @@ pub enum WindowEvent {
|
|||
/// [`transform`]: https://developer.mozilla.org/en-US/docs/Web/CSS/transform
|
||||
position: PhysicalPosition<f64>,
|
||||
|
||||
/// Indicates whether the event is created by a primary pointer.
|
||||
///
|
||||
/// A pointer is considered primary when it's a mouse, the first finger in a multi-touch
|
||||
/// interaction, or an unknown pointer source.
|
||||
primary: bool,
|
||||
|
||||
source: PointerSource,
|
||||
},
|
||||
|
||||
|
|
@ -264,6 +270,12 @@ pub enum WindowEvent {
|
|||
/// [`transform`]: https://developer.mozilla.org/en-US/docs/Web/CSS/transform
|
||||
position: PhysicalPosition<f64>,
|
||||
|
||||
/// Indicates whether the event is created by a primary pointer.
|
||||
///
|
||||
/// A pointer is considered primary when it's a mouse, the first finger in a multi-touch
|
||||
/// interaction, or an unknown pointer source.
|
||||
primary: bool,
|
||||
|
||||
kind: PointerKind,
|
||||
},
|
||||
|
||||
|
|
@ -284,6 +296,12 @@ pub enum WindowEvent {
|
|||
/// [`transform`]: https://developer.mozilla.org/en-US/docs/Web/CSS/transform
|
||||
position: Option<PhysicalPosition<f64>>,
|
||||
|
||||
/// Indicates whether the event is created by a primary pointer.
|
||||
///
|
||||
/// A pointer is considered primary when it's a mouse, the first finger in a multi-touch
|
||||
/// interaction, or an unknown pointer source.
|
||||
primary: bool,
|
||||
|
||||
kind: PointerKind,
|
||||
},
|
||||
|
||||
|
|
@ -307,6 +325,12 @@ pub enum WindowEvent {
|
|||
/// [`transform`]: https://developer.mozilla.org/en-US/docs/Web/CSS/transform
|
||||
position: PhysicalPosition<f64>,
|
||||
|
||||
/// Indicates whether the event is created by a primary pointer.
|
||||
///
|
||||
/// A pointer is considered primary when it's a mouse, the first finger in a multi-touch
|
||||
/// interaction, or an unknown pointer source.
|
||||
primary: bool,
|
||||
|
||||
button: ButtonSource,
|
||||
},
|
||||
|
||||
|
|
@ -1162,16 +1186,19 @@ mod tests {
|
|||
with_window_event(Ime(Enabled));
|
||||
with_window_event(PointerMoved {
|
||||
device_id: None,
|
||||
primary: true,
|
||||
position: (0, 0).into(),
|
||||
source: PointerSource::Mouse,
|
||||
});
|
||||
with_window_event(ModifiersChanged(event::Modifiers::default()));
|
||||
with_window_event(PointerEntered {
|
||||
device_id: None,
|
||||
primary: true,
|
||||
position: (0, 0).into(),
|
||||
kind: PointerKind::Mouse,
|
||||
});
|
||||
with_window_event(PointerLeft {
|
||||
primary: true,
|
||||
device_id: None,
|
||||
position: Some((0, 0).into()),
|
||||
kind: PointerKind::Mouse,
|
||||
|
|
@ -1183,12 +1210,14 @@ mod tests {
|
|||
});
|
||||
with_window_event(PointerButton {
|
||||
device_id: None,
|
||||
primary: true,
|
||||
state: event::ElementState::Pressed,
|
||||
position: (0, 0).into(),
|
||||
button: event::MouseButton::Other(0).into(),
|
||||
});
|
||||
with_window_event(PointerButton {
|
||||
device_id: None,
|
||||
primary: true,
|
||||
state: event::ElementState::Released,
|
||||
position: (0, 0).into(),
|
||||
button: event::ButtonSource::Touch {
|
||||
|
|
|
|||
|
|
@ -57,7 +57,6 @@ use web_sys::HtmlCanvasElement;
|
|||
use crate::application::ApplicationHandler;
|
||||
use crate::cursor::CustomCursorSource;
|
||||
use crate::error::NotSupportedError;
|
||||
use crate::event::FingerId;
|
||||
use crate::event_loop::{ActiveEventLoop, EventLoop};
|
||||
use crate::monitor::MonitorHandle;
|
||||
use crate::platform_impl::PlatformCustomCursorSource;
|
||||
|
|
@ -780,16 +779,3 @@ impl Display for OrientationLockError {
|
|||
}
|
||||
|
||||
impl Error for OrientationLockError {}
|
||||
|
||||
/// Additional methods on [`FingerId`] that are specific to Web.
|
||||
pub trait FingerIdExtWeb {
|
||||
/// Indicates if the finger represents the first contact in a multi-touch interaction.
|
||||
#[allow(clippy::wrong_self_convention)]
|
||||
fn is_primary(self) -> bool;
|
||||
}
|
||||
|
||||
impl FingerIdExtWeb for FingerId {
|
||||
fn is_primary(self) -> bool {
|
||||
self.0.is_primary()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ use serde::{Deserialize, Serialize};
|
|||
use windows_sys::Win32::Foundation::HANDLE;
|
||||
|
||||
use crate::dpi::PhysicalSize;
|
||||
use crate::event::{DeviceId, FingerId};
|
||||
use crate::event::DeviceId;
|
||||
use crate::event_loop::EventLoopBuilder;
|
||||
use crate::monitor::MonitorHandle;
|
||||
use crate::window::{BadIcon, Icon, Window, WindowAttributes};
|
||||
|
|
@ -670,20 +670,6 @@ impl DeviceIdExtWindows for DeviceId {
|
|||
}
|
||||
}
|
||||
|
||||
/// Additional methods on `FingerId` that are specific to Windows.
|
||||
pub trait FingerIdExtWindows {
|
||||
/// Indicates if the finger represents the first contact in a multi-touch interaction.
|
||||
#[allow(clippy::wrong_self_convention)]
|
||||
fn is_primary(self) -> bool;
|
||||
}
|
||||
|
||||
impl FingerIdExtWindows for FingerId {
|
||||
#[inline]
|
||||
fn is_primary(self) -> bool {
|
||||
self.0.is_primary()
|
||||
}
|
||||
}
|
||||
|
||||
/// Additional methods on `Icon` that are specific to Windows.
|
||||
pub trait IconExtWindows: Sized {
|
||||
/// Create an icon from a file path.
|
||||
|
|
|
|||
|
|
@ -107,6 +107,7 @@ pub struct EventLoop {
|
|||
running: bool,
|
||||
pending_redraw: bool,
|
||||
cause: StartCause,
|
||||
primary_pointer: FingerId,
|
||||
ignore_volume_keys: bool,
|
||||
combining_accent: Option<char>,
|
||||
}
|
||||
|
|
@ -140,6 +141,7 @@ impl EventLoop {
|
|||
|
||||
Ok(Self {
|
||||
android_app: android_app.clone(),
|
||||
primary_pointer: FingerId::dummy(),
|
||||
window_target: ActiveEventLoop {
|
||||
app: android_app.clone(),
|
||||
control_flow: Cell::new(ControlFlow::default()),
|
||||
|
|
@ -333,36 +335,83 @@ impl EventLoop {
|
|||
_ => None,
|
||||
};
|
||||
|
||||
if let Some(pointers) = pointers {
|
||||
for pointer in pointers {
|
||||
let tool_type = pointer.tool_type();
|
||||
let position =
|
||||
PhysicalPosition { x: pointer.x() as _, y: pointer.y() as _ };
|
||||
trace!(
|
||||
"Input event {device_id:?}, {action:?}, loc={position:?}, \
|
||||
pointer={pointer:?}, tool_type={tool_type:?}"
|
||||
);
|
||||
let finger_id = event::FingerId(FingerId(pointer.pointer_id()));
|
||||
let force = Some(Force::Normalized(pointer.pressure() as f64));
|
||||
for pointer in pointers.into_iter().flatten() {
|
||||
let tool_type = pointer.tool_type();
|
||||
let position = PhysicalPosition { x: pointer.x() as _, y: pointer.y() as _ };
|
||||
trace!(
|
||||
"Input event {device_id:?}, {action:?}, loc={position:?}, \
|
||||
pointer={pointer:?}, tool_type={tool_type:?}"
|
||||
);
|
||||
let finger_id = event::FingerId(FingerId(pointer.pointer_id()));
|
||||
let force = Some(Force::Normalized(pointer.pressure() as f64));
|
||||
|
||||
match action {
|
||||
MotionAction::Down | MotionAction::PointerDown => {
|
||||
let event = event::WindowEvent::PointerEntered {
|
||||
device_id,
|
||||
position,
|
||||
kind: match tool_type {
|
||||
android_activity::input::ToolType::Finger => {
|
||||
event::PointerKind::Touch(finger_id)
|
||||
},
|
||||
// TODO mouse events
|
||||
android_activity::input::ToolType::Mouse => continue,
|
||||
_ => event::PointerKind::Unknown,
|
||||
match action {
|
||||
MotionAction::Down | MotionAction::PointerDown => {
|
||||
let primary = action == MotionAction::Down;
|
||||
if primary {
|
||||
self.primary_pointer = finger_id.0;
|
||||
}
|
||||
let event = event::WindowEvent::PointerEntered {
|
||||
device_id,
|
||||
primary,
|
||||
position,
|
||||
kind: match tool_type {
|
||||
android_activity::input::ToolType::Finger => {
|
||||
event::PointerKind::Touch(finger_id)
|
||||
},
|
||||
};
|
||||
app.window_event(&self.window_target, GLOBAL_WINDOW, event);
|
||||
// TODO mouse events
|
||||
android_activity::input::ToolType::Mouse => continue,
|
||||
_ => event::PointerKind::Unknown,
|
||||
},
|
||||
};
|
||||
app.window_event(&self.window_target, GLOBAL_WINDOW, event);
|
||||
let event = event::WindowEvent::PointerButton {
|
||||
device_id,
|
||||
primary,
|
||||
state: event::ElementState::Pressed,
|
||||
position,
|
||||
button: match tool_type {
|
||||
android_activity::input::ToolType::Finger => {
|
||||
event::ButtonSource::Touch { finger_id, force }
|
||||
},
|
||||
// TODO mouse events
|
||||
android_activity::input::ToolType::Mouse => continue,
|
||||
_ => event::ButtonSource::Unknown(0),
|
||||
},
|
||||
};
|
||||
app.window_event(&self.window_target, GLOBAL_WINDOW, event);
|
||||
},
|
||||
MotionAction::Move => {
|
||||
let primary = self.primary_pointer == finger_id.0;
|
||||
let event = event::WindowEvent::PointerMoved {
|
||||
device_id,
|
||||
primary,
|
||||
position,
|
||||
source: match tool_type {
|
||||
android_activity::input::ToolType::Finger => {
|
||||
event::PointerSource::Touch { finger_id, force }
|
||||
},
|
||||
// TODO mouse events
|
||||
android_activity::input::ToolType::Mouse => continue,
|
||||
_ => event::PointerSource::Unknown,
|
||||
},
|
||||
};
|
||||
app.window_event(&self.window_target, GLOBAL_WINDOW, event);
|
||||
},
|
||||
MotionAction::Up | MotionAction::PointerUp | MotionAction::Cancel => {
|
||||
let primary = action == MotionAction::Up
|
||||
|| (action == MotionAction::Cancel
|
||||
&& self.primary_pointer == finger_id.0);
|
||||
|
||||
if primary {
|
||||
self.primary_pointer = FingerId::dummy();
|
||||
}
|
||||
|
||||
if let MotionAction::Up | MotionAction::PointerUp = action {
|
||||
let event = event::WindowEvent::PointerButton {
|
||||
device_id,
|
||||
state: event::ElementState::Pressed,
|
||||
primary,
|
||||
state: event::ElementState::Released,
|
||||
position,
|
||||
button: match tool_type {
|
||||
android_activity::input::ToolType::Finger => {
|
||||
|
|
@ -374,56 +423,24 @@ impl EventLoop {
|
|||
},
|
||||
};
|
||||
app.window_event(&self.window_target, GLOBAL_WINDOW, event);
|
||||
},
|
||||
MotionAction::Move => {
|
||||
let event = event::WindowEvent::PointerMoved {
|
||||
device_id,
|
||||
position,
|
||||
source: match tool_type {
|
||||
android_activity::input::ToolType::Finger => {
|
||||
event::PointerSource::Touch { finger_id, force }
|
||||
},
|
||||
// TODO mouse events
|
||||
android_activity::input::ToolType::Mouse => continue,
|
||||
_ => event::PointerSource::Unknown,
|
||||
},
|
||||
};
|
||||
app.window_event(&self.window_target, GLOBAL_WINDOW, event);
|
||||
},
|
||||
MotionAction::Up | MotionAction::PointerUp | MotionAction::Cancel => {
|
||||
if let MotionAction::Up | MotionAction::PointerUp = action {
|
||||
let event = event::WindowEvent::PointerButton {
|
||||
device_id,
|
||||
state: event::ElementState::Released,
|
||||
position,
|
||||
button: match tool_type {
|
||||
android_activity::input::ToolType::Finger => {
|
||||
event::ButtonSource::Touch { finger_id, force }
|
||||
},
|
||||
// TODO mouse events
|
||||
android_activity::input::ToolType::Mouse => continue,
|
||||
_ => event::ButtonSource::Unknown(0),
|
||||
},
|
||||
};
|
||||
app.window_event(&self.window_target, GLOBAL_WINDOW, event);
|
||||
}
|
||||
}
|
||||
|
||||
let event = event::WindowEvent::PointerLeft {
|
||||
device_id,
|
||||
position: Some(position),
|
||||
kind: match tool_type {
|
||||
android_activity::input::ToolType::Finger => {
|
||||
event::PointerKind::Touch(finger_id)
|
||||
},
|
||||
// TODO mouse events
|
||||
android_activity::input::ToolType::Mouse => continue,
|
||||
_ => event::PointerKind::Unknown,
|
||||
let event = event::WindowEvent::PointerLeft {
|
||||
device_id,
|
||||
primary,
|
||||
position: Some(position),
|
||||
kind: match tool_type {
|
||||
android_activity::input::ToolType::Finger => {
|
||||
event::PointerKind::Touch(finger_id)
|
||||
},
|
||||
};
|
||||
app.window_event(&self.window_target, GLOBAL_WINDOW, event);
|
||||
},
|
||||
_ => unreachable!(),
|
||||
}
|
||||
// TODO mouse events
|
||||
android_activity::input::ToolType::Mouse => continue,
|
||||
_ => event::PointerKind::Unknown,
|
||||
},
|
||||
};
|
||||
app.window_event(&self.window_target, GLOBAL_WINDOW, event);
|
||||
},
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -732,7 +749,6 @@ impl OwnedDisplayHandle {
|
|||
pub struct FingerId(i32);
|
||||
|
||||
impl FingerId {
|
||||
#[cfg(test)]
|
||||
pub const fn dummy() -> Self {
|
||||
FingerId(0)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -657,6 +657,7 @@ declare_class!(
|
|||
|
||||
self.queue_event(WindowEvent::PointerEntered {
|
||||
device_id: None,
|
||||
primary: true,
|
||||
position,
|
||||
kind: PointerKind::Mouse,
|
||||
});
|
||||
|
|
@ -670,6 +671,7 @@ declare_class!(
|
|||
|
||||
self.queue_event(WindowEvent::PointerLeft {
|
||||
device_id: None,
|
||||
primary: true,
|
||||
position: Some(position),
|
||||
kind: PointerKind::Mouse,
|
||||
});
|
||||
|
|
@ -1061,6 +1063,7 @@ impl WinitView {
|
|||
|
||||
self.queue_event(WindowEvent::PointerButton {
|
||||
device_id: None,
|
||||
primary: true,
|
||||
state: button_state,
|
||||
position,
|
||||
button: button.into(),
|
||||
|
|
@ -1087,6 +1090,7 @@ impl WinitView {
|
|||
|
||||
self.queue_event(WindowEvent::PointerMoved {
|
||||
device_id: None,
|
||||
primary: true,
|
||||
position: view_point.to_physical(self.scale_factor()),
|
||||
source: PointerSource::Mouse,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -34,6 +34,9 @@ pub struct WinitViewState {
|
|||
rotation_last_delta: Cell<CGFloat>,
|
||||
pinch_last_delta: Cell<CGFloat>,
|
||||
pan_last_delta: Cell<CGPoint>,
|
||||
|
||||
primary_finger: Cell<Option<usize>>,
|
||||
fingers: Cell<u8>,
|
||||
}
|
||||
|
||||
declare_class!(
|
||||
|
|
@ -371,6 +374,9 @@ impl WinitView {
|
|||
rotation_last_delta: Cell::new(0.0),
|
||||
pinch_last_delta: Cell::new(0.0),
|
||||
pan_last_delta: Cell::new(CGPoint { x: 0.0, y: 0.0 }),
|
||||
|
||||
primary_finger: Cell::new(None),
|
||||
fingers: Cell::new(0),
|
||||
});
|
||||
let this: Retained<Self> = unsafe { msg_send_id![super(this), initWithFrame: frame] };
|
||||
|
||||
|
|
@ -515,12 +521,33 @@ impl WinitView {
|
|||
let window_id = window.id();
|
||||
let finger_id = RootFingerId(FingerId(touch_id));
|
||||
|
||||
let ivars = self.ivars();
|
||||
|
||||
match phase {
|
||||
UITouchPhase::Began => {
|
||||
let primary = if let UITouchType::Pencil = touch_type {
|
||||
true
|
||||
} else {
|
||||
ivars.fingers.set(ivars.fingers.get() + 1);
|
||||
match ivars.primary_finger.get() {
|
||||
Some(primary_id) => primary_id == touch_id,
|
||||
None => {
|
||||
debug_assert_eq!(
|
||||
ivars.fingers.get(),
|
||||
1,
|
||||
"number of fingers were not counted correctly"
|
||||
);
|
||||
ivars.primary_finger.set(Some(touch_id));
|
||||
true
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
touch_events.push(EventWrapper::StaticEvent(Event::WindowEvent {
|
||||
window_id,
|
||||
event: WindowEvent::PointerEntered {
|
||||
device_id: None,
|
||||
primary,
|
||||
position,
|
||||
kind: if let UITouchType::Pencil = touch_type {
|
||||
PointerKind::Unknown
|
||||
|
|
@ -533,6 +560,7 @@ impl WinitView {
|
|||
window_id,
|
||||
event: WindowEvent::PointerButton {
|
||||
device_id: None,
|
||||
primary,
|
||||
state: ElementState::Pressed,
|
||||
position,
|
||||
button: if let UITouchType::Pencil = touch_type {
|
||||
|
|
@ -544,26 +572,44 @@ impl WinitView {
|
|||
}));
|
||||
},
|
||||
UITouchPhase::Moved => {
|
||||
let (primary, source) = if let UITouchType::Pencil = touch_type {
|
||||
(true, PointerSource::Unknown)
|
||||
} else {
|
||||
(ivars.primary_finger.get().unwrap() == touch_id, PointerSource::Touch {
|
||||
finger_id,
|
||||
force,
|
||||
})
|
||||
};
|
||||
|
||||
touch_events.push(EventWrapper::StaticEvent(Event::WindowEvent {
|
||||
window_id,
|
||||
event: WindowEvent::PointerMoved {
|
||||
device_id: None,
|
||||
primary,
|
||||
position,
|
||||
source: if let UITouchType::Pencil = touch_type {
|
||||
PointerSource::Unknown
|
||||
} else {
|
||||
PointerSource::Touch { finger_id, force }
|
||||
},
|
||||
source,
|
||||
},
|
||||
}));
|
||||
},
|
||||
// 2 is UITouchPhase::Stationary and is not expected here
|
||||
UITouchPhase::Ended | UITouchPhase::Cancelled => {
|
||||
let primary = if let UITouchType::Pencil = touch_type {
|
||||
true
|
||||
} else {
|
||||
ivars.fingers.set(ivars.fingers.get() - 1);
|
||||
let primary = ivars.primary_finger.get().unwrap() == touch_id;
|
||||
if ivars.fingers.get() == 0 {
|
||||
ivars.primary_finger.set(None);
|
||||
}
|
||||
primary
|
||||
};
|
||||
|
||||
if let UITouchPhase::Ended = phase {
|
||||
touch_events.push(EventWrapper::StaticEvent(Event::WindowEvent {
|
||||
window_id,
|
||||
event: WindowEvent::PointerButton {
|
||||
device_id: None,
|
||||
primary,
|
||||
state: ElementState::Released,
|
||||
position,
|
||||
button: if let UITouchType::Pencil = touch_type {
|
||||
|
|
@ -579,6 +625,7 @@ impl WinitView {
|
|||
window_id,
|
||||
event: WindowEvent::PointerLeft {
|
||||
device_id: None,
|
||||
primary,
|
||||
position: Some(position),
|
||||
kind: if let UITouchType::Pencil = touch_type {
|
||||
PointerKind::Unknown
|
||||
|
|
|
|||
|
|
@ -40,6 +40,9 @@ pub struct WinitSeatState {
|
|||
/// The mapping from touched points to the surfaces they're present.
|
||||
touch_map: AHashMap<i32, TouchPoint>,
|
||||
|
||||
/// Id of the first touch event.
|
||||
first_touch_id: Option<i32>,
|
||||
|
||||
/// The text input bound on the seat.
|
||||
text_input: Option<Arc<ZwpTextInputV3>>,
|
||||
|
||||
|
|
|
|||
|
|
@ -124,6 +124,7 @@ impl PointerHandler for WinitState {
|
|||
PointerEventKind::Enter { .. } => {
|
||||
self.events_sink.push_window_event(
|
||||
WindowEvent::PointerEntered {
|
||||
primary: true,
|
||||
device_id: None,
|
||||
position,
|
||||
kind: PointerKind::Mouse,
|
||||
|
|
@ -144,6 +145,7 @@ impl PointerHandler for WinitState {
|
|||
|
||||
self.events_sink.push_window_event(
|
||||
WindowEvent::PointerLeft {
|
||||
primary: true,
|
||||
device_id: None,
|
||||
position: Some(position),
|
||||
kind: PointerKind::Mouse,
|
||||
|
|
@ -154,6 +156,7 @@ impl PointerHandler for WinitState {
|
|||
PointerEventKind::Motion { .. } => {
|
||||
self.events_sink.push_window_event(
|
||||
WindowEvent::PointerMoved {
|
||||
primary: true,
|
||||
device_id: None,
|
||||
position,
|
||||
source: PointerSource::Mouse,
|
||||
|
|
@ -174,6 +177,7 @@ impl PointerHandler for WinitState {
|
|||
};
|
||||
self.events_sink.push_window_event(
|
||||
WindowEvent::PointerButton {
|
||||
primary: true,
|
||||
device_id: None,
|
||||
state,
|
||||
position,
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ impl TouchHandler for WinitState {
|
|||
// Update the state of the point.
|
||||
let location = LogicalPosition::<f64>::from(position);
|
||||
seat_state.touch_map.insert(id, TouchPoint { surface, location });
|
||||
let primary = seat_state.first_touch_id.get_or_insert(id) == &id;
|
||||
|
||||
let position = location.to_physical(scale_factor);
|
||||
let finger_id =
|
||||
|
|
@ -49,6 +50,7 @@ impl TouchHandler for WinitState {
|
|||
self.events_sink.push_window_event(
|
||||
WindowEvent::PointerEntered {
|
||||
device_id: None,
|
||||
primary,
|
||||
position,
|
||||
kind: PointerKind::Touch(finger_id),
|
||||
},
|
||||
|
|
@ -57,6 +59,7 @@ impl TouchHandler for WinitState {
|
|||
self.events_sink.push_window_event(
|
||||
WindowEvent::PointerButton {
|
||||
device_id: None,
|
||||
primary,
|
||||
state: ElementState::Pressed,
|
||||
position,
|
||||
button: ButtonSource::Touch { finger_id, force: None },
|
||||
|
|
@ -88,6 +91,12 @@ impl TouchHandler for WinitState {
|
|||
None => return,
|
||||
};
|
||||
|
||||
// Update the primary touch point.
|
||||
let primary = seat_state.first_touch_id == Some(id);
|
||||
if primary {
|
||||
seat_state.first_touch_id = None;
|
||||
}
|
||||
|
||||
let window_id = wayland::make_wid(&touch_point.surface);
|
||||
let scale_factor = match self.windows.get_mut().get(&window_id) {
|
||||
Some(window) => window.lock().unwrap().scale_factor(),
|
||||
|
|
@ -101,6 +110,7 @@ impl TouchHandler for WinitState {
|
|||
self.events_sink.push_window_event(
|
||||
WindowEvent::PointerButton {
|
||||
device_id: None,
|
||||
primary,
|
||||
state: ElementState::Released,
|
||||
position,
|
||||
button: ButtonSource::Touch { finger_id, force: None },
|
||||
|
|
@ -110,6 +120,7 @@ impl TouchHandler for WinitState {
|
|||
self.events_sink.push_window_event(
|
||||
WindowEvent::PointerLeft {
|
||||
device_id: None,
|
||||
primary,
|
||||
position: Some(position),
|
||||
kind: PointerKind::Touch(finger_id),
|
||||
},
|
||||
|
|
@ -140,6 +151,8 @@ impl TouchHandler for WinitState {
|
|||
None => return,
|
||||
};
|
||||
|
||||
let primary = seat_state.first_touch_id == Some(id);
|
||||
|
||||
let window_id = wayland::make_wid(&touch_point.surface);
|
||||
let scale_factor = match self.windows.get_mut().get(&window_id) {
|
||||
Some(window) => window.lock().unwrap().scale_factor(),
|
||||
|
|
@ -151,6 +164,7 @@ impl TouchHandler for WinitState {
|
|||
self.events_sink.push_window_event(
|
||||
WindowEvent::PointerMoved {
|
||||
device_id: None,
|
||||
primary,
|
||||
position: touch_point.location.to_physical(scale_factor),
|
||||
source: PointerSource::Touch {
|
||||
finger_id: crate::event::FingerId(crate::platform_impl::FingerId::Wayland(
|
||||
|
|
@ -179,11 +193,13 @@ impl TouchHandler for WinitState {
|
|||
None => return,
|
||||
};
|
||||
|
||||
let primary = seat_state.first_touch_id == Some(id);
|
||||
let position = touch_point.location.to_physical(scale_factor);
|
||||
|
||||
self.events_sink.push_window_event(
|
||||
WindowEvent::PointerLeft {
|
||||
device_id: None,
|
||||
primary,
|
||||
position: Some(position),
|
||||
kind: PointerKind::Touch(crate::event::FingerId(
|
||||
crate::platform_impl::FingerId::Wayland(FingerId(id)),
|
||||
|
|
@ -192,6 +208,8 @@ impl TouchHandler for WinitState {
|
|||
window_id,
|
||||
);
|
||||
}
|
||||
|
||||
seat_state.first_touch_id = None;
|
||||
}
|
||||
|
||||
fn shape(
|
||||
|
|
|
|||
|
|
@ -1034,12 +1034,14 @@ impl EventProcessor {
|
|||
let event = match event.detail as u32 {
|
||||
xlib::Button1 => WindowEvent::PointerButton {
|
||||
device_id,
|
||||
primary: true,
|
||||
state,
|
||||
position,
|
||||
button: MouseButton::Left.into(),
|
||||
},
|
||||
xlib::Button2 => WindowEvent::PointerButton {
|
||||
device_id,
|
||||
primary: true,
|
||||
state,
|
||||
position,
|
||||
button: MouseButton::Middle.into(),
|
||||
|
|
@ -1047,6 +1049,7 @@ impl EventProcessor {
|
|||
|
||||
xlib::Button3 => WindowEvent::PointerButton {
|
||||
device_id,
|
||||
primary: true,
|
||||
state,
|
||||
position,
|
||||
button: MouseButton::Right.into(),
|
||||
|
|
@ -1069,6 +1072,7 @@ impl EventProcessor {
|
|||
},
|
||||
8 => WindowEvent::PointerButton {
|
||||
device_id,
|
||||
primary: true,
|
||||
state,
|
||||
position,
|
||||
button: MouseButton::Back.into(),
|
||||
|
|
@ -1076,12 +1080,14 @@ impl EventProcessor {
|
|||
|
||||
9 => WindowEvent::PointerButton {
|
||||
device_id,
|
||||
primary: true,
|
||||
state,
|
||||
position,
|
||||
button: MouseButton::Forward.into(),
|
||||
},
|
||||
x => WindowEvent::PointerButton {
|
||||
device_id,
|
||||
primary: true,
|
||||
state,
|
||||
position,
|
||||
button: MouseButton::Other(x as u16).into(),
|
||||
|
|
@ -1116,6 +1122,7 @@ impl EventProcessor {
|
|||
window_id,
|
||||
event: WindowEvent::PointerMoved {
|
||||
device_id,
|
||||
primary: true,
|
||||
position,
|
||||
source: PointerSource::Mouse,
|
||||
},
|
||||
|
|
@ -1205,6 +1212,7 @@ impl EventProcessor {
|
|||
window_id,
|
||||
event: WindowEvent::PointerEntered {
|
||||
device_id,
|
||||
primary: true,
|
||||
position,
|
||||
kind: PointerKind::Mouse,
|
||||
},
|
||||
|
|
@ -1229,6 +1237,7 @@ impl EventProcessor {
|
|||
window_id: mkwid(window),
|
||||
event: WindowEvent::PointerLeft {
|
||||
device_id: Some(mkdid(event.deviceid as xinput::DeviceId)),
|
||||
primary: true,
|
||||
position: Some(PhysicalPosition::new(event.event_x, event.event_y)),
|
||||
kind: PointerKind::Mouse,
|
||||
},
|
||||
|
|
@ -1289,7 +1298,12 @@ impl EventProcessor {
|
|||
|
||||
let event = Event::WindowEvent {
|
||||
window_id,
|
||||
event: WindowEvent::PointerMoved { device_id, position, source: PointerSource::Mouse },
|
||||
event: WindowEvent::PointerMoved {
|
||||
device_id,
|
||||
primary: true,
|
||||
position,
|
||||
source: PointerSource::Mouse,
|
||||
},
|
||||
};
|
||||
callback(&self.target, event);
|
||||
}
|
||||
|
|
@ -1360,11 +1374,14 @@ impl EventProcessor {
|
|||
|
||||
// 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) {
|
||||
let is_first_touch =
|
||||
is_first_touch(&mut self.first_touch, &mut self.num_touch, id, phase);
|
||||
if is_first_touch {
|
||||
let event = Event::WindowEvent {
|
||||
window_id,
|
||||
event: WindowEvent::PointerMoved {
|
||||
device_id: None,
|
||||
primary: true,
|
||||
position: position.cast(),
|
||||
source: PointerSource::Mouse,
|
||||
},
|
||||
|
|
@ -1381,6 +1398,7 @@ impl EventProcessor {
|
|||
window_id,
|
||||
event: WindowEvent::PointerEntered {
|
||||
device_id,
|
||||
primary: is_first_touch,
|
||||
position,
|
||||
kind: PointerKind::Touch(finger_id),
|
||||
},
|
||||
|
|
@ -1390,6 +1408,7 @@ impl EventProcessor {
|
|||
window_id,
|
||||
event: WindowEvent::PointerButton {
|
||||
device_id,
|
||||
primary: is_first_touch,
|
||||
state: ElementState::Pressed,
|
||||
position,
|
||||
button: ButtonSource::Touch { finger_id, force: None },
|
||||
|
|
@ -1402,6 +1421,7 @@ impl EventProcessor {
|
|||
window_id,
|
||||
event: WindowEvent::PointerMoved {
|
||||
device_id,
|
||||
primary: is_first_touch,
|
||||
position,
|
||||
source: PointerSource::Touch { finger_id, force: None },
|
||||
},
|
||||
|
|
@ -1413,6 +1433,7 @@ impl EventProcessor {
|
|||
window_id,
|
||||
event: WindowEvent::PointerButton {
|
||||
device_id,
|
||||
primary: is_first_touch,
|
||||
state: ElementState::Released,
|
||||
position,
|
||||
button: ButtonSource::Touch { finger_id, force: None },
|
||||
|
|
@ -1423,6 +1444,7 @@ impl EventProcessor {
|
|||
window_id,
|
||||
event: WindowEvent::PointerLeft {
|
||||
device_id,
|
||||
primary: is_first_touch,
|
||||
position: Some(position),
|
||||
kind: PointerKind::Touch(finger_id),
|
||||
},
|
||||
|
|
|
|||
|
|
@ -404,6 +404,7 @@ impl EventLoop {
|
|||
EventOption::Mouse(MouseEvent { x, y }) => {
|
||||
app.window_event(window_target, window_id, event::WindowEvent::PointerMoved {
|
||||
device_id: None,
|
||||
primary: true,
|
||||
position: (x, y).into(),
|
||||
source: event::PointerSource::Mouse,
|
||||
});
|
||||
|
|
@ -417,6 +418,7 @@ impl EventLoop {
|
|||
while let Some((button, state)) = event_state.mouse(left, middle, right) {
|
||||
app.window_event(window_target, window_id, event::WindowEvent::PointerButton {
|
||||
device_id: None,
|
||||
primary: true,
|
||||
state,
|
||||
position: dpi::PhysicalPosition::default(),
|
||||
button: button.into(),
|
||||
|
|
@ -458,12 +460,14 @@ impl EventLoop {
|
|||
let event = if entered {
|
||||
event::WindowEvent::PointerEntered {
|
||||
device_id: None,
|
||||
primary: true,
|
||||
position: dpi::PhysicalPosition::default(),
|
||||
kind: event::PointerKind::Mouse,
|
||||
}
|
||||
} else {
|
||||
event::WindowEvent::PointerLeft {
|
||||
device_id: None,
|
||||
primary: true,
|
||||
position: None,
|
||||
kind: event::PointerKind::Mouse,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,21 +14,16 @@ pub(crate) fn mkdid(pointer_id: i32) -> Option<DeviceId> {
|
|||
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
pub struct FingerId {
|
||||
pointer_id: i32,
|
||||
primary: bool,
|
||||
}
|
||||
|
||||
impl FingerId {
|
||||
pub fn new(pointer_id: i32, primary: bool) -> Self {
|
||||
Self { pointer_id, primary }
|
||||
pub fn new(pointer_id: i32) -> Self {
|
||||
Self { pointer_id }
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub const fn dummy() -> Self {
|
||||
Self { pointer_id: -1, primary: false }
|
||||
}
|
||||
|
||||
pub fn is_primary(self) -> bool {
|
||||
self.primary
|
||||
Self { pointer_id: -1 }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -197,7 +197,7 @@ impl ActiveEventLoop {
|
|||
let has_focus = has_focus.clone();
|
||||
let modifiers = self.modifiers.clone();
|
||||
|
||||
move |active_modifiers, device_id, position, kind| {
|
||||
move |active_modifiers, device_id, primary, position, kind| {
|
||||
let focus = (has_focus.get() && modifiers.get() != active_modifiers).then(|| {
|
||||
modifiers.set(active_modifiers);
|
||||
Event::WindowEvent {
|
||||
|
|
@ -208,7 +208,12 @@ impl ActiveEventLoop {
|
|||
|
||||
runner.send_events(focus.into_iter().chain(iter::once(Event::WindowEvent {
|
||||
window_id,
|
||||
event: WindowEvent::PointerLeft { device_id, position: Some(position), kind },
|
||||
event: WindowEvent::PointerLeft {
|
||||
device_id,
|
||||
primary,
|
||||
position: Some(position),
|
||||
kind,
|
||||
},
|
||||
})))
|
||||
}
|
||||
});
|
||||
|
|
@ -218,7 +223,7 @@ impl ActiveEventLoop {
|
|||
let has_focus = has_focus.clone();
|
||||
let modifiers = self.modifiers.clone();
|
||||
|
||||
move |active_modifiers, device_id, position, kind| {
|
||||
move |active_modifiers, device_id, primary, position, kind| {
|
||||
let focus = (has_focus.get() && modifiers.get() != active_modifiers).then(|| {
|
||||
modifiers.set(active_modifiers);
|
||||
Event::WindowEvent {
|
||||
|
|
@ -229,7 +234,7 @@ impl ActiveEventLoop {
|
|||
|
||||
runner.send_events(focus.into_iter().chain(iter::once(Event::WindowEvent {
|
||||
window_id,
|
||||
event: WindowEvent::PointerEntered { device_id, position, kind },
|
||||
event: WindowEvent::PointerEntered { device_id, primary, position, kind },
|
||||
})))
|
||||
}
|
||||
});
|
||||
|
|
@ -241,21 +246,31 @@ impl ActiveEventLoop {
|
|||
let modifiers = self.modifiers.clone();
|
||||
|
||||
move |device_id, events| {
|
||||
runner.send_events(events.flat_map(|(active_modifiers, position, source)| {
|
||||
let modifiers = (has_focus.get() && modifiers.get() != active_modifiers)
|
||||
.then(|| {
|
||||
modifiers.set(active_modifiers);
|
||||
Event::WindowEvent {
|
||||
window_id,
|
||||
event: WindowEvent::ModifiersChanged(active_modifiers.into()),
|
||||
}
|
||||
});
|
||||
runner.send_events(events.flat_map(
|
||||
|(active_modifiers, primary, position, source)| {
|
||||
let modifiers = (has_focus.get()
|
||||
&& modifiers.get() != active_modifiers)
|
||||
.then(|| {
|
||||
modifiers.set(active_modifiers);
|
||||
Event::WindowEvent {
|
||||
window_id,
|
||||
event: WindowEvent::ModifiersChanged(
|
||||
active_modifiers.into(),
|
||||
),
|
||||
}
|
||||
});
|
||||
|
||||
modifiers.into_iter().chain(iter::once(Event::WindowEvent {
|
||||
window_id,
|
||||
event: WindowEvent::PointerMoved { device_id, position, source },
|
||||
}))
|
||||
}));
|
||||
modifiers.into_iter().chain(iter::once(Event::WindowEvent {
|
||||
window_id,
|
||||
event: WindowEvent::PointerMoved {
|
||||
device_id,
|
||||
primary,
|
||||
position,
|
||||
source,
|
||||
},
|
||||
}))
|
||||
},
|
||||
));
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
@ -263,7 +278,7 @@ impl ActiveEventLoop {
|
|||
let has_focus = has_focus.clone();
|
||||
let modifiers = self.modifiers.clone();
|
||||
|
||||
move |active_modifiers, device_id, position, state, button| {
|
||||
move |active_modifiers, device_id, primary, position, state, button| {
|
||||
let modifiers =
|
||||
(has_focus.get() && modifiers.get() != active_modifiers).then(|| {
|
||||
modifiers.set(active_modifiers);
|
||||
|
|
@ -275,7 +290,13 @@ impl ActiveEventLoop {
|
|||
|
||||
runner.send_events(modifiers.into_iter().chain([Event::WindowEvent {
|
||||
window_id,
|
||||
event: WindowEvent::PointerButton { device_id, state, position, button },
|
||||
event: WindowEvent::PointerButton {
|
||||
device_id,
|
||||
primary,
|
||||
state,
|
||||
position,
|
||||
button,
|
||||
},
|
||||
}]));
|
||||
}
|
||||
},
|
||||
|
|
@ -285,7 +306,7 @@ impl ActiveEventLoop {
|
|||
let runner = self.runner.clone();
|
||||
let modifiers = self.modifiers.clone();
|
||||
|
||||
move |active_modifiers, device_id, position, button| {
|
||||
move |active_modifiers, device_id, primary, position, button| {
|
||||
let modifiers = (modifiers.get() != active_modifiers).then(|| {
|
||||
modifiers.set(active_modifiers);
|
||||
Event::WindowEvent {
|
||||
|
|
@ -298,6 +319,7 @@ impl ActiveEventLoop {
|
|||
window_id,
|
||||
event: WindowEvent::PointerButton {
|
||||
device_id,
|
||||
primary,
|
||||
state: ElementState::Pressed,
|
||||
position,
|
||||
button,
|
||||
|
|
@ -311,7 +333,7 @@ impl ActiveEventLoop {
|
|||
let has_focus = has_focus.clone();
|
||||
let modifiers = self.modifiers.clone();
|
||||
|
||||
move |active_modifiers, device_id, position, button| {
|
||||
move |active_modifiers, device_id, primary, position, button| {
|
||||
let modifiers =
|
||||
(has_focus.get() && modifiers.get() != active_modifiers).then(|| {
|
||||
modifiers.set(active_modifiers);
|
||||
|
|
@ -325,6 +347,7 @@ impl ActiveEventLoop {
|
|||
window_id,
|
||||
event: WindowEvent::PointerButton {
|
||||
device_id,
|
||||
primary,
|
||||
state: ElementState::Released,
|
||||
position,
|
||||
button,
|
||||
|
|
|
|||
|
|
@ -331,28 +331,32 @@ impl Canvas {
|
|||
|
||||
pub fn on_pointer_leave<F>(&self, handler: F)
|
||||
where
|
||||
F: 'static + FnMut(ModifiersState, Option<DeviceId>, PhysicalPosition<f64>, PointerKind),
|
||||
F: 'static
|
||||
+ FnMut(ModifiersState, Option<DeviceId>, bool, PhysicalPosition<f64>, PointerKind),
|
||||
{
|
||||
self.handlers.borrow_mut().pointer_handler.on_pointer_leave(&self.common, handler)
|
||||
}
|
||||
|
||||
pub fn on_pointer_enter<F>(&self, handler: F)
|
||||
where
|
||||
F: 'static + FnMut(ModifiersState, Option<DeviceId>, PhysicalPosition<f64>, PointerKind),
|
||||
F: 'static
|
||||
+ FnMut(ModifiersState, Option<DeviceId>, bool, PhysicalPosition<f64>, PointerKind),
|
||||
{
|
||||
self.handlers.borrow_mut().pointer_handler.on_pointer_enter(&self.common, handler)
|
||||
}
|
||||
|
||||
pub fn on_pointer_release<C>(&self, handler: C)
|
||||
where
|
||||
C: 'static + FnMut(ModifiersState, Option<DeviceId>, PhysicalPosition<f64>, ButtonSource),
|
||||
C: 'static
|
||||
+ FnMut(ModifiersState, Option<DeviceId>, bool, PhysicalPosition<f64>, ButtonSource),
|
||||
{
|
||||
self.handlers.borrow_mut().pointer_handler.on_pointer_release(&self.common, handler)
|
||||
}
|
||||
|
||||
pub fn on_pointer_press<C>(&self, handler: C)
|
||||
where
|
||||
C: 'static + FnMut(ModifiersState, Option<DeviceId>, PhysicalPosition<f64>, ButtonSource),
|
||||
C: 'static
|
||||
+ FnMut(ModifiersState, Option<DeviceId>, bool, PhysicalPosition<f64>, ButtonSource),
|
||||
{
|
||||
self.handlers.borrow_mut().pointer_handler.on_pointer_press(
|
||||
&self.common,
|
||||
|
|
@ -366,12 +370,15 @@ impl Canvas {
|
|||
C: 'static
|
||||
+ FnMut(
|
||||
Option<DeviceId>,
|
||||
&mut dyn Iterator<Item = (ModifiersState, PhysicalPosition<f64>, PointerSource)>,
|
||||
&mut dyn Iterator<
|
||||
Item = (ModifiersState, bool, PhysicalPosition<f64>, PointerSource),
|
||||
>,
|
||||
),
|
||||
B: 'static
|
||||
+ FnMut(
|
||||
ModifiersState,
|
||||
Option<DeviceId>,
|
||||
bool,
|
||||
PhysicalPosition<f64>,
|
||||
ElementState,
|
||||
ButtonSource,
|
||||
|
|
|
|||
|
|
@ -164,7 +164,7 @@ pub fn mouse_scroll_delta(
|
|||
pub fn pointer_type(event: &PointerEvent, pointer_id: i32) -> PointerKind {
|
||||
match event.pointer_type().as_str() {
|
||||
"mouse" => PointerKind::Mouse,
|
||||
"touch" => PointerKind::Touch(FingerId::new(pointer_id, event.is_primary()).into()),
|
||||
"touch" => PointerKind::Touch(FingerId::new(pointer_id).into()),
|
||||
_ => PointerKind::Unknown,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,7 +35,8 @@ impl PointerHandler {
|
|||
|
||||
pub fn on_pointer_leave<F>(&mut self, canvas_common: &Common, mut handler: F)
|
||||
where
|
||||
F: 'static + FnMut(ModifiersState, Option<DeviceId>, PhysicalPosition<f64>, PointerKind),
|
||||
F: 'static
|
||||
+ FnMut(ModifiersState, Option<DeviceId>, bool, PhysicalPosition<f64>, PointerKind),
|
||||
{
|
||||
let window = canvas_common.window.clone();
|
||||
self.on_cursor_leave =
|
||||
|
|
@ -46,13 +47,14 @@ impl PointerHandler {
|
|||
let position =
|
||||
event::mouse_position(&event).to_physical(super::scale_factor(&window));
|
||||
let kind = event::pointer_type(&event, pointer_id);
|
||||
handler(modifiers, device_id, position, kind);
|
||||
handler(modifiers, device_id, event.is_primary(), position, kind);
|
||||
}));
|
||||
}
|
||||
|
||||
pub fn on_pointer_enter<F>(&mut self, canvas_common: &Common, mut handler: F)
|
||||
where
|
||||
F: 'static + FnMut(ModifiersState, Option<DeviceId>, PhysicalPosition<f64>, PointerKind),
|
||||
F: 'static
|
||||
+ FnMut(ModifiersState, Option<DeviceId>, bool, PhysicalPosition<f64>, PointerKind),
|
||||
{
|
||||
let window = canvas_common.window.clone();
|
||||
self.on_cursor_enter =
|
||||
|
|
@ -63,13 +65,14 @@ impl PointerHandler {
|
|||
let position =
|
||||
event::mouse_position(&event).to_physical(super::scale_factor(&window));
|
||||
let kind = event::pointer_type(&event, pointer_id);
|
||||
handler(modifiers, device_id, position, kind);
|
||||
handler(modifiers, device_id, event.is_primary(), position, kind);
|
||||
}));
|
||||
}
|
||||
|
||||
pub fn on_pointer_release<C>(&mut self, canvas_common: &Common, mut handler: C)
|
||||
where
|
||||
C: 'static + FnMut(ModifiersState, Option<DeviceId>, PhysicalPosition<f64>, ButtonSource),
|
||||
C: 'static
|
||||
+ FnMut(ModifiersState, Option<DeviceId>, bool, PhysicalPosition<f64>, ButtonSource),
|
||||
{
|
||||
let window = canvas_common.window.clone();
|
||||
self.on_pointer_release =
|
||||
|
|
@ -92,6 +95,7 @@ impl PointerHandler {
|
|||
handler(
|
||||
modifiers,
|
||||
mkdid(pointer_id),
|
||||
event.is_primary(),
|
||||
event::mouse_position(&event).to_physical(super::scale_factor(&window)),
|
||||
source,
|
||||
)
|
||||
|
|
@ -104,7 +108,8 @@ impl PointerHandler {
|
|||
mut handler: C,
|
||||
prevent_default: Rc<Cell<bool>>,
|
||||
) where
|
||||
C: 'static + FnMut(ModifiersState, Option<DeviceId>, PhysicalPosition<f64>, ButtonSource),
|
||||
C: 'static
|
||||
+ FnMut(ModifiersState, Option<DeviceId>, bool, PhysicalPosition<f64>, ButtonSource),
|
||||
{
|
||||
let window = canvas_common.window.clone();
|
||||
let canvas = canvas_common.raw().clone();
|
||||
|
|
@ -143,6 +148,7 @@ impl PointerHandler {
|
|||
handler(
|
||||
modifiers,
|
||||
mkdid(pointer_id),
|
||||
event.is_primary(),
|
||||
event::mouse_position(&event).to_physical(super::scale_factor(&window)),
|
||||
source,
|
||||
)
|
||||
|
|
@ -159,12 +165,15 @@ impl PointerHandler {
|
|||
C: 'static
|
||||
+ FnMut(
|
||||
Option<DeviceId>,
|
||||
&mut dyn Iterator<Item = (ModifiersState, PhysicalPosition<f64>, PointerSource)>,
|
||||
&mut dyn Iterator<
|
||||
Item = (ModifiersState, bool, PhysicalPosition<f64>, PointerSource),
|
||||
>,
|
||||
),
|
||||
B: 'static
|
||||
+ FnMut(
|
||||
ModifiersState,
|
||||
Option<DeviceId>,
|
||||
bool,
|
||||
PhysicalPosition<f64>,
|
||||
ElementState,
|
||||
ButtonSource,
|
||||
|
|
@ -177,6 +186,7 @@ impl PointerHandler {
|
|||
let pointer_id = event.pointer_id();
|
||||
let device_id = mkdid(pointer_id);
|
||||
let kind = event::pointer_type(&event, pointer_id);
|
||||
let primary = event.is_primary();
|
||||
|
||||
// chorded button event
|
||||
if let Some(button) = event::mouse_button(&event) {
|
||||
|
|
@ -213,6 +223,7 @@ impl PointerHandler {
|
|||
button_handler(
|
||||
event::mouse_modifiers(&event),
|
||||
device_id,
|
||||
primary,
|
||||
event::mouse_position(&event).to_physical(super::scale_factor(&window)),
|
||||
state,
|
||||
button,
|
||||
|
|
@ -229,6 +240,7 @@ impl PointerHandler {
|
|||
&mut event::pointer_move_event(event).map(|event| {
|
||||
(
|
||||
event::mouse_modifiers(&event),
|
||||
event.is_primary(),
|
||||
event::mouse_position(&event).to_physical(scale),
|
||||
match kind {
|
||||
PointerKind::Mouse => PointerSource::Mouse,
|
||||
|
|
|
|||
|
|
@ -1621,6 +1621,7 @@ unsafe fn public_window_callback_inner(
|
|||
window_id: WindowId::from_raw(window as usize),
|
||||
event: PointerEntered {
|
||||
device_id: None,
|
||||
primary: true,
|
||||
position,
|
||||
kind: PointerKind::Mouse,
|
||||
},
|
||||
|
|
@ -1646,6 +1647,7 @@ unsafe fn public_window_callback_inner(
|
|||
window_id: WindowId::from_raw(window as usize),
|
||||
event: PointerLeft {
|
||||
device_id: None,
|
||||
primary: true,
|
||||
position: Some(position),
|
||||
kind: PointerKind::Mouse,
|
||||
},
|
||||
|
|
@ -1667,7 +1669,12 @@ unsafe fn public_window_callback_inner(
|
|||
|
||||
userdata.send_event(Event::WindowEvent {
|
||||
window_id: WindowId::from_raw(window as usize),
|
||||
event: PointerMoved { device_id: None, position, source: PointerSource::Mouse },
|
||||
event: PointerMoved {
|
||||
device_id: None,
|
||||
primary: true,
|
||||
position,
|
||||
source: PointerSource::Mouse,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -1685,7 +1692,7 @@ unsafe fn public_window_callback_inner(
|
|||
|
||||
userdata.send_event(Event::WindowEvent {
|
||||
window_id: WindowId::from_raw(window as usize),
|
||||
event: PointerLeft { device_id: None, position: None, kind: Mouse },
|
||||
event: PointerLeft { device_id: None, primary: true, position: None, kind: Mouse },
|
||||
});
|
||||
|
||||
result = ProcResult::Value(0);
|
||||
|
|
@ -1762,6 +1769,7 @@ unsafe fn public_window_callback_inner(
|
|||
window_id: WindowId::from_raw(window as usize),
|
||||
event: PointerButton {
|
||||
device_id: None,
|
||||
primary: true,
|
||||
state: Pressed,
|
||||
position,
|
||||
button: Left.into(),
|
||||
|
|
@ -1787,6 +1795,7 @@ unsafe fn public_window_callback_inner(
|
|||
window_id: WindowId::from_raw(window as usize),
|
||||
event: PointerButton {
|
||||
device_id: None,
|
||||
primary: true,
|
||||
state: Released,
|
||||
position,
|
||||
button: Left.into(),
|
||||
|
|
@ -1812,6 +1821,7 @@ unsafe fn public_window_callback_inner(
|
|||
window_id: WindowId::from_raw(window as usize),
|
||||
event: PointerButton {
|
||||
device_id: None,
|
||||
primary: true,
|
||||
state: Pressed,
|
||||
position,
|
||||
button: Right.into(),
|
||||
|
|
@ -1837,6 +1847,7 @@ unsafe fn public_window_callback_inner(
|
|||
window_id: WindowId::from_raw(window as usize),
|
||||
event: PointerButton {
|
||||
device_id: None,
|
||||
primary: true,
|
||||
state: Released,
|
||||
position,
|
||||
button: Right.into(),
|
||||
|
|
@ -1862,6 +1873,7 @@ unsafe fn public_window_callback_inner(
|
|||
window_id: WindowId::from_raw(window as usize),
|
||||
event: PointerButton {
|
||||
device_id: None,
|
||||
primary: true,
|
||||
state: Pressed,
|
||||
position,
|
||||
button: Middle.into(),
|
||||
|
|
@ -1887,6 +1899,7 @@ unsafe fn public_window_callback_inner(
|
|||
window_id: WindowId::from_raw(window as usize),
|
||||
event: PointerButton {
|
||||
device_id: None,
|
||||
primary: true,
|
||||
state: Released,
|
||||
position,
|
||||
button: Middle.into(),
|
||||
|
|
@ -1913,6 +1926,7 @@ unsafe fn public_window_callback_inner(
|
|||
window_id: WindowId::from_raw(window as usize),
|
||||
event: PointerButton {
|
||||
device_id: None,
|
||||
primary: true,
|
||||
state: Pressed,
|
||||
position,
|
||||
button: match xbutton {
|
||||
|
|
@ -1944,6 +1958,7 @@ unsafe fn public_window_callback_inner(
|
|||
window_id: WindowId::from_raw(window as usize),
|
||||
event: PointerButton {
|
||||
device_id: None,
|
||||
primary: true,
|
||||
state: Released,
|
||||
position,
|
||||
button: match xbutton {
|
||||
|
|
@ -1997,16 +2012,15 @@ unsafe fn public_window_callback_inner(
|
|||
let position = PhysicalPosition::new(x, y);
|
||||
|
||||
let window_id = WindowId::from_raw(window as usize);
|
||||
let finger_id = RootFingerId(FingerId {
|
||||
id: input.dwID,
|
||||
primary: util::has_flag(input.dwFlags, TOUCHEVENTF_PRIMARY),
|
||||
});
|
||||
let finger_id = RootFingerId(FingerId { id: input.dwID });
|
||||
let primary = util::has_flag(input.dwFlags, TOUCHEVENTF_PRIMARY);
|
||||
|
||||
if util::has_flag(input.dwFlags, TOUCHEVENTF_DOWN) {
|
||||
userdata.send_event(Event::WindowEvent {
|
||||
window_id,
|
||||
event: WindowEvent::PointerEntered {
|
||||
device_id: None,
|
||||
primary,
|
||||
position,
|
||||
kind: PointerKind::Touch(finger_id),
|
||||
},
|
||||
|
|
@ -2015,6 +2029,7 @@ unsafe fn public_window_callback_inner(
|
|||
window_id,
|
||||
event: WindowEvent::PointerButton {
|
||||
device_id: None,
|
||||
primary,
|
||||
state: Pressed,
|
||||
position,
|
||||
button: Touch { finger_id, force: None },
|
||||
|
|
@ -2025,6 +2040,7 @@ unsafe fn public_window_callback_inner(
|
|||
window_id,
|
||||
event: WindowEvent::PointerButton {
|
||||
device_id: None,
|
||||
primary,
|
||||
state: Released,
|
||||
position,
|
||||
button: Touch { finger_id, force: None },
|
||||
|
|
@ -2034,6 +2050,7 @@ unsafe fn public_window_callback_inner(
|
|||
window_id,
|
||||
event: WindowEvent::PointerLeft {
|
||||
device_id: None,
|
||||
primary,
|
||||
position: Some(position),
|
||||
kind: PointerKind::Touch(finger_id),
|
||||
},
|
||||
|
|
@ -2043,6 +2060,7 @@ unsafe fn public_window_callback_inner(
|
|||
window_id,
|
||||
event: WindowEvent::PointerMoved {
|
||||
device_id: None,
|
||||
primary,
|
||||
position,
|
||||
source: PointerSource::Touch { finger_id, force: None },
|
||||
},
|
||||
|
|
@ -2165,16 +2183,15 @@ unsafe fn public_window_callback_inner(
|
|||
let position = PhysicalPosition::new(x, y);
|
||||
|
||||
let window_id = WindowId::from_raw(window as usize);
|
||||
let finger_id = RootFingerId(FingerId {
|
||||
id: pointer_info.pointerId,
|
||||
primary: util::has_flag(pointer_info.pointerFlags, POINTER_FLAG_PRIMARY),
|
||||
});
|
||||
let finger_id = RootFingerId(FingerId { id: pointer_info.pointerId });
|
||||
let primary = util::has_flag(pointer_info.pointerFlags, POINTER_FLAG_PRIMARY);
|
||||
|
||||
if util::has_flag(pointer_info.pointerFlags, POINTER_FLAG_DOWN) {
|
||||
userdata.send_event(Event::WindowEvent {
|
||||
window_id,
|
||||
event: WindowEvent::PointerEntered {
|
||||
device_id: None,
|
||||
primary,
|
||||
position,
|
||||
kind: if let PT_TOUCH = pointer_info.pointerType {
|
||||
PointerKind::Touch(finger_id)
|
||||
|
|
@ -2187,6 +2204,7 @@ unsafe fn public_window_callback_inner(
|
|||
window_id,
|
||||
event: WindowEvent::PointerButton {
|
||||
device_id: None,
|
||||
primary,
|
||||
state: Pressed,
|
||||
position,
|
||||
button: if let PT_TOUCH = pointer_info.pointerType {
|
||||
|
|
@ -2201,6 +2219,7 @@ unsafe fn public_window_callback_inner(
|
|||
window_id,
|
||||
event: WindowEvent::PointerButton {
|
||||
device_id: None,
|
||||
primary,
|
||||
state: Released,
|
||||
position,
|
||||
button: if let PT_TOUCH = pointer_info.pointerType {
|
||||
|
|
@ -2214,6 +2233,7 @@ unsafe fn public_window_callback_inner(
|
|||
window_id,
|
||||
event: WindowEvent::PointerLeft {
|
||||
device_id: None,
|
||||
primary,
|
||||
position: Some(position),
|
||||
kind: if let PT_TOUCH = pointer_info.pointerType {
|
||||
PointerKind::Touch(finger_id)
|
||||
|
|
@ -2227,6 +2247,7 @@ unsafe fn public_window_callback_inner(
|
|||
window_id,
|
||||
event: WindowEvent::PointerMoved {
|
||||
device_id: None,
|
||||
primary,
|
||||
position,
|
||||
source: if let PT_TOUCH = pointer_info.pointerType {
|
||||
PointerSource::Touch { finger_id, force }
|
||||
|
|
|
|||
|
|
@ -62,19 +62,12 @@ unsafe impl Sync for PlatformSpecificWindowAttributes {}
|
|||
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
pub struct FingerId {
|
||||
id: u32,
|
||||
primary: bool,
|
||||
}
|
||||
|
||||
impl FingerId {
|
||||
#[cfg(test)]
|
||||
pub const fn dummy() -> Self {
|
||||
FingerId { id: 0, primary: false }
|
||||
}
|
||||
}
|
||||
|
||||
impl FingerId {
|
||||
pub fn is_primary(self) -> bool {
|
||||
self.primary
|
||||
FingerId { id: 0 }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue