1
0
Fork 0
mirror of https://github.com/Zedfrigg/ironbar.git synced 2025-08-17 14:51:04 +02:00

refactor: major client code changes

This does away with `lazy_static` singletons for all the clients, instead putting them all inside a `Clients` struct on the `Ironbar` struct.

Client code has been refactored in places to accommodate this, and module code has been updated to get the clients the new way.

The Wayland client has been re-written from the ground up to remove a lot of the needless complications, provide a nicer interface and reduce some duplicate data.

The MPD music client has been overhauled to use the `mpd_utils` crate, which simplifies the code within Ironbar and should offer more robustness and better recovery when connection is lost to the server.

The launcher module in particular has been affected by the refactor.
This commit is contained in:
Jake Stanger 2024-01-07 23:50:10 +00:00
parent 57b57ed002
commit c702f6fffa
No known key found for this signature in database
GPG key ID: C51FC8F9CB0BEA61
33 changed files with 1081 additions and 1063 deletions

View file

@ -1,32 +1,35 @@
use super::{Visibility, Workspace, WorkspaceClient, WorkspaceUpdate};
use crate::{await_sync, send, spawn};
use async_once::AsyncOnce;
use color_eyre::Report;
use color_eyre::{Report, Result};
use futures_util::StreamExt;
use lazy_static::lazy_static;
use std::sync::Arc;
use swayipc_async::{Connection, Event, EventType, Node, WorkspaceChange, WorkspaceEvent};
use tokio::sync::broadcast::{channel, Receiver, Sender};
use tokio::sync::Mutex;
use tracing::{info, trace};
pub struct SwayEventClient {
#[derive(Debug)]
pub struct Client {
client: Arc<Mutex<Connection>>,
workspace_tx: Sender<WorkspaceUpdate>,
_workspace_rx: Receiver<WorkspaceUpdate>,
}
impl SwayEventClient {
fn new() -> Self {
impl Client {
pub(crate) async fn new() -> Result<Self> {
// Avoid using `arc_mut!` here because we need tokio Mutex.
let client = Arc::new(Mutex::new(Connection::new().await?));
info!("Sway IPC subscription client connected");
let (workspace_tx, workspace_rx) = channel(16);
{
// create 2nd client as subscription takes ownership
let client = Connection::new().await?;
let workspace_tx = workspace_tx.clone();
spawn(async move {
let client = Connection::new().await?;
info!("Sway IPC subscription client connected");
let event_types = [EventType::Workspace];
let mut events = client.subscribe(event_types).await?;
while let Some(event) = events.next().await {
@ -43,18 +46,18 @@ impl SwayEventClient {
});
}
Self {
Ok(Self {
client,
workspace_tx,
_workspace_rx: workspace_rx,
}
})
}
}
impl WorkspaceClient for SwayEventClient {
fn focus(&self, id: String) -> color_eyre::Result<()> {
impl WorkspaceClient for Client {
fn focus(&self, id: String) -> Result<()> {
await_sync(async move {
let client = get_client().await;
let mut client = client.lock().await;
let mut client = self.client.lock().await;
client.run_command(format!("workspace {id}")).await
})?;
Ok(())
@ -65,14 +68,12 @@ impl WorkspaceClient for SwayEventClient {
{
let tx = self.workspace_tx.clone();
await_sync(async {
let client = get_client().await;
let mut client = client.lock().await;
let client = self.client.clone();
await_sync(async {
let mut client = client.lock().await;
let workspaces = client.get_workspaces().await.expect("to get workspaces");
let workspaces = client
.get_workspaces()
.await
.expect("Failed to get workspaces");
let event =
WorkspaceUpdate::Init(workspaces.into_iter().map(Workspace::from).collect());
@ -84,27 +85,6 @@ impl WorkspaceClient for SwayEventClient {
}
}
lazy_static! {
static ref CLIENT: AsyncOnce<Arc<Mutex<Connection>>> = AsyncOnce::new(async {
let client = Connection::new()
.await
.expect("Failed to connect to Sway socket");
Arc::new(Mutex::new(client))
});
static ref SUB_CLIENT: SwayEventClient = SwayEventClient::new();
}
/// Gets the sway IPC client
async fn get_client() -> Arc<Mutex<Connection>> {
let client = CLIENT.get().await;
Arc::clone(client)
}
/// Gets the sway IPC event subscription client
pub fn get_sub_client() -> &'static SwayEventClient {
&SUB_CLIENT
}
impl From<Node> for Workspace {
fn from(node: Node) -> Self {
let visibility = Visibility::from(&node);