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:
Kirill Chibisov 2024-10-11 20:08:51 +03:00
parent d3207a8d76
commit c8c1eca3c7
19 changed files with 346 additions and 176 deletions

View file

@ -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)
}

View file

@ -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,
});

View file

@ -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

View file

@ -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>>,

View file

@ -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,

View file

@ -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(

View file

@ -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),
},

View file

@ -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,
}

View file

@ -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 }
}
}

View file

@ -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,

View file

@ -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,

View file

@ -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,
}
}

View file

@ -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,

View file

@ -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 }

View file

@ -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 }
}
}