From 1f64fefc86ff4d9999de0a0d5e68bd4ff1fd4c3c Mon Sep 17 00:00:00 2001 From: Julian Orth Date: Sun, 16 Oct 2022 21:05:44 +0200 Subject: [PATCH] registry: implement xwayland-only globals --- src/client.rs | 4 ++-- src/globals.rs | 27 ++++++++++++++++++++------- src/ifs/wl_registry.rs | 2 +- 3 files changed, 23 insertions(+), 10 deletions(-) diff --git a/src/client.rs b/src/client.rs index b4918bf3..c03db579 100644 --- a/src/client.rs +++ b/src/client.rs @@ -184,13 +184,13 @@ impl Clients { } } - pub fn broadcast(&self, secure: bool, mut f: B) + pub fn broadcast(&self, secure: bool, xwayland_only: bool, mut f: B) where B: FnMut(&Rc), { let clients = self.clients.borrow(); for client in clients.values() { - if !secure || client.data.secure { + if (!secure || client.data.secure) && (!xwayland_only || client.data.is_xwayland) { f(&client.data); } } diff --git a/src/globals.rs b/src/globals.rs index cc4431aa..140f394e 100644 --- a/src/globals.rs +++ b/src/globals.rs @@ -99,6 +99,9 @@ pub trait Global: GlobalBase { fn secure(&self) -> bool { false } + fn xwayland_only(&self) -> bool { + false + } } pub struct Globals { @@ -183,16 +186,19 @@ impl Globals { fn insert(&self, state: &State, global: Rc) { self.insert_no_broadcast_(&global); - self.broadcast(state, global.secure(), |r| r.send_global(&global)); + self.broadcast(state, global.secure(), global.xwayland_only(), |r| { + r.send_global(&global) + }); } pub fn get( &self, name: GlobalName, allow_secure: bool, + allow_xwayland_only: bool, ) -> Result, GlobalsError> { let global = self.take(name, false)?; - if global.secure() && !allow_secure { + if (global.secure() && !allow_secure) || (global.xwayland_only() && !allow_xwayland_only) { return Err(GlobalsError::GlobalDoesNotExist(name)); } Ok(global) @@ -201,7 +207,7 @@ impl Globals { pub fn remove(&self, state: &State, global: &T) -> Result<(), GlobalsError> { let _global = self.take(global.name(), true)?; global.remove(self); - self.broadcast(state, global.secure(), |r| { + self.broadcast(state, global.secure(), global.xwayland_only(), |r| { r.send_global_remove(global.name()) }); Ok(()) @@ -213,12 +219,13 @@ impl Globals { pub fn notify_all(&self, registry: &Rc) { let secure = registry.client.secure; + let xwayland = registry.client.is_xwayland; let globals = self.registry.lock(); macro_rules! emit { ($singleton:expr) => { for global in globals.values() { - if secure || !global.secure() { - if global.singleton() == $singleton { + if global.singleton() == $singleton { + if (secure || !global.secure()) && (xwayland || !global.xwayland_only()) { registry.send_global(global); } } @@ -229,8 +236,14 @@ impl Globals { emit!(false); } - fn broadcast)>(&self, state: &State, secure: bool, f: F) { - state.clients.broadcast(secure, |c| { + fn broadcast)>( + &self, + state: &State, + secure: bool, + xwayland_only: bool, + f: F, + ) { + state.clients.broadcast(secure, xwayland_only, |c| { let registries = c.lock_registries(); for registry in registries.values() { f(registry); diff --git a/src/ifs/wl_registry.rs b/src/ifs/wl_registry.rs index 50b3a501..9391d375 100644 --- a/src/ifs/wl_registry.rs +++ b/src/ifs/wl_registry.rs @@ -46,7 +46,7 @@ impl WlRegistry { let bind: Bind = self.client.parse(self, parser)?; let name = GlobalName::from_raw(bind.name); let globals = &self.client.state.globals; - let global = globals.get(name, self.client.secure)?; + let global = globals.get(name, self.client.secure, self.client.is_xwayland)?; if global.interface().name() != bind.interface { return Err(WlRegistryError::InvalidInterface(InterfaceError { name: global.name(),