cosmic-workspaces/src/dbus.rs
2026-04-29 21:41:03 +02:00

90 lines
2.4 KiB
Rust

use cosmic::iced::futures::StreamExt;
use cosmic::iced::{self};
use std::any::TypeId;
use std::hash::Hash;
use tokio::sync::broadcast;
use tokio_stream::wrappers::BroadcastStream;
#[derive(Clone, Debug)]
pub enum Event {
Show,
Hide,
}
struct CosmicWorkspaces {
event_sender: broadcast::Sender<Event>,
}
#[zbus::interface(name = "com.system76.CosmicWorkspaces")]
impl CosmicWorkspaces {
fn show(&self) {
let _ = self.event_sender.send(Event::Show);
}
fn hide(&self) {
let _ = self.event_sender.send(Event::Hide);
}
#[zbus(signal)]
async fn shown(&self, _emitter: &zbus::object_server::SignalEmitter<'_>) -> zbus::Result<()>;
#[zbus(signal)]
async fn hidden(&self, _emitter: &zbus::object_server::SignalEmitter<'_>) -> zbus::Result<()>;
}
#[derive(Clone, Debug)]
pub struct Interface {
emitter: zbus::object_server::SignalEmitter<'static>,
event_sender: broadcast::Sender<Event>,
}
impl Interface {
pub async fn new(conn: zbus::Connection) -> zbus::Result<Self> {
let event_sender = broadcast::Sender::new(8);
conn.object_server()
.at(
"/com/system76/CosmicWorkspaces",
CosmicWorkspaces {
event_sender: event_sender.clone(),
},
)
.await?;
Ok(Interface {
emitter: zbus::object_server::SignalEmitter::new(
&conn,
"/com/system76/CosmicWorkspaces",
)
.unwrap(),
event_sender,
})
}
pub async fn shown(&self) -> zbus::Result<()> {
self.emitter.shown(&self.emitter).await
}
pub async fn hidden(&self) -> zbus::Result<()> {
self.emitter.hidden(&self.emitter).await
}
pub fn subscription(&self) -> iced::Subscription<Event> {
#[derive(Clone)]
struct Wrapper {
event_sender: broadcast::Sender<Event>,
}
impl Hash for Wrapper {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
TypeId::of::<Wrapper>().hash(state);
}
}
iced::Subscription::run_with(
Wrapper {
event_sender: self.event_sender.clone(),
},
|Wrapper { event_sender }| {
BroadcastStream::new(event_sender.subscribe()).filter_map(|x| async { x.ok() })
},
)
}
}