mirror of
https://github.com/rust-windowing/winit.git
synced 2026-06-26 14:49:07 -04:00
winit-wayland: add pointer gesture hold
This commit is contained in:
@@ -40,7 +40,7 @@ sctk = { package = "smithay-client-toolkit", version = "0.20.0", default-feature
|
||||
sctk-adwaita = { version = "0.11.0", default-features = false, optional = true }
|
||||
wayland-backend = { version = "0.3.10", default-features = false, features = ["client_system"] }
|
||||
wayland-client = "0.31.10"
|
||||
wayland-protocols = { version = "0.32.8", features = ["staging"] }
|
||||
wayland-protocols = { version = "0.32.11", features = ["staging", "unstable"] }
|
||||
wayland-protocols-plasma = { version = "0.3.8", features = ["client"] }
|
||||
winit-common = { workspace = true, features = ["xkb", "wayland"] }
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ use sctk::reexports::protocols::wp::text_input::zv3::client::zwp_text_input_v3::
|
||||
use sctk::seat::pointer::{ThemeSpec, ThemedPointer};
|
||||
use sctk::seat::{Capability as SeatCapability, SeatHandler, SeatState};
|
||||
use tracing::warn;
|
||||
use wayland_protocols::wp::pointer_gestures::zv1::client::zwp_pointer_gesture_hold_v1::ZwpPointerGestureHoldV1;
|
||||
use wayland_protocols::wp::pointer_gestures::zv1::client::zwp_pointer_gesture_pinch_v1::ZwpPointerGesturePinchV1;
|
||||
use wayland_protocols::wp::tablet::zv2::client::zwp_tablet_seat_v2::ZwpTabletSeatV2;
|
||||
use winit_core::event::WindowEvent;
|
||||
@@ -60,6 +61,9 @@ pub struct WinitSeatState {
|
||||
/// The pinch pointer gesture bound on the seat.
|
||||
pointer_gesture_pinch: Option<ZwpPointerGesturePinchV1>,
|
||||
|
||||
/// The hold pointer gesture bound on the seat.
|
||||
pointer_gesture_hold: Option<ZwpPointerGestureHoldV1>,
|
||||
|
||||
/// The keyboard bound on the seat.
|
||||
keyboard_state: Option<KeyboardState>,
|
||||
|
||||
@@ -141,6 +145,14 @@ impl SeatHandler for WinitState {
|
||||
)
|
||||
});
|
||||
|
||||
seat_state.pointer_gesture_hold = self.pointer_gestures.as_ref().map(|manager| {
|
||||
manager.get_hold_gesture(
|
||||
themed_pointer.pointer(),
|
||||
queue_handle,
|
||||
PointerGestureData::default(),
|
||||
)
|
||||
});
|
||||
|
||||
let themed_pointer = Arc::new(themed_pointer);
|
||||
|
||||
// Register cursor surface.
|
||||
@@ -209,6 +221,10 @@ impl SeatHandler for WinitState {
|
||||
pointer_gesture_pinch.destroy();
|
||||
}
|
||||
|
||||
if let Some(pointer_gesture_hold) = seat_state.pointer_gesture_hold.take() {
|
||||
pointer_gesture_hold.destroy();
|
||||
}
|
||||
|
||||
if let Some(pointer) = seat_state.pointer.take() {
|
||||
let pointer_data = pointer.pointer().winit_data();
|
||||
|
||||
|
||||
@@ -7,9 +7,12 @@ use sctk::globals::GlobalData;
|
||||
use sctk::reexports::client::globals::{BindError, GlobalList};
|
||||
use sctk::reexports::client::{Connection, Dispatch, Proxy, QueueHandle, delegate_dispatch};
|
||||
use sctk::reexports::protocols::wp::pointer_gestures::zv1::client::zwp_pointer_gesture_pinch_v1::{
|
||||
Event, ZwpPointerGesturePinchV1,
|
||||
Event as PinchEvent, ZwpPointerGesturePinchV1,
|
||||
};
|
||||
use sctk::reexports::protocols::wp::pointer_gestures::zv1::client::zwp_pointer_gestures_v1::ZwpPointerGesturesV1;
|
||||
use wayland_protocols::wp::pointer_gestures::zv1::client::zwp_pointer_gesture_hold_v1::{
|
||||
Event as HoldEvent, ZwpPointerGestureHoldV1,
|
||||
};
|
||||
use winit_core::event::{TouchPhase, WindowEvent};
|
||||
use winit_core::window::WindowId;
|
||||
|
||||
@@ -27,7 +30,7 @@ impl PointerGesturesState {
|
||||
globals: &GlobalList,
|
||||
queue_handle: &QueueHandle<WinitState>,
|
||||
) -> Result<Self, BindError> {
|
||||
let pointer_gestures = globals.bind(queue_handle, 1..=1, GlobalData)?;
|
||||
let pointer_gestures = globals.bind(queue_handle, 3..=3, GlobalData)?;
|
||||
Ok(Self { pointer_gestures })
|
||||
}
|
||||
}
|
||||
@@ -70,6 +73,49 @@ impl Dispatch<ZwpPointerGesturesV1, GlobalData, WinitState> for PointerGesturesS
|
||||
}
|
||||
}
|
||||
|
||||
impl Dispatch<ZwpPointerGestureHoldV1, PointerGestureData, WinitState> for PointerGesturesState {
|
||||
fn event(
|
||||
state: &mut WinitState,
|
||||
_proxy: &ZwpPointerGestureHoldV1,
|
||||
event: <ZwpPointerGestureHoldV1 as wayland_client::Proxy>::Event,
|
||||
data: &PointerGestureData,
|
||||
_conn: &Connection,
|
||||
_qhandle: &QueueHandle<WinitState>,
|
||||
) {
|
||||
let mut pointer_gesture_data = data.inner.lock().unwrap();
|
||||
let (window_id, phase) = match event {
|
||||
HoldEvent::Begin { surface, fingers, .. } => {
|
||||
if fingers < 2 {
|
||||
return;
|
||||
}
|
||||
|
||||
let window_id = crate::make_wid(&surface);
|
||||
pointer_gesture_data.window_id = Some(window_id);
|
||||
|
||||
(window_id, TouchPhase::Started)
|
||||
},
|
||||
HoldEvent::End { cancelled, .. } => {
|
||||
let window_id = match pointer_gesture_data.window_id {
|
||||
Some(window_id) => window_id,
|
||||
_ => return,
|
||||
};
|
||||
|
||||
// Reset the state.
|
||||
*pointer_gesture_data = Default::default();
|
||||
|
||||
let phase = if cancelled == 0 { TouchPhase::Ended } else { TouchPhase::Cancelled };
|
||||
|
||||
(window_id, phase)
|
||||
},
|
||||
_ => return,
|
||||
};
|
||||
|
||||
state
|
||||
.events_sink
|
||||
.push_window_event(WindowEvent::HoldGesture { device_id: None, phase }, window_id);
|
||||
}
|
||||
}
|
||||
|
||||
impl Dispatch<ZwpPointerGesturePinchV1, PointerGestureData, WinitState> for PointerGesturesState {
|
||||
fn event(
|
||||
state: &mut WinitState,
|
||||
@@ -81,7 +127,7 @@ impl Dispatch<ZwpPointerGesturePinchV1, PointerGestureData, WinitState> for Poin
|
||||
) {
|
||||
let mut pointer_gesture_data = data.inner.lock().unwrap();
|
||||
let (window_id, phase, pan_delta, pinch_delta, rotation_delta) = match event {
|
||||
Event::Begin { surface, fingers, .. } => {
|
||||
PinchEvent::Begin { surface, fingers, .. } => {
|
||||
// We only support two fingers for now.
|
||||
if fingers != 2 {
|
||||
return;
|
||||
@@ -100,7 +146,7 @@ impl Dispatch<ZwpPointerGesturePinchV1, PointerGestureData, WinitState> for Poin
|
||||
|
||||
(window_id, TouchPhase::Started, PhysicalPosition::new(0., 0.), 0., 0.)
|
||||
},
|
||||
Event::Update { dx, dy, scale: pinch, rotation, .. } => {
|
||||
PinchEvent::Update { dx, dy, scale: pinch, rotation, .. } => {
|
||||
let window_id = match pointer_gesture_data.window_id {
|
||||
Some(window_id) => window_id,
|
||||
_ => return,
|
||||
@@ -121,7 +167,7 @@ impl Dispatch<ZwpPointerGesturePinchV1, PointerGestureData, WinitState> for Poin
|
||||
let rotation_delta = -rotation as f32;
|
||||
(window_id, TouchPhase::Moved, pan_delta, pinch_delta, rotation_delta)
|
||||
},
|
||||
Event::End { cancelled, .. } => {
|
||||
PinchEvent::End { cancelled, .. } => {
|
||||
let window_id = match pointer_gesture_data.window_id {
|
||||
Some(window_id) => window_id,
|
||||
_ => return,
|
||||
@@ -155,3 +201,4 @@ impl Dispatch<ZwpPointerGesturePinchV1, PointerGestureData, WinitState> for Poin
|
||||
|
||||
delegate_dispatch!(WinitState: [ZwpPointerGesturesV1: GlobalData] => PointerGesturesState);
|
||||
delegate_dispatch!(WinitState: [ZwpPointerGesturePinchV1: PointerGestureData] => PointerGesturesState);
|
||||
delegate_dispatch!(WinitState: [ZwpPointerGestureHoldV1: PointerGestureData] => PointerGesturesState);
|
||||
|
||||
Reference in New Issue
Block a user