feat: Add support IPC socket control over menu.

This commit is contained in:
2026-03-14 17:02:16 -04:00
parent cd1927fa9f
commit aad4c16d6e
15 changed files with 1501 additions and 185 deletions

View File

@@ -119,7 +119,13 @@ pub struct VisibleItem {
#[must_use]
#[derive(Debug)]
pub enum MenuResult {
Selected { items: Vec<(Value, usize)> },
Quicklist { items: Vec<(Value, usize)> },
Selected {
items: Vec<(Value, usize)>,
filter_text: String,
},
Quicklist {
items: Vec<(Value, usize)>,
filter_text: String,
},
Cancelled,
}

View File

@@ -190,6 +190,12 @@ impl<M: MutableMenu> MenuRunner<M> {
self.event_tx.subscribe()
}
/// Get a clone of the event broadcast sender. Useful for
/// IPC servers that need to create their own subscribers.
pub fn event_sender(&self) -> broadcast::Sender<MenuEvent> {
self.event_tx.clone()
}
/// Set a hook handler. Wraps it in a DebouncedDispatcher
/// with no debounce (all events fire immediately). Use
/// [`set_dispatcher`] for custom debounce settings.
@@ -615,7 +621,10 @@ impl<M: MutableMenu> MenuRunner<M> {
self.emit_hook(HookEvent::Close);
let _ = self.event_tx.send(MenuEvent::Selected(items.clone()));
return Ok(MenuResult::Selected { items });
return Ok(MenuResult::Selected {
items,
filter_text: self.filter_text.to_string(),
});
}
ActionOutcome::Quicklist { items } => {
let values: Vec<Value> = items.iter().map(|(v, _)| v.clone()).collect();
@@ -628,7 +637,10 @@ impl<M: MutableMenu> MenuRunner<M> {
self.emit_hook(HookEvent::Close);
let _ = self.event_tx.send(MenuEvent::Quicklist(values));
return Ok(MenuResult::Quicklist { items });
return Ok(MenuResult::Quicklist {
items,
filter_text: self.filter_text.to_string(),
});
}
ActionOutcome::Cancelled => {
info!("menu cancelled");
@@ -1360,7 +1372,7 @@ mod tests {
let result = handle.await.unwrap_or(Ok(MenuResult::Cancelled));
match result {
Ok(MenuResult::Quicklist { items }) => {
Ok(MenuResult::Quicklist { items, .. }) => {
// "alpha" matches "al"
assert!(!items.is_empty());
for (v, _) in &items {