diff --git a/src/clientside.rs b/src/clientside.rs index b2aea37..b5a7f43 100644 --- a/src/clientside.rs +++ b/src/clientside.rs @@ -20,6 +20,11 @@ use wayland_protocols::{ zwp_linux_dmabuf_feedback_v1::ZwpLinuxDmabufFeedbackV1 as DmabufFeedback, zwp_linux_dmabuf_v1::ZwpLinuxDmabufV1, }, + pointer_constraints::zv1::client::{ + zwp_confined_pointer_v1::ZwpConfinedPointerV1, + zwp_locked_pointer_v1::ZwpLockedPointerV1, + zwp_pointer_constraints_v1::ZwpPointerConstraintsV1, + }, viewporter::client::{wp_viewport::WpViewport, wp_viewporter::WpViewporter}, }, xdg::{ @@ -102,6 +107,7 @@ delegate_noop!(Globals: WlShmPool); delegate_noop!(Globals: WpViewporter); delegate_noop!(Globals: WpViewport); delegate_noop!(Globals: ZxdgOutputManagerV1); +delegate_noop!(Globals: ZwpPointerConstraintsV1); impl Dispatch for Globals { fn event( @@ -201,3 +207,5 @@ push_events!(WlDrm); push_events!(DmabufFeedback); push_events!(XdgOutput); push_events!(WlTouch); +push_events!(ZwpConfinedPointerV1); +push_events!(ZwpLockedPointerV1); diff --git a/src/server/dispatch.rs b/src/server/dispatch.rs index 921497e..bd0d36d 100644 --- a/src/server/dispatch.rs +++ b/src/server/dispatch.rs @@ -4,6 +4,18 @@ use std::sync::{Arc, OnceLock}; use wayland_protocols::{ wp::{ linux_dmabuf::zv1::{client as c_dmabuf, server as s_dmabuf}, + pointer_constraints::zv1::{ + client::zwp_pointer_constraints_v1::ZwpPointerConstraintsV1 as PointerConstraintsClient, + server::{ + zwp_confined_pointer_v1::{ + self as cp, ZwpConfinedPointerV1 as ConfinedPointerServer, + }, + zwp_locked_pointer_v1::{self as lp, ZwpLockedPointerV1 as LockedPointerServer}, + zwp_pointer_constraints_v1::{ + self as pc, ZwpPointerConstraintsV1 as PointerConstraintsServer, + }, + }, + }, relative_pointer::zv1::{ client::zwp_relative_pointer_manager_v1::ZwpRelativePointerManagerV1 as RelativePointerManClient, server::{ @@ -838,6 +850,135 @@ impl Dispatch Dispatch for ServerState { + fn request( + state: &mut Self, + _: &wayland_server::Client, + _: &ConfinedPointerServer, + request: ::Request, + key: &ObjectKey, + _: &DisplayHandle, + _: &mut wayland_server::DataInit<'_, Self>, + ) { + let confined_ptr: &ConfinedPointer = state.objects[*key].as_ref(); + simple_event_shunt! { + confined_ptr.client, request: cp::Request => [ + SetRegion { + |region| region.as_ref().map(|r| r.data().unwrap()) + }, + Destroy + ] + } + } +} + +impl Dispatch for ServerState { + fn request( + state: &mut Self, + _: &wayland_server::Client, + _: &LockedPointerServer, + request: ::Request, + key: &ObjectKey, + _: &DisplayHandle, + _: &mut wayland_server::DataInit<'_, Self>, + ) { + let locked_ptr: &LockedPointer = state.objects[*key].as_ref(); + simple_event_shunt! { + locked_ptr.client, request: lp::Request => [ + SetCursorPositionHint { surface_x, surface_y }, + SetRegion { + |region| region.as_ref().map(|r| r.data().unwrap()) + }, + Destroy + ] + } + } +} + +impl + Dispatch> + for ServerState +{ + fn request( + state: &mut Self, + _: &wayland_server::Client, + _: &PointerConstraintsServer, + request: ::Request, + client: &ClientGlobalWrapper, + _: &DisplayHandle, + data_init: &mut wayland_server::DataInit<'_, Self>, + ) { + use pc::Request; + + match request { + Request::ConfinePointer { + id, + surface, + pointer, + region, + lifetime, + } => { + let surf_key: ObjectKey = surface.data().copied().unwrap(); + let ptr_key: ObjectKey = pointer.data().copied().unwrap(); + state.objects.insert_from_other_objects( + [surf_key, ptr_key], + |[surf_obj, ptr_obj], key| { + let SurfaceData { + client: c_surface, .. + }: &SurfaceData = surf_obj.try_into().unwrap(); + let Pointer { client: c_ptr, .. }: &Pointer = ptr_obj.try_into().unwrap(); + + let client = client.confine_pointer( + c_surface, + c_ptr, + region.as_ref().map(|r| r.data().unwrap()), + convert_wenum(lifetime), + &state.qh, + key, + ); + let server = data_init.init(id, key); + + ConfinedPointer { client, server }.into() + }, + ); + } + Request::LockPointer { + id, + surface, + pointer, + region, + lifetime, + } => { + let surf_key: ObjectKey = surface.data().copied().unwrap(); + let ptr_key: ObjectKey = pointer.data().copied().unwrap(); + state.objects.insert_from_other_objects( + [surf_key, ptr_key], + |[surf_obj, ptr_obj], key| { + let SurfaceData { + client: c_surface, .. + }: &SurfaceData = surf_obj.try_into().unwrap(); + let Pointer { client: c_ptr, .. }: &Pointer = ptr_obj.try_into().unwrap(); + let client = client.lock_pointer( + c_surface, + c_ptr, + region.as_ref().map(|r| r.data().unwrap()), + convert_wenum(lifetime), + &state.qh, + key, + ); + let server = data_init.init(id, key); + LockedPointer { client, server }.into() + }, + ); + } + Request::Destroy => { + client.destroy(); + } + _ => unreachable!("unhandled pointer constraints request"), + } + } +} + #[derive(Clone)] pub(crate) struct ClientGlobalWrapper(Arc>); impl std::ops::Deref for ClientGlobalWrapper { @@ -929,6 +1070,7 @@ global_dispatch_no_events!( s_vp::wp_viewporter::WpViewporter, c_vp::wp_viewporter::WpViewporter ); +global_dispatch_no_events!(PointerConstraintsServer, PointerConstraintsClient); global_dispatch_with_events!(WlSeat, client::wl_seat::WlSeat); global_dispatch_with_events!(WlOutput, client::wl_output::WlOutput); diff --git a/src/server/event.rs b/src/server/event.rs index a78e434..5b35e60 100644 --- a/src/server/event.rs +++ b/src/server/event.rs @@ -3,9 +3,23 @@ use log::{debug, trace, warn}; use std::os::fd::AsFd; use wayland_client::{protocol as client, Proxy}; use wayland_protocols::{ - wp::relative_pointer::zv1::{ - client::zwp_relative_pointer_v1::{self, ZwpRelativePointerV1 as RelativePointerClient}, - server::zwp_relative_pointer_v1::ZwpRelativePointerV1 as RelativePointerServer, + wp::{ + pointer_constraints::zv1::{ + client::{ + zwp_confined_pointer_v1::{self, ZwpConfinedPointerV1 as ConfinedPointerClient}, + zwp_locked_pointer_v1::{self, ZwpLockedPointerV1 as LockedPointerClient}, + }, + server::{ + zwp_confined_pointer_v1::ZwpConfinedPointerV1 as ConfinedPointerServer, + zwp_locked_pointer_v1::ZwpLockedPointerV1 as LockedPointerServer, + }, + }, + relative_pointer::zv1::{ + client::zwp_relative_pointer_v1::{ + self, ZwpRelativePointerV1 as RelativePointerClient, + }, + server::zwp_relative_pointer_v1::ZwpRelativePointerV1 as RelativePointerServer, + }, }, xdg::{ shell::client::{xdg_popup, xdg_surface, xdg_toplevel}, @@ -631,7 +645,7 @@ impl HandleEvent for RelativePointer { fn handle_event(&mut self, event: Self::Event, _: &mut ServerState) { simple_event_shunt! { - self.server, event: rp::client::zwp_relative_pointer_v1::Event => [ + self.server, event: zwp_relative_pointer_v1::Event => [ RelativeMotion { utime_hi, utime_lo, @@ -644,3 +658,31 @@ impl HandleEvent for RelativePointer { } } } + +pub type LockedPointer = GenericObject; +impl HandleEvent for LockedPointer { + type Event = zwp_locked_pointer_v1::Event; + + fn handle_event(&mut self, event: Self::Event, _: &mut ServerState) { + simple_event_shunt! { + self.server, event: zwp_locked_pointer_v1::Event => [ + Locked, + Unlocked + ] + } + } +} + +pub type ConfinedPointer = GenericObject; +impl HandleEvent for ConfinedPointer { + type Event = zwp_confined_pointer_v1::Event; + + fn handle_event(&mut self, event: Self::Event, _: &mut ServerState) { + simple_event_shunt! { + self.server, event: zwp_confined_pointer_v1::Event => [ + Confined, + Unconfined + ] + } + } +} diff --git a/src/server/mod.rs b/src/server/mod.rs index 55aef6f..4240439 100644 --- a/src/server/mod.rs +++ b/src/server/mod.rs @@ -19,9 +19,8 @@ use wayland_client::{protocol as client, Proxy}; use wayland_protocols::{ wp::{ linux_dmabuf::zv1::{client as c_dmabuf, server as s_dmabuf}, - relative_pointer::zv1::{ - self as rp, server::zwp_relative_pointer_manager_v1::ZwpRelativePointerManagerV1, - }, + pointer_constraints::zv1::server::zwp_pointer_constraints_v1::ZwpPointerConstraintsV1, + relative_pointer::zv1::server::zwp_relative_pointer_manager_v1::ZwpRelativePointerManagerV1, viewporter::server as s_vp, }, xdg::{ @@ -306,7 +305,9 @@ pub(crate) enum Object { DmabufFeedback(DmabufFeedback), Drm(Drm), XdgOutput(XdgOutput), - Touch(Touch) + Touch(Touch), + ConfinedPointer(ConfinedPointer), + LockedPointer(LockedPointer) } } @@ -465,7 +466,8 @@ impl ServerState { WlDrmServer, s_dmabuf::zwp_linux_dmabuf_v1::ZwpLinuxDmabufV1, ZxdgOutputManagerV1, - s_vp::wp_viewporter::WpViewporter + s_vp::wp_viewporter::WpViewporter, + ZwpPointerConstraintsV1 ]; } } diff --git a/src/server/tests.rs b/src/server/tests.rs index 689ce5a..84a52fc 100644 --- a/src/server/tests.rs +++ b/src/server/tests.rs @@ -23,6 +23,7 @@ use wayland_client::{ use wayland_protocols::{ wp::{ linux_dmabuf::zv1::client::zwp_linux_dmabuf_v1::ZwpLinuxDmabufV1, + pointer_constraints::zv1::client::zwp_pointer_constraints_v1::ZwpPointerConstraintsV1, relative_pointer::zv1::client::zwp_relative_pointer_manager_v1::ZwpRelativePointerManagerV1, viewporter::client::wp_viewporter::WpViewporter, }, @@ -699,7 +700,8 @@ fn pass_through_globals() { ZwpRelativePointerManagerV1, ZxdgOutputManagerV1, WpViewporter, - WlDrm + WlDrm, + ZwpPointerConstraintsV1 } let mut globals = SupportedGlobals::default(); diff --git a/testwl/src/lib.rs b/testwl/src/lib.rs index 3a11e06..4cb8204 100644 --- a/testwl/src/lib.rs +++ b/testwl/src/lib.rs @@ -5,6 +5,7 @@ use std::time::Instant; use wayland_protocols::{ wp::{ linux_dmabuf::zv1::server::zwp_linux_dmabuf_v1::ZwpLinuxDmabufV1, + pointer_constraints::zv1::server::zwp_pointer_constraints_v1::ZwpPointerConstraintsV1, relative_pointer::zv1::server::zwp_relative_pointer_manager_v1::ZwpRelativePointerManagerV1, viewporter::server::wp_viewporter::WpViewporter, }, @@ -253,6 +254,7 @@ impl Server { global_noop!(ZxdgOutputManagerV1); global_noop!(WpViewporter); global_noop!(WlDrm); + global_noop!(ZwpPointerConstraintsV1); Self { display, @@ -276,7 +278,6 @@ impl Server { self.client.replace(client).is_none(), "Client already connected to test server" ); - //self.dispatch(); } pub fn dispatch(&mut self) {