globals: send to old registries when exposed changes
This commit is contained in:
parent
1ef1b5a607
commit
1570ba6b58
5 changed files with 81 additions and 21 deletions
|
|
@ -80,6 +80,7 @@ use {
|
|||
numcell::NumCell,
|
||||
},
|
||||
},
|
||||
arrayvec::ArrayVec,
|
||||
linearize::{Linearize, StaticMap},
|
||||
std::{
|
||||
error::Error,
|
||||
|
|
@ -150,6 +151,12 @@ pub trait Global: GlobalBase {
|
|||
let _ = state;
|
||||
true
|
||||
}
|
||||
fn permitted(&self, caps: ClientCaps, xwayland: bool) -> bool {
|
||||
caps.contains(self.required_caps()) && (xwayland || !self.xwayland_only())
|
||||
}
|
||||
fn not_permitted(&self, caps: ClientCaps, xwayland: bool) -> bool {
|
||||
!self.permitted(caps, xwayland)
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! singletons {
|
||||
|
|
@ -248,7 +255,7 @@ pub struct Globals {
|
|||
removed: CopyHashMap<GlobalName, Rc<dyn Global>>,
|
||||
pub outputs: CopyHashMap<GlobalName, Rc<WlOutputGlobal>>,
|
||||
pub seats: CopyHashMap<GlobalName, Rc<WlSeatGlobal>>,
|
||||
pub singletons: StaticMap<Singleton, GlobalName>,
|
||||
singletons: StaticMap<Singleton, GlobalName>,
|
||||
}
|
||||
|
||||
impl Globals {
|
||||
|
|
@ -290,7 +297,7 @@ impl Globals {
|
|||
fn insert(&self, state: &State, global: Rc<dyn Global>) {
|
||||
self.insert_no_broadcast_(&global);
|
||||
self.broadcast(state, global.required_caps(), global.xwayland_only(), |r| {
|
||||
r.send_global(&global)
|
||||
r.handle_global(&global)
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -301,9 +308,7 @@ impl Globals {
|
|||
allow_xwayland_only: bool,
|
||||
) -> Result<Rc<dyn Global>, GlobalsError> {
|
||||
let global = self.take(name, false)?;
|
||||
if client_caps.not_contains(global.required_caps())
|
||||
|| (global.xwayland_only() && !allow_xwayland_only)
|
||||
{
|
||||
if global.not_permitted(client_caps, allow_xwayland_only) {
|
||||
return Err(GlobalsError::GlobalDoesNotExist(name));
|
||||
}
|
||||
Ok(global)
|
||||
|
|
@ -321,7 +326,7 @@ impl Globals {
|
|||
assert_eq!(global.interface().0, replacement.interface().0);
|
||||
self.removed.set(global.name(), replacement);
|
||||
self.broadcast(state, global.required_caps(), global.xwayland_only(), |r| {
|
||||
r.send_global_remove(global.name())
|
||||
r.handle_global_removed(&**global)
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -339,10 +344,9 @@ impl Globals {
|
|||
for global in globals.values() {
|
||||
if global.singleton().is_some() == $singleton {
|
||||
if global.exposed(®istry.client.state)
|
||||
&& caps.contains(global.required_caps())
|
||||
&& (xwayland || !global.xwayland_only())
|
||||
&& global.permitted(caps, xwayland)
|
||||
{
|
||||
registry.send_global(global);
|
||||
registry.handle_global(global);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -400,6 +404,29 @@ impl Globals {
|
|||
global.clone().add(self);
|
||||
self.insert_no_broadcast(global.clone());
|
||||
}
|
||||
|
||||
pub fn expose_new_singletons(&self, state: &State) {
|
||||
let mut singletons = ArrayVec::<_, { Singleton::LENGTH }>::new();
|
||||
for name in self.singletons.values() {
|
||||
if let Some(global) = self.registry.get(name)
|
||||
&& global.exposed(state)
|
||||
{
|
||||
singletons.push(global);
|
||||
}
|
||||
}
|
||||
for client in state.clients.clients.borrow().values() {
|
||||
let client = &client.data;
|
||||
let caps = client.effective_caps.get();
|
||||
let xwayland = client.is_xwayland;
|
||||
for global in &singletons {
|
||||
if global.permitted(caps, xwayland) {
|
||||
for registry in client.objects.registries.lock().values() {
|
||||
registry.handle_global(global);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait WaylandGlobal: Global + 'static {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue