@@ -51,6 +51,8 @@ pub struct App { |
| 51 | 51 | should_quit: bool, |
| 52 | 52 | /// Pane divider resize in progress (split pane pointer path). |
| 53 | 53 | pane_resize_path: Option<Vec<bool>>, |
| 54 | + /// Sidebar resize in progress. |
| 55 | + sidebar_resizing: bool, |
| 54 | 56 | /// Last click time for double-click detection. |
| 55 | 57 | last_click_time: Option<Instant>, |
| 56 | 58 | /// Last click position for double-click detection. |
@@ -190,6 +192,7 @@ impl App { |
| 190 | 192 | help_modal, |
| 191 | 193 | should_quit: false, |
| 192 | 194 | pane_resize_path: None, |
| 195 | + sidebar_resizing: false, |
| 193 | 196 | last_click_time: None, |
| 194 | 197 | last_click_pos: None, |
| 195 | 198 | drag_source_path: None, |
@@ -326,6 +329,12 @@ impl App { |
| 326 | 329 | return; |
| 327 | 330 | } |
| 328 | 331 | |
| 332 | + // Check for sidebar resize handle |
| 333 | + if self.sidebar.is_resize_handle(pos) { |
| 334 | + self.sidebar_resizing = true; |
| 335 | + return; |
| 336 | + } |
| 337 | + |
| 329 | 338 | // Check for pane split divider resize start |
| 330 | 339 | if let Some(path) = self.root_pane.split_divider_at(pos) { |
| 331 | 340 | self.pane_resize_path = Some(path); |
@@ -416,8 +425,9 @@ impl App { |
| 416 | 425 | self.drag_active = false; |
| 417 | 426 | self.sidebar.set_drop_highlight(false); |
| 418 | 427 | |
| 419 | | - // Clear pane resize |
| 428 | + // Clear resize states |
| 420 | 429 | self.pane_resize_path = None; |
| 430 | + self.sidebar_resizing = false; |
| 421 | 431 | |
| 422 | 432 | if let Some(pane) = self.focused_pane_mut() { |
| 423 | 433 | if pane.is_resizing() { |
@@ -431,6 +441,15 @@ impl App { |
| 431 | 441 | |
| 432 | 442 | /// Handle mouse move. |
| 433 | 443 | fn handle_mouse_move(&mut self, pos: Point) { |
| 444 | + // Handle sidebar resize in progress |
| 445 | + if self.sidebar_resizing { |
| 446 | + let new_width = (pos.x - self.sidebar.bounds().x).max(0) as u32; |
| 447 | + self.sidebar.set_width(new_width); |
| 448 | + let size = self.renderer.size(); |
| 449 | + self.update_layout(size.width, size.height); |
| 450 | + return; |
| 451 | + } |
| 452 | + |
| 434 | 453 | // Handle pane divider resize in progress |
| 435 | 454 | if let Some(path) = &self.pane_resize_path { |
| 436 | 455 | let path_clone = path.clone(); |
@@ -1072,10 +1091,16 @@ impl App { |
| 1072 | 1091 | |
| 1073 | 1092 | /// Update layout. |
| 1074 | 1093 | fn update_layout(&mut self, width: u32, height: u32) { |
| 1075 | | - let sidebar_w = self.sidebar.width(); |
| 1094 | + // Preserve current sidebar width (or use default if sidebar is hidden) |
| 1095 | + let current_sidebar_width = if self.sidebar.is_visible() { |
| 1096 | + self.sidebar.bounds().width |
| 1097 | + } else { |
| 1098 | + SIDEBAR_WIDTH |
| 1099 | + }; |
| 1100 | + let sidebar_w = if self.sidebar.is_visible() { current_sidebar_width } else { 0 }; |
| 1076 | 1101 | let header_height = TAB_BAR_HEIGHT + TOOLBAR_HEIGHT + BREADCRUMB_HEIGHT; |
| 1077 | 1102 | |
| 1078 | | - self.sidebar.set_bounds(Rect::new(0, 0, SIDEBAR_WIDTH, height)); |
| 1103 | + self.sidebar.set_bounds(Rect::new(0, 0, current_sidebar_width, height)); |
| 1079 | 1104 | |
| 1080 | 1105 | self.tab_bar.set_bounds(Rect::new( |
| 1081 | 1106 | sidebar_w as i32, |