diff --git a/Cargo.lock b/Cargo.lock index 0fc2ef9..32705dc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1263,6 +1263,7 @@ dependencies = [ "rust-embed", "rustix 1.1.2", "tokio", + "tokio-stream", "wayland-protocols", "zbus 5.11.0", ] @@ -5492,6 +5493,20 @@ dependencies = [ "futures-core", "pin-project-lite", "tokio", + "tokio-util", +] + +[[package]] +name = "tokio-util" +version = "0.7.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14307c986784f72ef81c89db7d9e28d6ac26d16213b109ea501696195e6e3ce5" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 1edffcf..5561773 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -36,6 +36,7 @@ calloop-wayland-source = "0.4.1" aliasable = "0.1.3" futures-executor = { version = "0.3.31", features = ["thread-pool"] } zbus = "5.9.0" +tokio-stream = { version = "0.1.17", features = ["sync"] } [dependencies.i18n-embed] version = "0.16" diff --git a/src/dbus.rs b/src/dbus.rs index fdb1f35..f475f6f 100644 --- a/src/dbus.rs +++ b/src/dbus.rs @@ -1,9 +1,30 @@ -struct CosmicWorkspaces; +use cosmic::iced::{self, futures::StreamExt}; +use tokio::sync::broadcast; +use tokio_stream::wrappers::BroadcastStream; + +#[derive(Clone, Debug)] +pub enum Event { + Show, + Hide, +} + +struct CosmicWorkspaces { + event_sender: broadcast::Sender, +} #[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<()>; } @@ -11,12 +32,19 @@ impl CosmicWorkspaces { #[derive(Clone, Debug)] pub struct Interface { emitter: zbus::object_server::SignalEmitter<'static>, + event_sender: broadcast::Sender, } impl Interface { pub async fn new(conn: zbus::Connection) -> zbus::Result { + let event_sender = broadcast::Sender::new(8); conn.object_server() - .at("/com/system76/CosmicWorkspaces", CosmicWorkspaces) + .at( + "/com/system76/CosmicWorkspaces", + CosmicWorkspaces { + event_sender: event_sender.clone(), + }, + ) .await?; Ok(Interface { emitter: zbus::object_server::SignalEmitter::new( @@ -24,14 +52,22 @@ impl Interface { "/com/system76/CosmicWorkspaces", ) .unwrap(), + event_sender, }) } pub async fn shown(&self) -> zbus::Result<()> { - CosmicWorkspaces.shown(&self.emitter).await + self.emitter.shown(&self.emitter).await } pub async fn hidden(&self) -> zbus::Result<()> { - CosmicWorkspaces.hidden(&self.emitter).await + self.emitter.hidden(&self.emitter).await + } + + pub fn subscription(&self) -> iced::Subscription { + iced::Subscription::run_with_id( + "workspaces-dbus-sun", + BroadcastStream::new(self.event_sender.subscribe()).filter_map(|x| async { x.ok() }), + ) } } diff --git a/src/main.rs b/src/main.rs index 2a3c7f7..e58c446 100644 --- a/src/main.rs +++ b/src/main.rs @@ -116,6 +116,7 @@ enum Msg { TogglePinned(ExtWorkspaceHandleV1), EnteredWorkspaceSidebarEntry(ExtWorkspaceHandleV1, bool), DbusInterface(zbus::Result), + DBus(dbus::Event), Ignore, } @@ -728,6 +729,12 @@ impl Application for App { self.dbus_interface = Some(interface); } } + Msg::DBus(evt) => { + return match evt { + dbus::Event::Show => self.show(), + dbus::Event::Hide => self.hide(), + }; + } Msg::Ignore => {} } @@ -812,6 +819,9 @@ impl Application for App { if let Some(conn) = self.conn.clone() { subscriptions.push(backend::subscription(conn).map(Msg::Wayland)); } + if let Some(interface) = &self.dbus_interface { + subscriptions.push(interface.subscription().map(Msg::DBus)); + } iced::Subscription::batch(subscriptions) }