aboutsummaryrefslogtreecommitdiff
path: root/src/app
diff options
context:
space:
mode:
authorOgulcan Celik <ogulcancelik@gmail.com>2026-05-11 23:47:51 +0300
committerOgulcan Celik <ogulcancelik@gmail.com>2026-05-11 23:47:51 +0300
commit8d5dca8cfe2d580835d3392d0ebdff57f7de7298 (patch)
treeabd77f8d580b7e6e187e2512cd71205adb3e844a /src/app
parentfe693f613a23452e68589a4337863f217cc57930 (diff)
feat: add notification target keybind
Diffstat (limited to 'src/app')
-rw-r--r--src/app/input/mouse.rs2
-rw-r--r--src/app/input/navigate.rs45
-rw-r--r--src/app/state.rs2
3 files changed, 48 insertions, 1 deletions
diff --git a/src/app/input/mouse.rs b/src/app/input/mouse.rs
index f7997807..99157d0d 100644
--- a/src/app/input/mouse.rs
+++ b/src/app/input/mouse.rs
@@ -1009,7 +1009,7 @@ impl AppState {
&& rect_contains(self.view.toast_hit_area, col, row)
}
- fn focus_toast_target(&mut self) {
+ pub(crate) fn focus_toast_target(&mut self) {
let Some(target) = self.toast.as_ref().and_then(|toast| toast.target.clone()) else {
return;
};
diff --git a/src/app/input/navigate.rs b/src/app/input/navigate.rs
index bb88c46b..ce3d9cf4 100644
--- a/src/app/input/navigate.rs
+++ b/src/app/input/navigate.rs
@@ -380,6 +380,7 @@ pub(crate) enum NavigateAction {
EnterResizeMode,
ToggleSidebar,
ReloadConfig,
+ OpenNotificationTarget,
Detach,
}
@@ -464,6 +465,12 @@ fn navigate_action_for_key(state: &AppState, key: &KeyEvent) -> Option<NavigateA
return Some(NavigateAction::ReloadConfig);
}
if kb
+ .open_notification_target
+ .is_some_and(|(code, mods)| key_matches(key, code, mods))
+ {
+ return Some(NavigateAction::OpenNotificationTarget);
+ }
+ if kb
.detach
.is_some_and(|(code, mods)| key_matches(key, code, mods))
{
@@ -553,6 +560,12 @@ pub(super) fn execute_navigate_action(state: &mut AppState, action: NavigateActi
state.request_reload_config = true;
leave_navigate_mode(state);
}
+ NavigateAction::OpenNotificationTarget => {
+ state.focus_toast_target();
+ if state.mode == Mode::Navigate {
+ leave_navigate_mode(state);
+ }
+ }
NavigateAction::Detach => {
state.detach_requested = true;
leave_navigate_mode(state);
@@ -653,6 +666,38 @@ mod tests {
}
#[test]
+ fn custom_open_notification_key_focuses_current_toast_target() {
+ let mut state = state_with_workspaces(&["one", "two"]);
+ state.active = Some(0);
+ state.selected = 0;
+ state.mode = Mode::Navigate;
+ state.keybinds.open_notification_target = Some((KeyCode::Char('g'), KeyModifiers::empty()));
+ state.keybinds.open_notification_target_label = Some("g".into());
+ let target_workspace_id = state.workspaces[1].id.clone();
+ let target_pane = state.workspaces[1].tabs[0].root_pane;
+ state.toast = Some(crate::app::state::ToastNotification {
+ kind: crate::app::state::ToastKind::NeedsAttention,
+ title: "pi needs attention".into(),
+ context: "two".into(),
+ target: Some(crate::app::state::ToastTarget {
+ workspace_id: target_workspace_id,
+ pane_id: target_pane,
+ }),
+ });
+
+ handle_navigate_key(
+ &mut state,
+ KeyEvent::new(KeyCode::Char('g'), KeyModifiers::empty()),
+ );
+
+ assert_eq!(state.active, Some(1));
+ assert_eq!(state.selected, 1);
+ assert_eq!(state.workspaces[1].focused_pane_id(), Some(target_pane));
+ assert!(state.toast.is_none());
+ assert_eq!(state.mode, Mode::Terminal);
+ }
+
+ #[test]
fn movement_action_stays_in_navigate_mode() {
let mut state = state_with_workspaces(&["a", "b"]);
state.selected = 0;
diff --git a/src/app/state.rs b/src/app/state.rs
index dd081298..3791f674 100644
--- a/src/app/state.rs
+++ b/src/app/state.rs
@@ -897,6 +897,8 @@ impl AppState {
detach_label: None,
reload_config: None,
reload_config_label: None,
+ open_notification_target: None,
+ open_notification_target_label: None,
previous_workspace: None,
previous_workspace_label: None,
next_workspace: None,