From 37845c907ed85fd05211990df1fddc9184916fb2 Mon Sep 17 00:00:00 2001 From: Julian Orth Date: Wed, 24 Apr 2024 17:25:27 +0200 Subject: [PATCH] wayland: implement wl-fixes --- src/globals.rs | 2 + src/ifs.rs | 1 + src/ifs/wl_fixes.rs | 90 ++++++++++++++++++++++++++ src/it/test_ifs.rs | 1 + src/it/test_ifs/test_registry.rs | 7 +- src/it/test_ifs/test_wl_fixes.rs | 38 +++++++++++ src/it/test_transport.rs | 1 + src/it/tests.rs | 2 + src/it/tests/t0043_destroy_registry.rs | 31 +++++++++ wire/wl_fixes.txt | 7 ++ 10 files changed, 179 insertions(+), 1 deletion(-) create mode 100644 src/ifs/wl_fixes.rs create mode 100644 src/it/test_ifs/test_wl_fixes.rs create mode 100644 src/it/tests/t0043_destroy_registry.rs create mode 100644 wire/wl_fixes.txt diff --git a/src/globals.rs b/src/globals.rs index c8595388..c8935e7c 100644 --- a/src/globals.rs +++ b/src/globals.rs @@ -15,6 +15,7 @@ use { jay_damage_tracking::JayDamageTrackingGlobal, org_kde_kwin_server_decoration_manager::OrgKdeKwinServerDecorationManagerGlobal, wl_compositor::WlCompositorGlobal, + wl_fixes::WlFixesGlobal, wl_output::WlOutputGlobal, wl_registry::WlRegistry, wl_seat::{ @@ -197,6 +198,7 @@ impl Globals { add_singleton!(ZwpPointerGesturesV1Global); add_singleton!(ZwpTabletManagerV2Global); add_singleton!(JayDamageTrackingGlobal); + add_singleton!(WlFixesGlobal); } pub fn add_backend_singletons(&self, backend: &Rc) { diff --git a/src/ifs.rs b/src/ifs.rs index 3d81f770..10dc4a7b 100644 --- a/src/ifs.rs +++ b/src/ifs.rs @@ -31,6 +31,7 @@ pub mod wl_callback; pub mod wl_compositor; pub mod wl_display; pub mod wl_drm; +pub mod wl_fixes; pub mod wl_output; pub mod wl_region; pub mod wl_registry; diff --git a/src/ifs/wl_fixes.rs b/src/ifs/wl_fixes.rs new file mode 100644 index 00000000..22ed4f1c --- /dev/null +++ b/src/ifs/wl_fixes.rs @@ -0,0 +1,90 @@ +use { + crate::{ + client::{Client, ClientError}, + globals::{Global, GlobalName}, + leaks::Tracker, + object::{Object, Version}, + wire::{wl_fixes::*, WlFixesId}, + }, + std::rc::Rc, + thiserror::Error, +}; + +pub struct WlFixesGlobal { + pub name: GlobalName, +} + +impl WlFixesGlobal { + pub fn new(name: GlobalName) -> Self { + Self { name } + } + + fn bind_( + self: Rc, + id: WlFixesId, + client: &Rc, + version: Version, + ) -> Result<(), WlFixesError> { + let mgr = Rc::new(WlFixes { + id, + client: client.clone(), + tracker: Default::default(), + version, + }); + track!(client, mgr); + client.add_client_obj(&mgr)?; + Ok(()) + } +} + +global_base!(WlFixesGlobal, WlFixes, WlFixesError); + +simple_add_global!(WlFixesGlobal); + +impl Global for WlFixesGlobal { + fn singleton(&self) -> bool { + true + } + + fn version(&self) -> u32 { + 1 + } +} + +pub struct WlFixes { + pub id: WlFixesId, + pub client: Rc, + pub tracker: Tracker, + pub version: Version, +} + +impl WlFixesRequestHandler for WlFixes { + type Error = WlFixesError; + + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { + self.client.remove_obj(self)?; + Ok(()) + } + + fn destroy_registry(&self, req: DestroyRegistry, _slf: &Rc) -> Result<(), Self::Error> { + let registry = self.client.lookup(req.registry)?; + self.client.remove_obj(&*registry)?; + Ok(()) + } +} + +object_base! { + self = WlFixes; + version = self.version; +} + +impl Object for WlFixes {} + +simple_add_obj!(WlFixes); + +#[derive(Debug, Error)] +pub enum WlFixesError { + #[error(transparent)] + ClientError(Box), +} +efrom!(WlFixesError, ClientError); diff --git a/src/it/test_ifs.rs b/src/it/test_ifs.rs index ebd29ce9..ec7debca 100644 --- a/src/it/test_ifs.rs +++ b/src/it/test_ifs.rs @@ -49,6 +49,7 @@ pub mod test_viewport; pub mod test_viewporter; pub mod test_virtual_keyboard; pub mod test_virtual_keyboard_manager; +pub mod test_wl_fixes; pub mod test_xdg_activation; pub mod test_xdg_activation_token; pub mod test_xdg_base; diff --git a/src/it/test_ifs/test_registry.rs b/src/it/test_ifs/test_registry.rs index cead68b6..b3249723 100644 --- a/src/it/test_ifs/test_registry.rs +++ b/src/it/test_ifs/test_registry.rs @@ -19,7 +19,8 @@ use { test_toplevel_drag_manager::TestToplevelDragManager, test_viewporter::TestViewporter, test_virtual_keyboard_manager::TestVirtualKeyboardManager, - test_xdg_activation::TestXdgActivation, test_xdg_base::TestXdgWmBase, + test_wl_fixes::TestWlFixes, test_xdg_activation::TestXdgActivation, + test_xdg_base::TestXdgWmBase, }, test_object::TestObject, test_transport::TestTransport, @@ -58,6 +59,7 @@ pub struct TestRegistrySingletons { pub zwp_virtual_keyboard_manager_v1: u32, pub zwp_input_method_manager_v2: u32, pub zwp_text_input_manager_v3: u32, + pub wl_fixes: u32, } pub struct TestRegistry { @@ -85,6 +87,7 @@ pub struct TestRegistry { pub virtual_keyboard_manager: CloneCell>>, pub input_method_manager: CloneCell>>, pub text_input_manager: CloneCell>>, + pub wl_fixes: CloneCell>>, pub seats: CopyHashMap>, } @@ -156,6 +159,7 @@ impl TestRegistry { zwp_virtual_keyboard_manager_v1, zwp_input_method_manager_v2, zwp_text_input_manager_v3, + wl_fixes, }; self.singletons.set(Some(singletons.clone())); Ok(singletons) @@ -271,6 +275,7 @@ impl TestRegistry { 1, TestTextInputManager ); + create_singleton!(get_wl_fixes, wl_fixes, wl_fixes, 1, TestWlFixes); pub fn bind( &self, diff --git a/src/it/test_ifs/test_wl_fixes.rs b/src/it/test_ifs/test_wl_fixes.rs new file mode 100644 index 00000000..d14f57a8 --- /dev/null +++ b/src/it/test_ifs/test_wl_fixes.rs @@ -0,0 +1,38 @@ +use { + crate::{ + it::{ + test_error::TestResult, test_ifs::test_registry::TestRegistry, test_object::TestObject, + test_transport::TestTransport, + }, + wire::{wl_fixes::*, WlFixesId}, + }, + std::rc::Rc, +}; + +pub struct TestWlFixes { + pub id: WlFixesId, + pub tran: Rc, +} + +impl TestWlFixes { + pub fn new(tran: &Rc) -> Self { + Self { + id: tran.id(), + tran: tran.clone(), + } + } + + pub fn destroy_registry(&self, registry: &TestRegistry) -> TestResult { + self.tran.send(DestroyRegistry { + self_id: self.id, + registry: registry.id, + })?; + Ok(()) + } +} + +test_object! { + TestWlFixes, WlFixes; +} + +impl TestObject for TestWlFixes {} diff --git a/src/it/test_transport.rs b/src/it/test_transport.rs index a869f460..5f9f9c00 100644 --- a/src/it/test_transport.rs +++ b/src/it/test_transport.rs @@ -73,6 +73,7 @@ impl TestTransport { virtual_keyboard_manager: Default::default(), input_method_manager: Default::default(), text_input_manager: Default::default(), + wl_fixes: Default::default(), seats: Default::default(), }); self.send(wl_display::GetRegistry { diff --git a/src/it/tests.rs b/src/it/tests.rs index c32fe489..71b6d2b8 100644 --- a/src/it/tests.rs +++ b/src/it/tests.rs @@ -74,6 +74,7 @@ mod t0039_alpha_modifier; mod t0040_virtual_keyboard; mod t0041_input_method; mod t0042_toplevel_select; +mod t0043_destroy_registry; pub trait TestCase: Sync { fn name(&self) -> &'static str; @@ -135,5 +136,6 @@ pub fn tests() -> Vec<&'static dyn TestCase> { t0040_virtual_keyboard, t0041_input_method, t0042_toplevel_select, + t0043_destroy_registry, } } diff --git a/src/it/tests/t0043_destroy_registry.rs b/src/it/tests/t0043_destroy_registry.rs new file mode 100644 index 00000000..3e4545c5 --- /dev/null +++ b/src/it/tests/t0043_destroy_registry.rs @@ -0,0 +1,31 @@ +use { + crate::it::{test_error::TestResult, testrun::TestRun}, + std::rc::Rc, +}; + +testcase!(); + +async fn test(run: Rc) -> TestResult { + let client = run.create_client().await?; + let wl_fixes = client.registry.get_wl_fixes().await?; + + let registry1 = client.tran.get_registry(); + + client.sync().await; + let before = client.server.objects.registries.len(); + + wl_fixes.destroy_registry(®istry1)?; + + client.sync().await; + let after = client.server.objects.registries.len(); + + tassert_eq!(before, after + 1); + + let registry2 = client.tran.get_registry(); + client.sync().await; + + tassert_eq!(registry1.id, registry2.id); + tassert!(registry2.globals.is_not_empty()); + + Ok(()) +} diff --git a/wire/wl_fixes.txt b/wire/wl_fixes.txt new file mode 100644 index 00000000..a78e7e7f --- /dev/null +++ b/wire/wl_fixes.txt @@ -0,0 +1,7 @@ +request destroy { + +} + +request destroy_registry { + registry: id(wl_registry), +}