diff options
| author | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-05-20 22:03:49 +0300 |
|---|---|---|
| committer | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-05-20 22:08:26 +0300 |
| commit | df357b250c0fcf4edf2681d4f114e199afb51899 (patch) | |
| tree | eba744d9238057e8758e2098670e0561d920d998 /src/app | |
| parent | c584037c77c63f6a08f8837f357c89432b8043e7 (diff) | |
fix: clarify keybinding conflict warnings
refs #154
Diffstat (limited to 'src/app')
| -rw-r--r-- | src/app/input/modal.rs | 38 | ||||
| -rw-r--r-- | src/app/input/navigate.rs | 12 | ||||
| -rw-r--r-- | src/app/input/sidebar.rs | 8 | ||||
| -rw-r--r-- | src/app/mod.rs | 28 | ||||
| -rw-r--r-- | src/app/state.rs | 6 |
5 files changed, 52 insertions, 40 deletions
diff --git a/src/app/input/modal.rs b/src/app/input/modal.rs index 5b585221..084f44a9 100644 --- a/src/app/input/modal.rs +++ b/src/app/input/modal.rs @@ -67,7 +67,7 @@ pub(super) fn modal_action_from_buttons<A: Copy>( #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub(crate) enum GlobalMenuAction { - Quit, + Detach, WhatsNew, Keybinds, ReloadConfig, @@ -83,7 +83,7 @@ pub(super) fn global_menu_actions(state: &AppState) -> Vec<GlobalMenuAction> { if state.update_available.is_some() || state.latest_release_notes_available { actions.push(GlobalMenuAction::WhatsNew); } - actions.push(GlobalMenuAction::Quit); + actions.push(GlobalMenuAction::Detach); actions } @@ -111,19 +111,19 @@ fn open_update_release_notes(state: &mut AppState) { state.mode = Mode::ReleaseNotes; } -pub(super) fn request_quit_or_detach(state: &mut AppState) { - if state.quit_detaches { - state.detach_requested = true; - } else { +pub(super) fn request_detach(state: &mut AppState) { + if state.detach_exits { state.should_quit = true; + } else { + state.detach_requested = true; } } pub(super) fn apply_global_menu_action(state: &mut AppState, action: GlobalMenuAction) { match action { - GlobalMenuAction::Quit => { + GlobalMenuAction::Detach => { leave_modal(state); - request_quit_or_detach(state); + request_detach(state); } GlobalMenuAction::WhatsNew => open_update_release_notes(state), GlobalMenuAction::Keybinds => open_keybind_help(state), @@ -690,6 +690,28 @@ mod tests { } #[test] + fn detach_requests_client_detach_in_persistence_mode() { + let mut state = state_with_workspaces(&["test"]); + state.detach_exits = false; + + request_detach(&mut state); + + assert!(state.detach_requested); + assert!(!state.should_quit); + } + + #[test] + fn detach_exits_in_no_session_mode() { + let mut state = state_with_workspaces(&["test"]); + state.detach_exits = true; + + request_detach(&mut state); + + assert!(state.should_quit); + assert!(!state.detach_requested); + } + + #[test] fn global_menu_whats_new_opens_saved_release_notes() { let _guard = config_env_lock().lock().unwrap(); let path = temp_config_path("whats-new-saved-release-notes"); diff --git a/src/app/input/navigate.rs b/src/app/input/navigate.rs index 8bf10832..17180fed 100644 --- a/src/app/input/navigate.rs +++ b/src/app/input/navigate.rs @@ -479,7 +479,6 @@ pub(crate) enum NavigateAction { CyclePanePrevious, Help, Settings, - Quit, ReloadConfig, OpenNotificationTarget, Detach, @@ -545,7 +544,6 @@ fn action_for_key( for (bindings, action) in [ (&kb.help, NavigateAction::Help), (&kb.settings, NavigateAction::Settings), - (&kb.quit, NavigateAction::Quit), (&kb.workspace_picker, NavigateAction::WorkspacePicker), (&kb.new_workspace, NavigateAction::NewWorkspace), (&kb.rename_workspace, NavigateAction::RenameWorkspace), @@ -727,10 +725,6 @@ pub(super) fn execute_navigate_action_in_context( } NavigateAction::Help => super::modal::open_keybind_help(state), NavigateAction::Settings => super::settings::open_settings(state), - NavigateAction::Quit => { - super::modal::request_quit_or_detach(state); - leave_navigate_mode(state); - } NavigateAction::ReloadConfig => { state.request_reload_config = true; leave_navigate_mode(state); @@ -742,7 +736,7 @@ pub(super) fn execute_navigate_action_in_context( } } NavigateAction::Detach => { - state.detach_requested = true; + super::modal::request_detach(state); leave_navigate_mode(state); } } @@ -1449,9 +1443,9 @@ mod tests { } #[test] - fn persistence_mode_navigate_q_detaches_instead_of_quitting_server() { + fn navigate_q_detaches_in_persistence_mode() { let mut state = crate::app::state::AppState::test_new(); - state.quit_detaches = true; + state.detach_exits = false; handle_navigate_key( &mut state, diff --git a/src/app/input/sidebar.rs b/src/app/input/sidebar.rs index 7491c9c1..dc192e50 100644 --- a/src/app/input/sidebar.rs +++ b/src/app/input/sidebar.rs @@ -192,7 +192,7 @@ impl AppState { } else if self.latest_release_notes_available { labels.push("what's new"); } - labels.push(if self.quit_detaches { "detach" } else { "quit" }); + labels.push("detach"); labels } @@ -578,7 +578,7 @@ mod tests { "keybinds", "reload config", "update ready", - "quit" + "detach" ] ); assert!(!app.state.should_quit); @@ -587,7 +587,7 @@ mod tests { #[test] fn persistence_mode_menu_surfaces_detach_action() { let mut app = app_for_mouse_test(); - app.state.quit_detaches = true; + app.state.detach_exits = false; let launcher = app.state.global_launcher_rect(); app.handle_mouse(mouse( @@ -625,7 +625,7 @@ mod tests { "keybinds", "reload config", "what's new", - "quit" + "detach" ] ); } diff --git a/src/app/mod.rs b/src/app/mod.rs index 63bf690d..b87eec66 100644 --- a/src/app/mod.rs +++ b/src/app/mod.rs @@ -338,7 +338,7 @@ impl App { selected, mode, should_quit: false, - quit_detaches: !no_session, + detach_exits: no_session, detach_requested: false, request_new_workspace: false, request_new_tab: false, @@ -466,10 +466,7 @@ impl App { }); Self { - config_diagnostic_deadline: state - .config_diagnostic - .as_ref() - .map(|_| Instant::now() + Duration::from_secs(8)), + config_diagnostic_deadline: None, toast_deadline: None, state, event_tx, @@ -797,7 +794,7 @@ impl App { self.state.toast = None; self.state.config_diagnostic = crate::config::config_diagnostic_summary(&diagnostics); - self.config_diagnostic_deadline = Some(Instant::now() + Duration::from_secs(8)); + self.config_diagnostic_deadline = None; crate::config::ConfigReloadReport { status: crate::config::ConfigReloadStatus::Failed, diagnostics, @@ -827,11 +824,11 @@ impl App { self.state.keybinds = live.keybinds; } Err(keybind_diagnostics) => { - let mut message = keybind_diagnostics.join("; "); - if !message.contains("keeping current keybinds") { - message.push_str("; keeping current keybinds"); - } - diagnostics.push(message); + diagnostics.extend( + keybind_diagnostics + .into_iter() + .map(|diagnostic| format!("{diagnostic}; kept current keybinds")), + ); } } } @@ -928,7 +925,7 @@ impl App { } } else { self.state.config_diagnostic = crate::config::config_diagnostic_summary(&diagnostics); - self.config_diagnostic_deadline = Some(Instant::now() + Duration::from_secs(8)); + self.config_diagnostic_deadline = None; if notify_success { self.state.toast = Some(crate::app::state::ToastNotification { kind: crate::app::state::ToastKind::UpdateInstalled, @@ -1545,8 +1542,7 @@ mod tests { .config_diagnostic .as_deref() .is_some_and(|message| { - message.contains("keys.new_workspace") - && message.contains("keeping current keybinds") + message.contains("keys.new_workspace") && message.contains("kept current keybinds") })); std::env::remove_var(crate::config::CONFIG_PATH_ENV_VAR); @@ -2514,7 +2510,7 @@ mod tests { app.state.workspaces = vec![Workspace::test_new("test")]; app.state.active = Some(0); app.state.selected = 0; - app.state.quit_detaches = true; + app.state.detach_exits = false; // Start in navigate mode. app.state.mode = Mode::Navigate; @@ -2540,7 +2536,7 @@ mod tests { app.state.workspaces = vec![Workspace::test_new("test")]; app.state.active = Some(0); app.state.selected = 0; - app.state.quit_detaches = true; + app.state.detach_exits = false; // Start in terminal mode (default after workspace creation). app.state.mode = Mode::Terminal; diff --git a/src/app/state.rs b/src/app/state.rs index 921a82c9..7ee79c4a 100644 --- a/src/app/state.rs +++ b/src/app/state.rs @@ -900,8 +900,8 @@ pub struct AppState { pub selected: usize, pub mode: Mode, pub should_quit: bool, - /// In persistence mode, client quit actions detach instead of stopping the server. - pub quit_detaches: bool, + /// In monolithic --no-session mode, detach exits the app because there is no server to detach from. + pub detach_exits: bool, /// Set when the current client should detach from the persistent session. /// The server's event loop checks this and handles client detach. pub detach_requested: bool, @@ -1159,7 +1159,7 @@ impl AppState { selected: 0, mode: Mode::Navigate, should_quit: false, - quit_detaches: false, + detach_exits: false, detach_requested: false, request_new_workspace: false, request_new_tab: false, |
