aboutsummaryrefslogtreecommitdiff
path: root/src/app
diff options
context:
space:
mode:
authorOgulcan Celik <ogulcancelik@gmail.com>2026-06-30 03:59:52 +0300
committerOgulcan Celik <ogulcancelik@gmail.com>2026-06-30 04:00:33 +0300
commitf54d8e8c0aee5d3ec9724234d1bcd418bff8ff2f (patch)
tree67eb7fd76f668feab4b5a4ef245eea854a04d42d /src/app
parent5e2dc40691e30f90c5fe3b1e60d5074ceb358556 (diff)
feat: add hidden collapsed sidebar mode
refs #842
Diffstat (limited to 'src/app')
-rw-r--r--src/app/input/sidebar.rs14
-rw-r--r--src/app/mod.rs27
-rw-r--r--src/app/state.rs2
3 files changed, 43 insertions, 0 deletions
diff --git a/src/app/input/sidebar.rs b/src/app/input/sidebar.rs
index fd631cd4..39affc83 100644
--- a/src/app/input/sidebar.rs
+++ b/src/app/input/sidebar.rs
@@ -497,6 +497,7 @@ mod tests {
use super::super::{app_for_mouse_test, capture_snapshot, mouse, unique_temp_path};
use crate::{
app::state::{AgentPanelSort, DragTarget, Mode},
+ config::SidebarCollapsedModeConfig,
detect::Agent,
workspace::Workspace,
};
@@ -969,6 +970,19 @@ mod tests {
}
#[test]
+ fn hidden_collapsed_sidebar_has_no_mouse_expand_hotspot() {
+ let mut app = app_for_mouse_test();
+ app.state.sidebar_collapsed = true;
+ app.state.sidebar_collapsed_mode = SidebarCollapsedModeConfig::Hidden;
+ app.state.view.sidebar_rect = Rect::new(0, 0, 0, 20);
+ app.state.view.terminal_area = Rect::new(0, 0, 80, 20);
+
+ app.handle_mouse(mouse(MouseEventKind::Down(MouseButton::Left), 0, 19));
+
+ assert!(app.state.sidebar_collapsed);
+ }
+
+ #[test]
fn clicking_expanded_sidebar_toggle_collapses_sidebar() {
let mut app = app_for_mouse_test();
app.state.sidebar_collapsed = false;
diff --git a/src/app/mod.rs b/src/app/mod.rs
index 2860664f..05518134 100644
--- a/src/app/mod.rs
+++ b/src/app/mod.rs
@@ -588,6 +588,7 @@ impl App {
sidebar_width_source,
sidebar_width_auto: false,
sidebar_collapsed: false,
+ sidebar_collapsed_mode: config.ui.sidebar_collapsed_mode,
sidebar_section_split,
agent_panel_sort,
next_agent_state_change_seq: 0,
@@ -1340,6 +1341,7 @@ impl App {
}
self.state.sidebar_min_width = config.ui.sidebar_min_width;
self.state.sidebar_max_width = config.ui.sidebar_max_width;
+ self.state.sidebar_collapsed_mode = config.ui.sidebar_collapsed_mode;
self.state.mobile_width_threshold = config.ui.mobile_width_threshold;
// Re-clamp the live width to the new bounds. No source guard — bounds
// always apply, including to widths owned by Persisted or Manual.
@@ -2500,6 +2502,31 @@ mod tests {
}
#[test]
+ fn reload_config_updates_sidebar_collapsed_mode() {
+ let _guard = config_env_lock().lock().unwrap();
+ let path = temp_config_path("reload-config-sidebar-collapsed-mode");
+ std::fs::create_dir_all(path.parent().unwrap()).unwrap();
+ std::env::set_var(crate::config::CONFIG_PATH_ENV_VAR, &path);
+
+ let mut app = test_app();
+ assert_eq!(
+ app.state.sidebar_collapsed_mode,
+ crate::config::SidebarCollapsedModeConfig::Compact
+ );
+
+ std::fs::write(&path, "[ui]\nsidebar_collapsed_mode = \"hidden\"\n").unwrap();
+ let report = app.reload_config();
+ assert_eq!(report.status, crate::config::ConfigReloadStatus::Applied);
+ assert_eq!(
+ app.state.sidebar_collapsed_mode,
+ crate::config::SidebarCollapsedModeConfig::Hidden
+ );
+
+ std::env::remove_var(crate::config::CONFIG_PATH_ENV_VAR);
+ let _ = std::fs::remove_dir_all(path.parent().unwrap());
+ }
+
+ #[test]
fn reload_config_updates_sidebar_bounds_and_reclamps() {
let _guard = config_env_lock().lock().unwrap();
let path = temp_config_path("reload-config-sidebar-bounds");
diff --git a/src/app/state.rs b/src/app/state.rs
index 9e5dbed1..694ff252 100644
--- a/src/app/state.rs
+++ b/src/app/state.rs
@@ -1349,6 +1349,7 @@ pub struct AppState {
pub sidebar_width_source: SidebarWidthSource,
pub sidebar_width_auto: bool,
pub sidebar_collapsed: bool,
+ pub sidebar_collapsed_mode: crate::config::SidebarCollapsedModeConfig,
/// Ratio of sidebar height allocated to the workspaces section.
pub sidebar_section_split: f32,
pub agent_panel_sort: AgentPanelSort,
@@ -1708,6 +1709,7 @@ impl AppState {
sidebar_width_source: SidebarWidthSource::ConfigDefault,
sidebar_width_auto: false,
sidebar_collapsed: false,
+ sidebar_collapsed_mode: crate::config::SidebarCollapsedModeConfig::Compact,
sidebar_section_split: 0.5,
agent_panel_sort: AgentPanelSort::Spaces,
next_agent_state_change_seq: 0,