1
0
Fork 0
mirror of https://github.com/Zedfrigg/ironbar.git synced 2025-07-03 19:51:03 +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

@ -26,9 +26,8 @@ use tokio::task::{block_in_place, JoinHandle};
use tracing::{debug, error, info, warn};
use universal_config::ConfigLoader;
use clients::wayland;
use crate::bar::{create_bar, Bar};
use crate::clients::Clients;
use crate::config::{Config, MonitorConfig};
use crate::error::ExitCode;
#[cfg(feature = "ipc")]
@ -104,12 +103,14 @@ lazy_static::lazy_static! {
#[derive(Debug)]
pub struct Ironbar {
bars: Rc<RefCell<Vec<Bar>>>,
clients: Rc<RefCell<Clients>>,
}
impl Ironbar {
fn new() -> Self {
Self {
bars: Rc::new(RefCell::new(vec![])),
clients: Rc::new(RefCell::new(Clients::new())),
}
}
@ -124,8 +125,8 @@ impl Ironbar {
let instance = Rc::new(self);
// force start wayland client ahead of ui
let wl = wayland::get_client();
lock!(wl).roundtrip();
let wl = instance.clients.borrow_mut().wayland();
wl.roundtrip();
app.connect_activate(move |app| {
if running.load(Ordering::Relaxed) {
@ -142,7 +143,7 @@ impl Ironbar {
}
}
*instance.bars.borrow_mut() = load_interface(app);
*instance.bars.borrow_mut() = load_interface(app, instance.clone());
let style_path = env::var("IRONBAR_CSS").ok().map_or_else(
|| {
@ -228,7 +229,7 @@ fn start_ironbar() {
}
/// Loads the Ironbar config and interface.
pub fn load_interface(app: &Application) -> Vec<Bar> {
pub fn load_interface(app: &Application, ironbar: Rc<Ironbar>) -> Vec<Bar> {
let display = Display::default().map_or_else(
|| {
let report = Report::msg("Failed to get default GTK display");
@ -264,7 +265,7 @@ pub fn load_interface(app: &Application) -> Vec<Bar> {
}
}
match create_bars(app, &display, &config) {
match create_bars(app, &display, &config, &ironbar) {
Ok(bars) => {
debug!("Created {} bars", bars.len());
bars
@ -277,9 +278,14 @@ pub fn load_interface(app: &Application) -> Vec<Bar> {
}
/// Creates each of the bars across each of the (configured) outputs.
fn create_bars(app: &Application, display: &Display, config: &Config) -> Result<Vec<Bar>> {
let wl = wayland::get_client();
let outputs = lock!(wl).get_outputs();
fn create_bars(
app: &Application,
display: &Display,
config: &Config,
ironbar: &Rc<Ironbar>,
) -> Result<Vec<Bar>> {
let wl = ironbar.clients.borrow_mut().wayland();
let outputs = wl.output_info_all();
debug!("Received {} outputs from Wayland", outputs.len());
debug!("Outputs: {:?}", outputs);
@ -313,17 +319,27 @@ fn create_bars(app: &Application, display: &Display, config: &Config) -> Result<
&monitor,
monitor_name.to_string(),
config.clone(),
ironbar.clone(),
)?]
}
Some(MonitorConfig::Multiple(configs)) => configs
.iter()
.map(|config| create_bar(app, &monitor, monitor_name.to_string(), config.clone()))
.map(|config| {
create_bar(
app,
&monitor,
monitor_name.to_string(),
config.clone(),
ironbar.clone(),
)
})
.collect::<Result<_>>()?,
None if show_default_bar => vec![create_bar(
app,
&monitor,
monitor_name.to_string(),
config.clone(),
ironbar.clone(),
)?],
None => vec![],
};
@ -364,11 +380,8 @@ where
/// This is not an `async` operation
/// so can be used outside of an async function.
///
/// Do note it must be called from within a Tokio runtime still.
///
/// Use sparingly! Prefer async functions wherever possible.
///
/// TODO: remove all instances of this once async trait funcs are stable
/// Use sparingly, as this risks blocking the UI thread!
/// Prefer async functions wherever possible.
pub fn await_sync<F: Future>(f: F) -> F::Output {
block_in_place(|| Ironbar::runtime().block_on(f))
}