Add pointer constraints support (zwp_pointer_constraints_v1)

Part of #8
This commit is contained in:
Shawn Wallace 2024-05-20 02:14:18 -04:00
parent 2317ebb842
commit da82e6907c
6 changed files with 208 additions and 11 deletions

View file

@ -20,6 +20,11 @@ use wayland_protocols::{
zwp_linux_dmabuf_feedback_v1::ZwpLinuxDmabufFeedbackV1 as DmabufFeedback, zwp_linux_dmabuf_feedback_v1::ZwpLinuxDmabufFeedbackV1 as DmabufFeedback,
zwp_linux_dmabuf_v1::ZwpLinuxDmabufV1, 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}, viewporter::client::{wp_viewport::WpViewport, wp_viewporter::WpViewporter},
}, },
xdg::{ xdg::{
@ -102,6 +107,7 @@ delegate_noop!(Globals: WlShmPool);
delegate_noop!(Globals: WpViewporter); delegate_noop!(Globals: WpViewporter);
delegate_noop!(Globals: WpViewport); delegate_noop!(Globals: WpViewport);
delegate_noop!(Globals: ZxdgOutputManagerV1); delegate_noop!(Globals: ZxdgOutputManagerV1);
delegate_noop!(Globals: ZwpPointerConstraintsV1);
impl Dispatch<WlRegistry, ()> for Globals { impl Dispatch<WlRegistry, ()> for Globals {
fn event( fn event(
@ -201,3 +207,5 @@ push_events!(WlDrm);
push_events!(DmabufFeedback); push_events!(DmabufFeedback);
push_events!(XdgOutput); push_events!(XdgOutput);
push_events!(WlTouch); push_events!(WlTouch);
push_events!(ZwpConfinedPointerV1);
push_events!(ZwpLockedPointerV1);

View file

@ -4,6 +4,18 @@ use std::sync::{Arc, OnceLock};
use wayland_protocols::{ use wayland_protocols::{
wp::{ wp::{
linux_dmabuf::zv1::{client as c_dmabuf, server as s_dmabuf}, 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::{ relative_pointer::zv1::{
client::zwp_relative_pointer_manager_v1::ZwpRelativePointerManagerV1 as RelativePointerManClient, client::zwp_relative_pointer_manager_v1::ZwpRelativePointerManagerV1 as RelativePointerManClient,
server::{ server::{
@ -838,6 +850,135 @@ impl<C: XConnection> Dispatch<OutputManServer, ClientGlobalWrapper<OutputManClie
} }
} }
impl<C: XConnection> Dispatch<ConfinedPointerServer, ObjectKey> for ServerState<C> {
fn request(
state: &mut Self,
_: &wayland_server::Client,
_: &ConfinedPointerServer,
request: <ConfinedPointerServer as Resource>::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<C: XConnection> Dispatch<LockedPointerServer, ObjectKey> for ServerState<C> {
fn request(
state: &mut Self,
_: &wayland_server::Client,
_: &LockedPointerServer,
request: <LockedPointerServer as Resource>::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<C: XConnection>
Dispatch<PointerConstraintsServer, ClientGlobalWrapper<PointerConstraintsClient>>
for ServerState<C>
{
fn request(
state: &mut Self,
_: &wayland_server::Client,
_: &PointerConstraintsServer,
request: <PointerConstraintsServer as Resource>::Request,
client: &ClientGlobalWrapper<PointerConstraintsClient>,
_: &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)] #[derive(Clone)]
pub(crate) struct ClientGlobalWrapper<T: Proxy>(Arc<OnceLock<T>>); pub(crate) struct ClientGlobalWrapper<T: Proxy>(Arc<OnceLock<T>>);
impl<T: Proxy> std::ops::Deref for ClientGlobalWrapper<T> { impl<T: Proxy> std::ops::Deref for ClientGlobalWrapper<T> {
@ -929,6 +1070,7 @@ global_dispatch_no_events!(
s_vp::wp_viewporter::WpViewporter, s_vp::wp_viewporter::WpViewporter,
c_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!(WlSeat, client::wl_seat::WlSeat);
global_dispatch_with_events!(WlOutput, client::wl_output::WlOutput); global_dispatch_with_events!(WlOutput, client::wl_output::WlOutput);

View file

@ -3,9 +3,23 @@ use log::{debug, trace, warn};
use std::os::fd::AsFd; use std::os::fd::AsFd;
use wayland_client::{protocol as client, Proxy}; use wayland_client::{protocol as client, Proxy};
use wayland_protocols::{ use wayland_protocols::{
wp::relative_pointer::zv1::{ wp::{
client::zwp_relative_pointer_v1::{self, ZwpRelativePointerV1 as RelativePointerClient}, pointer_constraints::zv1::{
server::zwp_relative_pointer_v1::ZwpRelativePointerV1 as RelativePointerServer, 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::{ xdg::{
shell::client::{xdg_popup, xdg_surface, xdg_toplevel}, shell::client::{xdg_popup, xdg_surface, xdg_toplevel},
@ -631,7 +645,7 @@ impl HandleEvent for RelativePointer {
fn handle_event<C: XConnection>(&mut self, event: Self::Event, _: &mut ServerState<C>) { fn handle_event<C: XConnection>(&mut self, event: Self::Event, _: &mut ServerState<C>) {
simple_event_shunt! { simple_event_shunt! {
self.server, event: rp::client::zwp_relative_pointer_v1::Event => [ self.server, event: zwp_relative_pointer_v1::Event => [
RelativeMotion { RelativeMotion {
utime_hi, utime_hi,
utime_lo, utime_lo,
@ -644,3 +658,31 @@ impl HandleEvent for RelativePointer {
} }
} }
} }
pub type LockedPointer = GenericObject<LockedPointerServer, LockedPointerClient>;
impl HandleEvent for LockedPointer {
type Event = zwp_locked_pointer_v1::Event;
fn handle_event<C: XConnection>(&mut self, event: Self::Event, _: &mut ServerState<C>) {
simple_event_shunt! {
self.server, event: zwp_locked_pointer_v1::Event => [
Locked,
Unlocked
]
}
}
}
pub type ConfinedPointer = GenericObject<ConfinedPointerServer, ConfinedPointerClient>;
impl HandleEvent for ConfinedPointer {
type Event = zwp_confined_pointer_v1::Event;
fn handle_event<C: XConnection>(&mut self, event: Self::Event, _: &mut ServerState<C>) {
simple_event_shunt! {
self.server, event: zwp_confined_pointer_v1::Event => [
Confined,
Unconfined
]
}
}
}

View file

@ -19,9 +19,8 @@ use wayland_client::{protocol as client, Proxy};
use wayland_protocols::{ use wayland_protocols::{
wp::{ wp::{
linux_dmabuf::zv1::{client as c_dmabuf, server as s_dmabuf}, linux_dmabuf::zv1::{client as c_dmabuf, server as s_dmabuf},
relative_pointer::zv1::{ pointer_constraints::zv1::server::zwp_pointer_constraints_v1::ZwpPointerConstraintsV1,
self as rp, server::zwp_relative_pointer_manager_v1::ZwpRelativePointerManagerV1, relative_pointer::zv1::server::zwp_relative_pointer_manager_v1::ZwpRelativePointerManagerV1,
},
viewporter::server as s_vp, viewporter::server as s_vp,
}, },
xdg::{ xdg::{
@ -306,7 +305,9 @@ pub(crate) enum Object {
DmabufFeedback(DmabufFeedback), DmabufFeedback(DmabufFeedback),
Drm(Drm), Drm(Drm),
XdgOutput(XdgOutput), XdgOutput(XdgOutput),
Touch(Touch) Touch(Touch),
ConfinedPointer(ConfinedPointer),
LockedPointer(LockedPointer)
} }
} }
@ -465,7 +466,8 @@ impl<C: XConnection> ServerState<C> {
WlDrmServer, WlDrmServer,
s_dmabuf::zwp_linux_dmabuf_v1::ZwpLinuxDmabufV1, s_dmabuf::zwp_linux_dmabuf_v1::ZwpLinuxDmabufV1,
ZxdgOutputManagerV1, ZxdgOutputManagerV1,
s_vp::wp_viewporter::WpViewporter s_vp::wp_viewporter::WpViewporter,
ZwpPointerConstraintsV1
]; ];
} }
} }

View file

@ -23,6 +23,7 @@ use wayland_client::{
use wayland_protocols::{ use wayland_protocols::{
wp::{ wp::{
linux_dmabuf::zv1::client::zwp_linux_dmabuf_v1::ZwpLinuxDmabufV1, 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, relative_pointer::zv1::client::zwp_relative_pointer_manager_v1::ZwpRelativePointerManagerV1,
viewporter::client::wp_viewporter::WpViewporter, viewporter::client::wp_viewporter::WpViewporter,
}, },
@ -699,7 +700,8 @@ fn pass_through_globals() {
ZwpRelativePointerManagerV1, ZwpRelativePointerManagerV1,
ZxdgOutputManagerV1, ZxdgOutputManagerV1,
WpViewporter, WpViewporter,
WlDrm WlDrm,
ZwpPointerConstraintsV1
} }
let mut globals = SupportedGlobals::default(); let mut globals = SupportedGlobals::default();

View file

@ -5,6 +5,7 @@ use std::time::Instant;
use wayland_protocols::{ use wayland_protocols::{
wp::{ wp::{
linux_dmabuf::zv1::server::zwp_linux_dmabuf_v1::ZwpLinuxDmabufV1, 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, relative_pointer::zv1::server::zwp_relative_pointer_manager_v1::ZwpRelativePointerManagerV1,
viewporter::server::wp_viewporter::WpViewporter, viewporter::server::wp_viewporter::WpViewporter,
}, },
@ -253,6 +254,7 @@ impl Server {
global_noop!(ZxdgOutputManagerV1); global_noop!(ZxdgOutputManagerV1);
global_noop!(WpViewporter); global_noop!(WpViewporter);
global_noop!(WlDrm); global_noop!(WlDrm);
global_noop!(ZwpPointerConstraintsV1);
Self { Self {
display, display,
@ -276,7 +278,6 @@ impl Server {
self.client.replace(client).is_none(), self.client.replace(client).is_none(),
"Client already connected to test server" "Client already connected to test server"
); );
//self.dispatch();
} }
pub fn dispatch(&mut self) { pub fn dispatch(&mut self) {