oxwm

https://git.tonybtw.com/oxwm.git git://git.tonybtw.com/oxwm.git

added caching to ShellBlock so it only re-executes the shell command when the interval has elapsed, returning the cached output otherwise

Commit
84f46f68c001f5c657730e45827b5264801572fc
Parent
165e841
Author
tonybtw <tonybtw@tonybtw.com>
Date
2025-12-23 05:27:54

Diff

diff --git a/src/bar/blocks/shell.rs b/src/bar/blocks/shell.rs
index bdf6b6f..81930e5 100644
--- a/src/bar/blocks/shell.rs
+++ b/src/bar/blocks/shell.rs
@@ -1,13 +1,15 @@
 use super::Block;
 use crate::errors::BlockError;
 use std::process::Command;
-use std::time::Duration;
+use std::time::{Duration, Instant};
 
 pub struct ShellBlock {
     format: String,
     command: String,
     interval: Duration,
     color: u32,
+    cached_output: Option<String>,
+    last_run: Option<Instant>,
 }
 
 impl ShellBlock {
@@ -17,12 +19,12 @@ impl ShellBlock {
             command: command.to_string(),
             interval: Duration::from_secs(interval_secs),
             color,
+            cached_output: None,
+            last_run: None,
         }
     }
-}
 
-impl Block for ShellBlock {
-    fn content(&mut self) -> Result<String, BlockError> {
+    fn execute(&mut self) -> Result<String, BlockError> {
         let output = Command::new("sh")
             .arg("-c")
             .arg(&self.command)
@@ -37,7 +39,29 @@ impl Block for ShellBlock {
         }
 
         let result = String::from_utf8_lossy(&output.stdout).trim().to_string();
-        Ok(self.format.replace("{}", &result))
+        let formatted = self.format.replace("{}", &result);
+
+        self.cached_output = Some(formatted.clone());
+        self.last_run = Some(Instant::now());
+
+        Ok(formatted)
+    }
+}
+
+impl Block for ShellBlock {
+    fn content(&mut self) -> Result<String, BlockError> {
+        let should_refresh = match self.last_run {
+            None => true,
+            Some(last) => last.elapsed() >= self.interval,
+        };
+
+        if should_refresh {
+            return self.execute();
+        }
+
+        self.cached_output
+            .clone()
+            .ok_or_else(|| BlockError::CommandFailed("No cached output".to_string()))
     }
 
     fn interval(&self) -> Duration {