diff options
| author | Can Celik <ogulcancelik@gmail.com> | 2026-09-21 00:29:45 +0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-09-21 00:29:45 +0300 |
| commit | 0ff0f27e222633c97ba4291f6b9be4137002ca84 (patch) | |
| tree | 97ee77c8a85801ab90133492ddd71b3ce635b8fb /src/ui | |
| parent | f090ce95d05d2e7811869be93f9a23bf4ac2c3af (diff) | |
fix: preserve session layouts across shutdown and restore failures (#4400)
* fix: preserve session layouts across shutdown and restore failures
refs #4320
* test: update subscription fixture for pane restore errors
---------
Co-authored-by: JJ Liebig <jonathan.liebig@gmail.com>
Diffstat (limited to 'src/ui')
| -rw-r--r-- | src/ui/panes.rs | 42 |
1 files changed, 40 insertions, 2 deletions
diff --git a/src/ui/panes.rs b/src/ui/panes.rs index ab3e352a..be9df8da 100644 --- a/src/ui/panes.rs +++ b/src/ui/panes.rs @@ -2,7 +2,7 @@ use ratatui::{ buffer::Buffer, layout::Rect, style::{Color, Modifier, Style}, - widgets::{Block, Borders}, + widgets::{Block, Borders, Paragraph, Wrap}, Frame, }; @@ -392,9 +392,10 @@ pub(super) fn render_panes( pane_infos: &[PaneInfo], split_borders: &[crate::layout::SplitBorder], ) { - let Some(ws_idx) = target.map(|target| target.workspace_index) else { + let Some(target) = target else { return; }; + let ws_idx = target.workspace_index; let Some(ws) = app.workspaces.get(ws_idx) else { return; }; @@ -406,6 +407,17 @@ pub(super) fn render_panes( && app.pane_exposes_host_cursor(ws_idx, info.id); rt.render(frame, info.inner_rect, show_cursor); render_pane_scrollbar(app, frame, info, rt); + } else if let Some(reason) = ws + .tabs + .get(target.tab_index) + .and_then(|tab| tab.terminal_id(info.id)) + .and_then(|id| app.terminals.get(id)) + .and_then(|terminal| terminal.restore_error.as_deref()) + { + frame.render_widget( + Paragraph::new(reason).wrap(Wrap { trim: false }), + info.inner_rect, + ); } } @@ -848,6 +860,32 @@ mod tests { } #[test] + fn unavailable_pane_renders_restore_failure_without_a_runtime() { + let mut app = AppState::test_new(); + app.workspaces = vec![Workspace::test_new("unavailable")]; + app.active = Some(0); + app.ensure_test_terminals(); + let pane_id = app.workspaces[0].tabs[0].root_pane; + let terminal_id = app.workspaces[0].terminal_id(pane_id).unwrap().clone(); + app.terminals.get_mut(&terminal_id).unwrap().restore_error = + Some("Saved directory is unavailable. Restart to retry.".into()); + let (buffer, cursor, _, _) = crate::server::render_stream::render_tab_surface_virtual( + &app, + &TerminalRuntimeRegistry::new(), + Some(crate::ui::TabSurfaceTarget { + workspace_index: 0, + tab_index: 0, + }), + Rect::new(0, 0, 80, 24), + false, + Default::default(), + ); + let text: String = buffer.content.iter().map(|cell| cell.symbol()).collect(); + assert!(text.contains("Saved directory is unavailable.")); + assert!(cursor.is_none_or(|cursor| !cursor.visible)); + } + + #[test] fn pane_border_title_trims_and_truncates() { assert_eq!( pane_border_title(" claude ", 20, false).as_deref(), |
