Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pointer API Sketch #3001

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
148 changes: 50 additions & 98 deletions src/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -378,60 +378,25 @@ pub enum WindowEvent {
/// - **iOS / Android / Web / Orbital:** Unsupported.
Ime(Ime),

/// The cursor has moved on the window.
///
/// ## Platform-specific
///
/// - **Web:** Doesn't take into account CSS [`border`], [`padding`], or [`transform`].
///
/// [`border`]: https://developer.mozilla.org/en-US/docs/Web/CSS/border
/// [`padding`]: https://developer.mozilla.org/en-US/docs/Web/CSS/padding
/// [`transform`]: https://developer.mozilla.org/en-US/docs/Web/CSS/transform
CursorMoved {
Pointer {
device_id: DeviceId,

/// (x,y) coords in pixels relative to the top-left corner of the window. Because the range of this data is
/// limited by the display area and it may have been transformed by the OS to implement effects such as cursor
/// acceleration, it should not be used to implement non-cursor-like interactions such as 3D camera control.
position: PhysicalPosition<f64>,
pointer_id: PointerId,
event: PointerEvent,
},

/// The cursor has entered the window.
///
/// ## Platform-specific
///
/// - **Web:** Doesn't take into account CSS [`border`], [`padding`], or [`transform`].
///
/// [`border`]: https://developer.mozilla.org/en-US/docs/Web/CSS/border
/// [`padding`]: https://developer.mozilla.org/en-US/docs/Web/CSS/padding
/// [`transform`]: https://developer.mozilla.org/en-US/docs/Web/CSS/transform
CursorEntered { device_id: DeviceId },

/// The cursor has left the window.
///
/// ## Platform-specific
///
/// - **Web:** Doesn't take into account CSS [`border`], [`padding`], or [`transform`].
///
/// [`border`]: https://developer.mozilla.org/en-US/docs/Web/CSS/border
/// [`padding`]: https://developer.mozilla.org/en-US/docs/Web/CSS/padding
/// [`transform`]: https://developer.mozilla.org/en-US/docs/Web/CSS/transform
CursorLeft { device_id: DeviceId },

// /// An mouse button press has been received.
// MouseInput {
// device_id: DeviceId,
// state: ElementState,
// button: MouseButton,
// },
/// A mouse wheel movement or touchpad scroll occurred.
MouseWheel {
device_id: DeviceId,
delta: MouseScrollDelta,
phase: TouchPhase,
},

/// An mouse button press has been received.
MouseInput {
device_id: DeviceId,
state: ElementState,
button: MouseButton,
},

/// Touchpad magnification event with two-finger pinch gesture.
///
/// Positive delta values indicate magnification (zooming in) and
Expand Down Expand Up @@ -497,18 +462,6 @@ pub enum WindowEvent {
value: f64,
},

/// Touch event has been received
///
/// ## Platform-specific
///
/// - **Web:** Doesn't take into account CSS [`border`], [`padding`], or [`transform`].
/// - **macOS:** Unsupported.
///
/// [`border`]: https://developer.mozilla.org/en-US/docs/Web/CSS/border
/// [`padding`]: https://developer.mozilla.org/en-US/docs/Web/CSS/padding
/// [`transform`]: https://developer.mozilla.org/en-US/docs/Web/CSS/transform
Touch(Touch),

/// The window's scale factor has changed.
///
/// The following user actions can cause DPI changes:
Expand Down Expand Up @@ -594,7 +547,7 @@ pub enum DeviceEvent {

/// Change in physical position of a pointing device.
///
/// This represents raw, unfiltered physical motion. Not to be confused with [`WindowEvent::CursorMoved`].
/// This represents raw, unfiltered physical motion. Not to be confused with cursor motion.
MouseMotion {
/// (x, y) change in position in unspecified units.
///
Expand Down Expand Up @@ -897,8 +850,7 @@ pub enum Ime {
Disabled,
}

/// Describes touch-screen input state.
#[derive(Debug, Hash, PartialEq, Eq, Clone, Copy)]
#[derive(Debug, PartialEq, Clone, Copy)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum TouchPhase {
Started,
Expand All @@ -907,45 +859,36 @@ pub enum TouchPhase {
Cancelled,
}

/// Represents a touch event
///
/// Every time the user touches the screen, a new [`TouchPhase::Started`] event with an unique
/// identifier for the finger is generated. When the finger is lifted, an [`TouchPhase::Ended`]
/// event is generated with the same finger id.
///
/// After a `Started` event has been emitted, there may be zero or more `Move`
/// events when the finger is moved or the touch pressure changes.
///
/// The finger id may be reused by the system after an `Ended` event. The user
/// should assume that a new `Started` event received with the same id has nothing
/// to do with the old finger and is a new finger.
///
/// A [`TouchPhase::Cancelled`] event is emitted when the system has canceled tracking this
/// touch, such as when the window loses focus, or on iOS if the user moves the
/// device against their face.
///
/// ## Platform-specific
///
/// - **Web:** Doesn't take into account CSS [`border`], [`padding`], or [`transform`].
/// - **macOS:** Unsupported.
///
/// [`border`]: https://developer.mozilla.org/en-US/docs/Web/CSS/border
/// [`padding`]: https://developer.mozilla.org/en-US/docs/Web/CSS/padding
/// [`transform`]: https://developer.mozilla.org/en-US/docs/Web/CSS/transform
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Touch {
pub device_id: DeviceId,
pub phase: TouchPhase,
pub location: PhysicalPosition<f64>,
/// Describes how hard the screen was pressed. May be `None` if the platform
/// does not support pressure sensitivity.
///
/// ## Platform-specific
///
/// - Only available on **iOS** 9.0+, **Windows** 8+, and **Web**.
pub force: Option<Force>,
/// Unique identifier of a finger.
pub id: u64,
#[derive(Debug, PartialEq, Clone, Copy)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum PointerEvent {
Created,
Destroyed,
Entered,
Left,
UpdateForce(Force),
UpdateTilt(Tilt),
UpdateAngle(f64),
Moved(PhysicalPosition<f64>),
Button {
button: PointerButton,
state: ElementState,
},
MotionCancelled,
}

#[derive(Debug, Hash, PartialEq, Eq, Clone, Copy)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum PointerId {
Cursor,
Touch { finger: u64 },
}

#[derive(Debug, PartialEq, Clone, Copy)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Tilt {
angle_x: f64,
angle_y: f64,
}

/// Describes the force of a touch event
Expand Down Expand Up @@ -1043,6 +986,15 @@ pub enum MouseButton {
Other(u16),
}

#[derive(Debug, Hash, PartialEq, Eq, Clone, Copy)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum PointerButton {
Mouse(MouseButton),
// Touch (probably) doesn't have any variations, different fingers
// are different pointers.
Touch,
}

/// Describes a difference in the mouse scroll wheel state.
#[derive(Debug, Clone, Copy, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
Expand Down
41 changes: 30 additions & 11 deletions src/platform_impl/linux/wayland/seat/pointer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ use sctk::seat::SeatState;
use sctk::shell::xdg::frame::FrameClick;

use crate::dpi::{LogicalPosition, PhysicalPosition};
use crate::event::{ElementState, MouseButton, MouseScrollDelta, TouchPhase, WindowEvent};
use crate::event::{
ElementState, MouseButton, MouseScrollDelta, PointerId, TouchPhase, WindowEvent,
};

use crate::platform_impl::wayland::state::WinitState;
use crate::platform_impl::wayland::{self, DeviceId, WindowId};
Expand Down Expand Up @@ -115,8 +117,13 @@ impl PointerHandler for WinitState {
}
// Regular events on the main surface.
PointerEventKind::Enter { .. } => {
self.events_sink
.push_window_event(WindowEvent::CursorEntered { device_id }, window_id);
self.events_sink.push_window_event(
WindowEvent::PointerEntered {
device_id,
source: PointerId::Cursor,
},
window_id,
);

if let Some(pointer) = seat_state.pointer.as_ref().map(Arc::downgrade) {
window.pointer_entered(pointer);
Expand All @@ -126,9 +133,11 @@ impl PointerHandler for WinitState {
pointer.winit_data().inner.lock().unwrap().surface = Some(window_id);

self.events_sink.push_window_event(
WindowEvent::CursorMoved {
WindowEvent::PointerMoved {
device_id,
position,
location: position,
source: PointerId::Cursor,
force: None,
},
window_id,
);
Expand All @@ -141,14 +150,21 @@ impl PointerHandler for WinitState {
// Remove the active surface.
pointer.winit_data().inner.lock().unwrap().surface = None;

self.events_sink
.push_window_event(WindowEvent::CursorLeft { device_id }, window_id);
self.events_sink.push_window_event(
WindowEvent::PointerLeft {
device_id,
source: PointerId::Cursor,
},
window_id,
);
}
PointerEventKind::Motion { .. } => {
self.events_sink.push_window_event(
WindowEvent::CursorMoved {
WindowEvent::PointerMoved {
device_id,
position,
location: position,
source: PointerId::Cursor,
force: None,
},
window_id,
);
Expand All @@ -170,10 +186,13 @@ impl PointerHandler for WinitState {
ElementState::Released
};
self.events_sink.push_window_event(
WindowEvent::MouseInput {
WindowEvent::PointerButton {
device_id,
source: PointerId::Cursor,
state,
button,
button: Some(button),
location: None,
force: None,
},
window_id,
);
Expand Down
46 changes: 22 additions & 24 deletions src/platform_impl/linux/wayland/seat/touch/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ use sctk::reexports::client::{Connection, Proxy, QueueHandle};

use sctk::seat::touch::{TouchData, TouchHandler};

use crate::dpi::LogicalPosition;
use crate::event::{Touch, TouchPhase, WindowEvent};
use crate::dpi::{LogicalPosition, PhysicalPosition};
use crate::event::{ElementState, PointerId, WindowEvent};

use crate::platform_impl::wayland::state::WinitState;
use crate::platform_impl::wayland::{self, DeviceId};
Expand Down Expand Up @@ -41,15 +41,16 @@ impl TouchHandler for WinitState {
.insert(id, TouchPoint { surface, location });

self.events_sink.push_window_event(
WindowEvent::Touch(Touch {
WindowEvent::PointerButton {
device_id: crate::event::DeviceId(crate::platform_impl::DeviceId::Wayland(
DeviceId,
)),
phase: TouchPhase::Started,
location: location.to_physical(scale_factor),
source: PointerId::Touch { finger: id as u64 },
force: None,
id: id as u64,
}),
location: Some(location.to_physical(scale_factor)),
state: ElementState::Pressed,
button: None,
},
window_id,
);
}
Expand Down Expand Up @@ -78,15 +79,16 @@ impl TouchHandler for WinitState {
};

self.events_sink.push_window_event(
WindowEvent::Touch(Touch {
WindowEvent::PointerButton {
device_id: crate::event::DeviceId(crate::platform_impl::DeviceId::Wayland(
DeviceId,
)),
phase: TouchPhase::Ended,
location: touch_point.location.to_physical(scale_factor),
source: PointerId::Touch { finger: id as u64 },
state: ElementState::Released,
button: None,
location: None,
force: None,
id: id as u64,
}),
},
window_id,
);
}
Expand Down Expand Up @@ -117,15 +119,14 @@ impl TouchHandler for WinitState {
touch_point.location = LogicalPosition::<f64>::from(position);

self.events_sink.push_window_event(
WindowEvent::Touch(Touch {
WindowEvent::PointerMoved {
device_id: crate::event::DeviceId(crate::platform_impl::DeviceId::Wayland(
DeviceId,
)),
phase: TouchPhase::Cancelled,
source: PointerId::Touch { finger: id as u64 },
location: touch_point.location.to_physical(scale_factor),
force: None,
id: id as u64,
}),
},
window_id,
);
}
Expand All @@ -140,20 +141,17 @@ impl TouchHandler for WinitState {
None => return,
};

let location = touch_point.location.to_physical(scale_factor);
let location: PhysicalPosition<f64> = touch_point.location.to_physical(scale_factor);

self.events_sink.push_window_event(
WindowEvent::Touch(Touch {
WindowEvent::PointerCancelled {
device_id: crate::event::DeviceId(crate::platform_impl::DeviceId::Wayland(
DeviceId,
)),
phase: TouchPhase::Cancelled,
location,
force: None,
id: id as u64,
}),
source: PointerId::Touch { finger: id as u64 },
},
window_id,
);
)
}
}

Expand Down