From 25f363d08615606024eead41b188166de41a7576 Mon Sep 17 00:00:00 2001 From: Julian Orth Date: Wed, 24 Apr 2024 14:03:33 +0200 Subject: [PATCH] wayland: implement ext-transient-seat-v1 --- docs/features.md | 2 + release-notes.md | 1 + src/client.rs | 1 + src/globals.rs | 2 + src/ifs/wl_seat.rs | 2 + .../wl_seat/ext_transient_seat_manager_v1.rs | 106 ++++++++++++++++++ src/ifs/wl_seat/ext_transient_seat_v1.rs | 48 ++++++++ wire/ext_transient_seat_manager_v1.txt | 6 + wire/ext_transient_seat_v1.txt | 10 ++ 9 files changed, 178 insertions(+) create mode 100644 src/ifs/wl_seat/ext_transient_seat_manager_v1.rs create mode 100644 src/ifs/wl_seat/ext_transient_seat_v1.rs create mode 100644 wire/ext_transient_seat_manager_v1.txt create mode 100644 wire/ext_transient_seat_v1.txt diff --git a/docs/features.md b/docs/features.md index 0f96cdbe..dc0cb816 100644 --- a/docs/features.md +++ b/docs/features.md @@ -127,6 +127,7 @@ Jay supports the following wayland protocols: | ext_foreign_toplevel_list_v1 | 1 | Yes | | ext_idle_notifier_v1 | 1 | Yes | | ext_session_lock_manager_v1 | 1 | Yes | +| ext_transient_seat_manager_v1 | 1[^ts_rejected] | Yes | | org_kde_kwin_server_decoration_manager | 1 | | | wl_compositor | 6[^no_touch] | | | wl_data_device_manager | 3 | | @@ -167,6 +168,7 @@ Jay supports the following wayland protocols: [^no_tearing]: Tearing screen updates are not supported. [^no_exclusive]: Exclusive zones are not supported. [^lsaccess]: Sandboxes can restrict access to this protocol. +[^ts_rejected]: Seat creation is always rejected. ## Missing Features diff --git a/release-notes.md b/release-notes.md index 92b9ae45..81957005 100644 --- a/release-notes.md +++ b/release-notes.md @@ -2,6 +2,7 @@ - Add support for wp-security-manager-v1. - Add support for xdg-dialog-v1. +- Add support for ext-transient-seat-v1. # 1.1.0 (2024-04-22) diff --git a/src/client.rs b/src/client.rs index 2c95c68d..4b170cc8 100644 --- a/src/client.rs +++ b/src/client.rs @@ -53,6 +53,7 @@ bitflags! { CAP_JAY_COMPOSITOR = 1 << 5, CAP_LAYER_SHELL = 1 << 6, CAP_SCREENCOPY_MANAGER = 1 << 7, + CAP_SEAT_MANAGER = 1 << 8, } #[derive(Debug, Copy, Clone, Hash, Ord, PartialOrd, Eq, PartialEq)] diff --git a/src/globals.rs b/src/globals.rs index 53f50942..e73fe0bf 100644 --- a/src/globals.rs +++ b/src/globals.rs @@ -17,6 +17,7 @@ use { wl_output::WlOutputGlobal, wl_registry::WlRegistry, wl_seat::{ + ext_transient_seat_manager_v1::ExtTransientSeatManagerV1Global, text_input::{ zwp_input_method_manager_v2::ZwpInputMethodManagerV2Global, zwp_text_input_manager_v3::ZwpTextInputManagerV3Global, @@ -188,6 +189,7 @@ impl Globals { add_singleton!(ZwpTextInputManagerV3Global); add_singleton!(WpSecurityContextManagerV1Global); add_singleton!(XdgWmDialogV1Global); + add_singleton!(ExtTransientSeatManagerV1Global); } pub fn add_backend_singletons(&self, backend: &Rc) { diff --git a/src/ifs/wl_seat.rs b/src/ifs/wl_seat.rs index 04805b19..6fc3a530 100644 --- a/src/ifs/wl_seat.rs +++ b/src/ifs/wl_seat.rs @@ -1,4 +1,6 @@ mod event_handling; +pub mod ext_transient_seat_manager_v1; +pub mod ext_transient_seat_v1; mod kb_owner; mod pointer_owner; pub mod text_input; diff --git a/src/ifs/wl_seat/ext_transient_seat_manager_v1.rs b/src/ifs/wl_seat/ext_transient_seat_manager_v1.rs new file mode 100644 index 00000000..8cbe6edd --- /dev/null +++ b/src/ifs/wl_seat/ext_transient_seat_manager_v1.rs @@ -0,0 +1,106 @@ +use { + crate::{ + client::{Client, ClientCaps, ClientError, CAP_SEAT_MANAGER}, + globals::{Global, GlobalName}, + ifs::wl_seat::ext_transient_seat_v1::ExtTransientSeatV1, + leaks::Tracker, + object::{Object, Version}, + wire::{ext_transient_seat_manager_v1::*, ExtTransientSeatManagerV1Id}, + }, + std::rc::Rc, + thiserror::Error, +}; + +pub struct ExtTransientSeatManagerV1Global { + pub name: GlobalName, +} + +pub struct ExtTransientSeatManagerV1 { + pub id: ExtTransientSeatManagerV1Id, + pub client: Rc, + pub tracker: Tracker, + pub version: Version, +} + +impl ExtTransientSeatManagerV1Global { + pub fn new(name: GlobalName) -> Self { + Self { name } + } + + fn bind_( + self: Rc, + id: ExtTransientSeatManagerV1Id, + client: &Rc, + version: Version, + ) -> Result<(), ExtTransientSeatManagerV1Error> { + let obj = Rc::new(ExtTransientSeatManagerV1 { + id, + client: client.clone(), + tracker: Default::default(), + version, + }); + track!(client, obj); + client.add_client_obj(&obj)?; + Ok(()) + } +} + +global_base!( + ExtTransientSeatManagerV1Global, + ExtTransientSeatManagerV1, + ExtTransientSeatManagerV1Error +); + +impl Global for ExtTransientSeatManagerV1Global { + fn singleton(&self) -> bool { + true + } + + fn version(&self) -> u32 { + 1 + } + + fn required_caps(&self) -> ClientCaps { + CAP_SEAT_MANAGER + } +} + +simple_add_global!(ExtTransientSeatManagerV1Global); + +impl ExtTransientSeatManagerV1RequestHandler for ExtTransientSeatManagerV1 { + type Error = ExtTransientSeatManagerV1Error; + + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { + self.client.remove_obj(self)?; + Ok(()) + } + + fn create(&self, req: Create, _slf: &Rc) -> Result<(), Self::Error> { + let obj = Rc::new(ExtTransientSeatV1 { + id: req.seat, + client: self.client.clone(), + tracker: Default::default(), + version: self.version, + }); + track!(self.client, obj); + self.client.add_client_obj(&obj)?; + obj.send_denied(); + Ok(()) + } +} + +object_base! { + self = ExtTransientSeatManagerV1; + version = self.version; +} + +impl Object for ExtTransientSeatManagerV1 {} + +simple_add_obj!(ExtTransientSeatManagerV1); + +#[derive(Debug, Error)] +pub enum ExtTransientSeatManagerV1Error { + #[error(transparent)] + ClientError(Box), +} +efrom!(ExtTransientSeatManagerV1Error, ClientError); diff --git a/src/ifs/wl_seat/ext_transient_seat_v1.rs b/src/ifs/wl_seat/ext_transient_seat_v1.rs new file mode 100644 index 00000000..23bd55c8 --- /dev/null +++ b/src/ifs/wl_seat/ext_transient_seat_v1.rs @@ -0,0 +1,48 @@ +use { + crate::{ + client::{Client, ClientError}, + leaks::Tracker, + object::{Object, Version}, + wire::{ext_transient_seat_v1::*, ExtTransientSeatV1Id}, + }, + std::rc::Rc, + thiserror::Error, +}; + +pub struct ExtTransientSeatV1 { + pub id: ExtTransientSeatV1Id, + pub client: Rc, + pub tracker: Tracker, + pub version: Version, +} + +impl ExtTransientSeatV1 { + pub fn send_denied(&self) { + self.client.event(Denied { self_id: self.id }); + } +} + +impl ExtTransientSeatV1RequestHandler for ExtTransientSeatV1 { + type Error = ExtTransientSeatV1Error; + + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { + self.client.remove_obj(self)?; + Ok(()) + } +} + +object_base! { + self = ExtTransientSeatV1; + version = self.version; +} + +impl Object for ExtTransientSeatV1 {} + +simple_add_obj!(ExtTransientSeatV1); + +#[derive(Debug, Error)] +pub enum ExtTransientSeatV1Error { + #[error(transparent)] + ClientError(Box), +} +efrom!(ExtTransientSeatV1Error, ClientError); diff --git a/wire/ext_transient_seat_manager_v1.txt b/wire/ext_transient_seat_manager_v1.txt new file mode 100644 index 00000000..2efdf29e --- /dev/null +++ b/wire/ext_transient_seat_manager_v1.txt @@ -0,0 +1,6 @@ +request create { + seat: id(ext_transient_seat_v1), +} + +request destroy { +} diff --git a/wire/ext_transient_seat_v1.txt b/wire/ext_transient_seat_v1.txt new file mode 100644 index 00000000..22a4f87c --- /dev/null +++ b/wire/ext_transient_seat_v1.txt @@ -0,0 +1,10 @@ +request destroy { +} + +event ready { + global_name: u32, +} + +event denied { + +}