aboutsummaryrefslogtreecommitdiff
path: root/crates/dinggerd/src/hooks.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/dinggerd/src/hooks.rs')
-rw-r--r--crates/dinggerd/src/hooks.rs27
1 files changed, 26 insertions, 1 deletions
diff --git a/crates/dinggerd/src/hooks.rs b/crates/dinggerd/src/hooks.rs
index a649fa0..b2f9e97 100644
--- a/crates/dinggerd/src/hooks.rs
+++ b/crates/dinggerd/src/hooks.rs
@@ -18,6 +18,9 @@
//! order, so a turn that starts and finishes between two polls is still a
//! completion, and each report wakes the watcher immediately.
//!
+//! `{"method":"pane.mark_unread","params":{"pane_id":"%3"}}` marks an idle
+//! agent unread (`dingger unread`, pi's /unread): it shows as done again.
+//!
//! Each line is answered with `{"ok":true}`.
//!
//! `{"method":"poke"}` only wakes the watcher; `dingger focus` and tmux's
@@ -26,7 +29,7 @@
//! until the next report or until the pane stops running the agent; screen
//! detection is the fallback for panes that never report.
-use std::collections::HashMap;
+use std::collections::{HashMap, HashSet};
use std::io::{BufRead, BufReader};
use std::os::unix::net::{UnixListener, UnixStream};
use std::path::PathBuf;
@@ -68,6 +71,20 @@ fn reports() -> MutexGuard<'static, HashMap<String, PaneReports>> {
.unwrap_or_else(|poisoned| poisoned.into_inner())
}
+/// Panes marked unread, not yet applied by the watcher.
+fn unread_marks() -> MutexGuard<'static, HashSet<String>> {
+ static MARKS: OnceLock<Mutex<HashSet<String>>> = OnceLock::new();
+ MARKS
+ .get_or_init(|| Mutex::new(HashSet::new()))
+ .lock()
+ .unwrap_or_else(|poisoned| poisoned.into_inner())
+}
+
+/// Whether the pane was marked unread since the last call.
+pub fn take_unread(pane_id: &str) -> bool {
+ unread_marks().remove(pane_id)
+}
+
fn wake_signal() -> &'static (Mutex<bool>, Condvar) {
static WAKE: OnceLock<(Mutex<bool>, Condvar)> = OnceLock::new();
WAKE.get_or_init(|| (Mutex::new(false), Condvar::new()))
@@ -145,6 +162,14 @@ fn handle_stream(stream: UnixStream) {
wake();
continue;
}
+ if message.method == "pane.mark_unread" {
+ if let Some(params) = message.params {
+ info!(pane = %params.pane_id, "marked unread");
+ unread_marks().insert(params.pane_id);
+ wake();
+ }
+ continue;
+ }
let (true, Some(params)) = (message.method == "pane.report_agent", message.params) else {
continue;
};