mirror of
https://github.com/Zedfrigg/ironbar.git
synced 2025-07-03 11:41:04 +02:00
Major module refactor (#19)
* refactor: major module restructuring Modules now implement a "controller", which allows for separation of logic from UI code and enforces a tighter structure around how modules should be written. The introduction of this change required major refactoring or even rewriting of all modules. This also better integrates the popup into modules, making it easier for data to be passed around without fetching the same thing twice The refactor also improves some client code, switching from `ksway` to the much more stable `swayipc-async`. Partial multi-monitor for the tray module has been added. BREAKING CHANGE: The `mpd` module config has changed, moving the icons to their own object.
This commit is contained in:
parent
daafa0943e
commit
720ba7bfb0
26 changed files with 2381 additions and 1846 deletions
|
@ -1,10 +1,11 @@
|
|||
use crate::modules::{Module, ModuleInfo};
|
||||
use crate::modules::{Module, ModuleInfo, ModuleUpdateEvent, ModuleWidget, WidgetContext};
|
||||
use color_eyre::{eyre::Report, eyre::Result, eyre::WrapErr, Section};
|
||||
use gtk::prelude::*;
|
||||
use gtk::Label;
|
||||
use serde::Deserialize;
|
||||
use std::process::Command;
|
||||
use tokio::spawn;
|
||||
use tokio::sync::mpsc::{Receiver, Sender};
|
||||
use tokio::time::sleep;
|
||||
use tracing::{error, instrument};
|
||||
|
||||
|
@ -23,57 +24,78 @@ const fn default_interval() -> u64 {
|
|||
}
|
||||
|
||||
impl Module<Label> for ScriptModule {
|
||||
fn into_widget(self, _info: &ModuleInfo) -> Result<Label> {
|
||||
let label = Label::builder().use_markup(true).build();
|
||||
type SendMessage = String;
|
||||
type ReceiveMessage = ();
|
||||
|
||||
let (tx, rx) = glib::MainContext::channel(glib::PRIORITY_DEFAULT);
|
||||
fn spawn_controller(
|
||||
&self,
|
||||
_info: &ModuleInfo,
|
||||
tx: Sender<ModuleUpdateEvent<Self::SendMessage>>,
|
||||
_rx: Receiver<Self::ReceiveMessage>,
|
||||
) -> Result<()> {
|
||||
let interval = self.interval;
|
||||
let path = self.path.clone();
|
||||
spawn(async move {
|
||||
loop {
|
||||
match self.run_script() {
|
||||
Ok(stdout) => tx.send(stdout).expect("Failed to send stdout"),
|
||||
match run_script(&path) {
|
||||
Ok(stdout) => tx
|
||||
.send(ModuleUpdateEvent::Update(stdout))
|
||||
.await
|
||||
.expect("Failed to send stdout"),
|
||||
Err(err) => error!("{:?}", err),
|
||||
}
|
||||
|
||||
sleep(tokio::time::Duration::from_millis(self.interval)).await;
|
||||
sleep(tokio::time::Duration::from_millis(interval)).await;
|
||||
}
|
||||
});
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn into_widget(
|
||||
self,
|
||||
context: WidgetContext<Self::SendMessage, Self::ReceiveMessage>,
|
||||
_info: &ModuleInfo,
|
||||
) -> Result<ModuleWidget<Label>> {
|
||||
let label = Label::builder().use_markup(true).build();
|
||||
|
||||
{
|
||||
let label = label.clone();
|
||||
rx.attach(None, move |s| {
|
||||
context.widget_rx.attach(None, move |s| {
|
||||
label.set_label(s.as_str());
|
||||
Continue(true)
|
||||
});
|
||||
}
|
||||
|
||||
Ok(label)
|
||||
Ok(ModuleWidget {
|
||||
widget: label,
|
||||
popup: None,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl ScriptModule {
|
||||
#[instrument]
|
||||
fn run_script(&self) -> Result<String> {
|
||||
let output = Command::new("sh")
|
||||
.arg("-c")
|
||||
.arg(&self.path)
|
||||
.output()
|
||||
.wrap_err("Failed to get script output")?;
|
||||
#[instrument]
|
||||
fn run_script(path: &str) -> Result<String> {
|
||||
let output = Command::new("sh")
|
||||
.arg("-c")
|
||||
.arg(path)
|
||||
.output()
|
||||
.wrap_err("Failed to get script output")?;
|
||||
|
||||
if output.status.success() {
|
||||
let stdout = String::from_utf8(output.stdout)
|
||||
.map(|output| output.trim().to_string())
|
||||
.wrap_err("Script stdout not valid UTF-8")?;
|
||||
if output.status.success() {
|
||||
let stdout = String::from_utf8(output.stdout)
|
||||
.map(|output| output.trim().to_string())
|
||||
.wrap_err("Script stdout not valid UTF-8")?;
|
||||
|
||||
Ok(stdout)
|
||||
} else {
|
||||
let stderr = String::from_utf8(output.stderr)
|
||||
.map(|output| output.trim().to_string())
|
||||
.wrap_err("Script stderr not valid UTF-8")?;
|
||||
Ok(stdout)
|
||||
} else {
|
||||
let stderr = String::from_utf8(output.stderr)
|
||||
.map(|output| output.trim().to_string())
|
||||
.wrap_err("Script stderr not valid UTF-8")?;
|
||||
|
||||
Err(Report::msg(stderr)
|
||||
.wrap_err("Script returned non-zero error code")
|
||||
.suggestion("Check the path to your script")
|
||||
.suggestion("Check the script for errors"))
|
||||
}
|
||||
Err(Report::msg(stderr)
|
||||
.wrap_err("Script returned non-zero error code")
|
||||
.suggestion("Check the path to your script")
|
||||
.suggestion("Check the script for errors"))
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue