2024-05-06 15:39:04 +02:00
|
|
|
// Copyright 2023 System76 <info@system76.com>
|
|
|
|
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
|
|
|
|
2023-01-03 14:36:56 -08:00
|
|
|
// 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};
|
2023-01-03 14:36:56 -08:00
|
|
|
|
|
|
|
|
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(
|
2023-01-03 14:36:56 -08:00
|
|
|
"status-notifier-watcher",
|
2024-10-30 22:51:08 -04:00
|
|
|
stream::unfold(State::NotConnected, |state| async move {
|
2023-01-03 14:36:56 -08:00
|
|
|
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)))
|
2023-01-03 14:36:56 -08:00
|
|
|
}
|
2024-10-30 22:51:08 -04:00
|
|
|
Err(err) => Some((Event::Error(err.to_string()), State::Failed)),
|
2023-01-03 14:36:56 -08:00
|
|
|
},
|
|
|
|
|
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,
|
2023-01-03 14:36:56 -08:00
|
|
|
},
|
2024-10-30 22:51:08 -04:00
|
|
|
State::Failed => None,
|
2023-01-03 14:36:56 -08:00
|
|
|
}
|
2024-10-30 22:51:08 -04:00
|
|
|
}),
|
2023-01-03 14:36:56 -08: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))
|
|
|
|
|
}
|