cosmic-applets/cosmic-applet-status-area/src/subscriptions/status_notifier_watcher/mod.rs

61 lines
1.8 KiB
Rust
Raw Normal View History

2024-05-06 15:39:04 +02:00
// Copyright 2023 System76 <info@system76.com>
// SPDX-License-Identifier: GPL-3.0-only
// TODO: Both this and server proxy could emit same events, have way to generate stream from either?
2024-10-30 22:51:08 -04:00
use cosmic::iced::{self, Subscription};
2025-08-12 21:38:51 +02:00
use futures::{StreamExt, stream};
use crate::subscriptions::status_notifier_item::StatusNotifierItem;
mod client;
mod server;
#[derive(Clone, Debug)]
pub enum Event {
Connected(zbus::Connection),
Registered(StatusNotifierItem),
Unregistered(String),
Error(String), // XXX
}
enum State {
NotConnected,
Connected(client::EventStream),
Failed,
}
pub fn subscription() -> iced::Subscription<Event> {
2024-10-30 22:51:08 -04:00
Subscription::run_with_id(
"status-notifier-watcher",
2024-10-30 22:51:08 -04:00
stream::unfold(State::NotConnected, |state| async move {
match state {
State::NotConnected => match connect().await {
Ok((connection, stream)) => {
2024-10-30 22:51:08 -04:00
Some((Event::Connected(connection), State::Connected(stream)))
}
2024-10-30 22:51:08 -04:00
Err(err) => Some((Event::Error(err.to_string()), State::Failed)),
},
State::Connected(mut stream) => match stream.next().await {
2024-10-30 22:51:08 -04:00
Some(event) => Some((event, State::Connected(stream))),
None => None,
},
2024-10-30 22:51:08 -04:00
State::Failed => None,
}
2024-10-30 22:51:08 -04:00
}),
)
}
async fn connect() -> zbus::Result<(zbus::Connection, client::EventStream)> {
// Connect to session dbus socket
let connection = zbus::Connection::session().await?;
// Start `StatusNotifierWatcher` service, if there isn't one running already
server::create_service(&connection).await?;
// Connect client and listen for registered/unregistered
let stream = client::watch(&connection).await?;
Ok((connection, stream))
}