mirror of
https://github.com/Zedfrigg/ironbar.git
synced 2025-07-03 03:31:03 +02:00
feat: swaync notifications module
Adds a new module which connects to SwayNC to display information from the notifications deamon. Resolves #7
This commit is contained in:
parent
660dc81e7d
commit
7742a46578
15 changed files with 592 additions and 3 deletions
|
@ -6,6 +6,8 @@ pub mod clipboard;
|
|||
pub mod compositor;
|
||||
#[cfg(feature = "music")]
|
||||
pub mod music;
|
||||
#[cfg(feature = "notifications")]
|
||||
pub mod swaync;
|
||||
#[cfg(feature = "tray")]
|
||||
pub mod system_tray;
|
||||
#[cfg(feature = "upower")]
|
||||
|
@ -25,6 +27,8 @@ pub struct Clients {
|
|||
clipboard: Option<Arc<clipboard::Client>>,
|
||||
#[cfg(feature = "music")]
|
||||
music: std::collections::HashMap<music::ClientType, Arc<dyn music::MusicClient>>,
|
||||
#[cfg(feature = "notifications")]
|
||||
notifications: Option<Arc<swaync::Client>>,
|
||||
#[cfg(feature = "tray")]
|
||||
tray: Option<Arc<system_tray::TrayEventReceiver>>,
|
||||
#[cfg(feature = "upower")]
|
||||
|
@ -71,6 +75,15 @@ impl Clients {
|
|||
.clone()
|
||||
}
|
||||
|
||||
#[cfg(feature = "notifications")]
|
||||
pub fn notifications(&mut self) -> Arc<swaync::Client> {
|
||||
self.notifications
|
||||
.get_or_insert_with(|| {
|
||||
Arc::new(crate::await_sync(async { swaync::Client::new().await }))
|
||||
})
|
||||
.clone()
|
||||
}
|
||||
|
||||
#[cfg(feature = "tray")]
|
||||
pub fn tray(&mut self) -> Arc<system_tray::TrayEventReceiver> {
|
||||
self.tray
|
||||
|
@ -122,7 +135,7 @@ macro_rules! register_client {
|
|||
where
|
||||
TSend: Clone,
|
||||
{
|
||||
fn provide(&self) -> Arc<$ty> {
|
||||
fn provide(&self) -> std::sync::Arc<$ty> {
|
||||
self.ironbar.clients.borrow_mut().$method()
|
||||
}
|
||||
}
|
||||
|
|
111
src/clients/swaync/dbus.rs
Normal file
111
src/clients/swaync/dbus.rs
Normal file
|
@ -0,0 +1,111 @@
|
|||
//! # D-Bus interface proxy for: `org.erikreider.swaync.cc`
|
||||
//!
|
||||
//! This code was generated by `zbus-xmlgen` `4.0.1` from D-Bus introspection data.
|
||||
//! Source: `Interface '/org/erikreider/swaync/cc' from service 'org.erikreider.swaync.cc' on session bus`.
|
||||
//!
|
||||
//! You may prefer to adapt it, instead of using it verbatim.
|
||||
//!
|
||||
//! More information can be found in the [Writing a client proxy] section of the zbus
|
||||
//! documentation.
|
||||
//!
|
||||
//! This type implements the [D-Bus standard interfaces], (`org.freedesktop.DBus.*`) for which the
|
||||
//! following zbus API can be used:
|
||||
//!
|
||||
//! * [`zbus::fdo::PropertiesProxy`]
|
||||
//! * [`zbus::fdo::IntrospectableProxy`]
|
||||
//! * [`zbus::fdo::PeerProxy`]
|
||||
//!
|
||||
//! Consequently `zbus-xmlgen` did not generate code for the above interfaces.
|
||||
//!
|
||||
//! [Writing a client proxy]: https://dbus2.github.io/zbus/client.html
|
||||
//! [D-Bus standard interfaces]: https://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces,
|
||||
|
||||
#[zbus::dbus_proxy(
|
||||
interface = "org.erikreider.swaync.cc",
|
||||
default_service = "org.erikreider.swaync.cc",
|
||||
default_path = "/org/erikreider/swaync/cc"
|
||||
)]
|
||||
trait SwayNc {
|
||||
/// AddInhibitor method
|
||||
fn add_inhibitor(&self, application_id: &str) -> zbus::Result<bool>;
|
||||
|
||||
/// ChangeConfigValue method
|
||||
fn change_config_value(
|
||||
&self,
|
||||
name: &str,
|
||||
value: &zbus::zvariant::Value<'_>,
|
||||
write_to_file: bool,
|
||||
path: &str,
|
||||
) -> zbus::Result<()>;
|
||||
|
||||
/// ClearInhibitors method
|
||||
fn clear_inhibitors(&self) -> zbus::Result<bool>;
|
||||
|
||||
/// CloseAllNotifications method
|
||||
fn close_all_notifications(&self) -> zbus::Result<()>;
|
||||
|
||||
/// CloseNotification method
|
||||
fn close_notification(&self, id: u32) -> zbus::Result<()>;
|
||||
|
||||
/// GetDnd method
|
||||
fn get_dnd(&self) -> zbus::Result<bool>;
|
||||
|
||||
/// GetSubscribeData method
|
||||
fn get_subscribe_data(&self) -> zbus::Result<(bool, bool, u32, bool)>;
|
||||
|
||||
/// GetVisibility method
|
||||
fn get_visibility(&self) -> zbus::Result<bool>;
|
||||
|
||||
/// HideLatestNotifications method
|
||||
fn hide_latest_notifications(&self, close: bool) -> zbus::Result<()>;
|
||||
|
||||
/// IsInhibited method
|
||||
fn is_inhibited(&self) -> zbus::Result<bool>;
|
||||
|
||||
/// NotificationCount method
|
||||
fn notification_count(&self) -> zbus::Result<u32>;
|
||||
|
||||
/// NumberOfInhibitors method
|
||||
fn number_of_inhibitors(&self) -> zbus::Result<u32>;
|
||||
|
||||
/// ReloadConfig method
|
||||
fn reload_config(&self) -> zbus::Result<()>;
|
||||
|
||||
/// ReloadCss method
|
||||
fn reload_css(&self) -> zbus::Result<bool>;
|
||||
|
||||
/// RemoveInhibitor method
|
||||
fn remove_inhibitor(&self, application_id: &str) -> zbus::Result<bool>;
|
||||
|
||||
/// SetDnd method
|
||||
fn set_dnd(&self, state: bool) -> zbus::Result<()>;
|
||||
|
||||
/// SetVisibility method
|
||||
fn set_visibility(&self, visibility: bool) -> zbus::Result<()>;
|
||||
|
||||
/// ToggleDnd method
|
||||
fn toggle_dnd(&self) -> zbus::Result<bool>;
|
||||
|
||||
/// ToggleVisibility method
|
||||
fn toggle_visibility(&self) -> zbus::Result<()>;
|
||||
|
||||
/// Subscribe signal
|
||||
#[dbus_proxy(signal)]
|
||||
fn subscribe(&self, count: u32, dnd: bool, cc_open: bool) -> zbus::Result<()>;
|
||||
|
||||
/// SubscribeV2 signal
|
||||
#[dbus_proxy(signal)]
|
||||
fn subscribe_v2(
|
||||
&self,
|
||||
count: u32,
|
||||
dnd: bool,
|
||||
cc_open: bool,
|
||||
inhibited: bool,
|
||||
) -> zbus::Result<()>;
|
||||
|
||||
/// Inhibited property
|
||||
#[dbus_proxy(property)]
|
||||
fn inhibited(&self) -> zbus::Result<bool>;
|
||||
#[dbus_proxy(property)]
|
||||
fn set_inhibited(&self, value: bool) -> zbus::Result<()>;
|
||||
}
|
88
src/clients/swaync/mod.rs
Normal file
88
src/clients/swaync/mod.rs
Normal file
|
@ -0,0 +1,88 @@
|
|||
mod dbus;
|
||||
|
||||
use crate::{register_client, send, spawn};
|
||||
use color_eyre::{Report, Result};
|
||||
use dbus::SwayNcProxy;
|
||||
use serde::Deserialize;
|
||||
use tokio::sync::broadcast;
|
||||
use tracing::{debug, error};
|
||||
use zbus::export::ordered_stream::OrderedStreamExt;
|
||||
use zbus::zvariant::Type;
|
||||
|
||||
#[derive(Debug, Clone, Copy, Type, Deserialize)]
|
||||
pub struct Event {
|
||||
pub count: u32,
|
||||
pub dnd: bool,
|
||||
pub cc_open: bool,
|
||||
pub inhibited: bool,
|
||||
}
|
||||
|
||||
type GetSubscribeData = (bool, bool, u32, bool);
|
||||
|
||||
/// Converts the data returned from
|
||||
/// `get_subscribe_data` into an event for convenience.
|
||||
impl From<GetSubscribeData> for Event {
|
||||
fn from((dnd, cc_open, count, inhibited): (bool, bool, u32, bool)) -> Self {
|
||||
Self {
|
||||
dnd,
|
||||
cc_open,
|
||||
count,
|
||||
inhibited,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Client {
|
||||
proxy: SwayNcProxy<'static>,
|
||||
tx: broadcast::Sender<Event>,
|
||||
_rx: broadcast::Receiver<Event>,
|
||||
}
|
||||
|
||||
impl Client {
|
||||
pub async fn new() -> Self {
|
||||
let dbus = Box::pin(zbus::Connection::session())
|
||||
.await
|
||||
.expect("failed to create connection to system bus");
|
||||
|
||||
let proxy = SwayNcProxy::new(&dbus).await.unwrap();
|
||||
let (tx, rx) = broadcast::channel(8);
|
||||
|
||||
let mut stream = proxy.receive_subscribe_v2().await.unwrap();
|
||||
|
||||
{
|
||||
let tx = tx.clone();
|
||||
|
||||
spawn(async move {
|
||||
while let Some(ev) = stream.next().await {
|
||||
let ev = ev.body::<Event>().expect("to deserialize");
|
||||
debug!("Received event: {ev:?}");
|
||||
send!(tx, ev);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Self { proxy, tx, _rx: rx }
|
||||
}
|
||||
|
||||
pub fn subscribe(&self) -> broadcast::Receiver<Event> {
|
||||
self.tx.subscribe()
|
||||
}
|
||||
|
||||
pub async fn state(&self) -> Result<Event> {
|
||||
debug!("Getting subscribe data (current state)");
|
||||
match self.proxy.get_subscribe_data().await {
|
||||
Ok(data) => Ok(data.into()),
|
||||
Err(err) => Err(Report::new(err)),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn toggle_visibility(&self) {
|
||||
debug!("Toggling visibility");
|
||||
if let Err(err) = self.proxy.toggle_visibility().await {
|
||||
error!("{err:?}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
register_client!(Client, notifications);
|
Loading…
Add table
Add a link
Reference in a new issue