1
0
Fork 0
forked from wry/wry

registry: implement xwayland-only globals

This commit is contained in:
Julian Orth 2022-10-16 21:05:44 +02:00
parent 887fab0936
commit 1f64fefc86
3 changed files with 23 additions and 10 deletions

View file

@ -184,13 +184,13 @@ impl Clients {
} }
} }
pub fn broadcast<B>(&self, secure: bool, mut f: B) pub fn broadcast<B>(&self, secure: bool, xwayland_only: bool, mut f: B)
where where
B: FnMut(&Rc<Client>), B: FnMut(&Rc<Client>),
{ {
let clients = self.clients.borrow(); let clients = self.clients.borrow();
for client in clients.values() { for client in clients.values() {
if !secure || client.data.secure { if (!secure || client.data.secure) && (!xwayland_only || client.data.is_xwayland) {
f(&client.data); f(&client.data);
} }
} }

View file

@ -99,6 +99,9 @@ pub trait Global: GlobalBase {
fn secure(&self) -> bool { fn secure(&self) -> bool {
false false
} }
fn xwayland_only(&self) -> bool {
false
}
} }
pub struct Globals { pub struct Globals {
@ -183,16 +186,19 @@ impl Globals {
fn insert(&self, state: &State, global: Rc<dyn Global>) { fn insert(&self, state: &State, global: Rc<dyn Global>) {
self.insert_no_broadcast_(&global); 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( pub fn get(
&self, &self,
name: GlobalName, name: GlobalName,
allow_secure: bool, allow_secure: bool,
allow_xwayland_only: bool,
) -> Result<Rc<dyn Global>, GlobalsError> { ) -> Result<Rc<dyn Global>, GlobalsError> {
let global = self.take(name, false)?; 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)); return Err(GlobalsError::GlobalDoesNotExist(name));
} }
Ok(global) Ok(global)
@ -201,7 +207,7 @@ impl Globals {
pub fn remove<T: WaylandGlobal>(&self, state: &State, global: &T) -> Result<(), GlobalsError> { pub fn remove<T: WaylandGlobal>(&self, state: &State, global: &T) -> Result<(), GlobalsError> {
let _global = self.take(global.name(), true)?; let _global = self.take(global.name(), true)?;
global.remove(self); global.remove(self);
self.broadcast(state, global.secure(), |r| { self.broadcast(state, global.secure(), global.xwayland_only(), |r| {
r.send_global_remove(global.name()) r.send_global_remove(global.name())
}); });
Ok(()) Ok(())
@ -213,12 +219,13 @@ impl Globals {
pub fn notify_all(&self, registry: &Rc<WlRegistry>) { pub fn notify_all(&self, registry: &Rc<WlRegistry>) {
let secure = registry.client.secure; let secure = registry.client.secure;
let xwayland = registry.client.is_xwayland;
let globals = self.registry.lock(); let globals = self.registry.lock();
macro_rules! emit { macro_rules! emit {
($singleton:expr) => { ($singleton:expr) => {
for global in globals.values() { 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); registry.send_global(global);
} }
} }
@ -229,8 +236,14 @@ impl Globals {
emit!(false); emit!(false);
} }
fn broadcast<F: Fn(&Rc<WlRegistry>)>(&self, state: &State, secure: bool, f: F) { fn broadcast<F: Fn(&Rc<WlRegistry>)>(
state.clients.broadcast(secure, |c| { &self,
state: &State,
secure: bool,
xwayland_only: bool,
f: F,
) {
state.clients.broadcast(secure, xwayland_only, |c| {
let registries = c.lock_registries(); let registries = c.lock_registries();
for registry in registries.values() { for registry in registries.values() {
f(registry); f(registry);

View file

@ -46,7 +46,7 @@ impl WlRegistry {
let bind: Bind = self.client.parse(self, parser)?; let bind: Bind = self.client.parse(self, parser)?;
let name = GlobalName::from_raw(bind.name); let name = GlobalName::from_raw(bind.name);
let globals = &self.client.state.globals; 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 { if global.interface().name() != bind.interface {
return Err(WlRegistryError::InvalidInterface(InterfaceError { return Err(WlRegistryError::InvalidInterface(InterfaceError {
name: global.name(), name: global.name(),