a lightweight, interval-based utility to combat digital strain through "Ma" (intentional pauses) for the eyes and body.
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix: pause timer on screen lock, debounce tray GTK

+21 -1
+6
src/idle/linux.rs
··· 41 41 Err(_) => return Ok(None), 42 42 }; 43 43 44 + // Screen is locked → treat as fully idle so the timer pauses. 45 + let locked: bool = proxy.call("GetActive", &()).unwrap_or(false); 46 + if locked { 47 + return Ok(Some(Duration::from_secs(u32::MAX as u64))); 48 + } 49 + 44 50 // GetSessionIdleTime returns idle time in milliseconds. 45 51 let ms: u32 = match proxy.call("GetSessionIdleTime", &()) { 46 52 Ok(v) => v,
+15 -1
src/tray.rs
··· 1 + use std::cell::{Cell, RefCell}; 1 2 use std::time::Duration; 2 3 3 4 use muda::{Menu, MenuEvent, MenuItem, PredefinedMenuItem, Submenu}; ··· 20 21 pause_items: Vec<(MenuItem, u64)>, 21 22 item_settings: MenuItem, 22 23 item_quit: MenuItem, 24 + last_paused: Cell<Option<bool>>, 25 + last_tooltip: RefCell<String>, 23 26 } 24 27 25 28 impl AppTray { ··· 67 70 pause_items, 68 71 item_settings, 69 72 item_quit, 73 + last_paused: Cell::new(None), 74 + last_tooltip: RefCell::new(String::new()), 70 75 }) 71 76 } 72 77 73 - /// Set icon and menu state to reflect paused state. 78 + /// Set icon and menu state to reflect paused state. No-op if state unchanged. 74 79 pub fn set_paused(&self, paused: bool) { 80 + if self.last_paused.get() == Some(paused) { 81 + return; 82 + } 83 + self.last_paused.set(Some(paused)); 75 84 let _ = self._tray.set_icon(Some(if paused { 76 85 self.icon_paused.clone() 77 86 } else { ··· 80 89 let _ = self.item_resume.set_enabled(paused); 81 90 } 82 91 92 + /// Update tray tooltip. No-op if text unchanged. 83 93 pub fn set_tooltip(&self, text: &str) { 94 + if *self.last_tooltip.borrow() == text { 95 + return; 96 + } 97 + *self.last_tooltip.borrow_mut() = text.to_owned(); 84 98 let _ = self._tray.set_tooltip(Some(text)); 85 99 } 86 100