1
0
Fork 0
forked from wry/wry

globals: send to old registries when exposed changes

This commit is contained in:
Julian Orth 2026-03-05 15:59:59 +01:00
parent 1ef1b5a607
commit 1570ba6b58
5 changed files with 81 additions and 21 deletions

View file

@ -1155,11 +1155,11 @@ impl ConfigProxyHandler {
}
fn handle_set_explicit_sync_enabled(&self, enabled: bool) {
self.state.explicit_sync_enabled.set(enabled);
self.state.set_explicit_sync_enabled(enabled);
}
fn handle_set_color_management_enabled(&self, enabled: bool) {
self.state.color_management_enabled.set(enabled);
self.state.set_color_management_enabled(enabled);
}
fn handle_get_socket_path(&self) {
@ -2366,7 +2366,7 @@ impl ConfigProxyHandler {
}
fn handle_set_middle_click_paste_enabled(&self, enabled: bool) {
self.state.enable_primary_selection.set(enabled);
self.state.set_primary_selection_enabled(enabled);
}
fn handle_seat_create_mark(&self, seat: Seat, kc: Option<u32>) -> Result<(), CphError> {

View file

@ -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(&registry.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 {

View file

@ -49,8 +49,7 @@ impl JayColorManagementRequestHandler for JayColorManagement {
fn set_enabled(&self, req: SetEnabled, _slf: &Rc<Self>) -> Result<(), Self::Error> {
self.client
.state
.color_management_enabled
.set(req.enabled != 0);
.set_color_management_enabled(req.enabled != 0);
Ok(())
}
}

View file

@ -1,12 +1,13 @@
use {
crate::{
client::Client,
globals::{Global, GlobalName, GlobalsError},
globals::{Global, GlobalName, GlobalsError, Singleton},
leaks::Tracker,
object::{Interface, Object, Version},
wire::{WlRegistryId, wl_registry::*},
},
std::rc::Rc,
linearize::StaticMap,
std::{cell::Cell, rc::Rc},
thiserror::Error,
};
@ -14,6 +15,7 @@ pub struct WlRegistry {
id: WlRegistryId,
pub client: Rc<Client>,
pub tracker: Tracker<Self>,
advertised: StaticMap<Singleton, Cell<bool>>,
}
impl WlRegistry {
@ -22,23 +24,34 @@ impl WlRegistry {
id,
client: client.clone(),
tracker: Default::default(),
advertised: Default::default(),
}
}
pub fn send_global(self: &Rc<Self>, global: &Rc<dyn Global>) {
pub fn handle_global(&self, global: &Rc<dyn Global>) {
if let Some(singleton) = global.singleton()
&& self.advertised[singleton].replace(true)
{
return;
}
self.client.event(crate::wire::wl_registry::Global {
self_id: self.id,
name: global.name().raw(),
interface: global.interface().name(),
version: global.version(),
})
});
}
pub fn send_global_remove(self: &Rc<Self>, name: GlobalName) {
pub fn handle_global_removed(&self, global: &dyn Global) {
if let Some(singleton) = global.singleton()
&& !self.advertised[singleton].replace(false)
{
return;
}
self.client.event(GlobalRemove {
self_id: self.id,
name: name.raw(),
})
name: global.name().raw(),
});
}
}

View file

@ -736,6 +736,8 @@ impl State {
for sc in scs {
sc.do_destroy();
}
self.expose_new_singletons();
}
fn reload_cursors(&self) {
@ -1667,6 +1669,25 @@ impl State {
ws.desired_output.set(output.global.output_id.clone());
self.tree_changed();
}
fn expose_new_singletons(&self) {
self.globals.expose_new_singletons(self);
}
pub fn set_color_management_enabled(&self, enabled: bool) {
self.color_management_enabled.set(enabled);
self.expose_new_singletons();
}
pub fn set_primary_selection_enabled(&self, enabled: bool) {
self.enable_primary_selection.set(enabled);
self.expose_new_singletons();
}
pub fn set_explicit_sync_enabled(&self, enabled: bool) {
self.explicit_sync_enabled.set(enabled);
self.expose_new_singletons();
}
}
#[derive(Debug, Error)]