@@ -8,6 +8,7 @@ use super::primitives::{draw_text, fill_rect, Canvas, Color, Rect, TextStyle};
88use super :: terminal:: TerminalPane ;
99use alloc:: collections:: VecDeque ;
1010use alloc:: string:: String ;
11+ use alloc:: vec:: Vec ;
1112use spin:: Mutex ;
1213
1314// Architecture-specific framebuffer imports
@@ -103,6 +104,10 @@ pub struct TerminalManager {
103104 has_unread : [ bool ; 2 ] ,
104105 /// Scroll offset for Logs tab (0 = following tail, >0 = scrolled up)
105106 logs_scroll_offset : usize ,
107+ /// Saved pixel data for the shell terminal area (saved when switching away)
108+ shell_pixel_backup : Option < Vec < u8 > > ,
109+ /// Saved cursor position for the shell terminal (col, row)
110+ shell_cursor_backup : ( usize , usize ) ,
106111}
107112
108113impl TerminalManager {
@@ -136,6 +141,8 @@ impl TerminalManager {
136141 tab_shortcuts : [ "F1" , "F2" ] ,
137142 has_unread : [ false , false ] ,
138143 logs_scroll_offset : 0 ,
144+ shell_pixel_backup : None ,
145+ shell_cursor_backup : ( 0 , 0 ) ,
139146 }
140147 }
141148
@@ -155,6 +162,12 @@ impl TerminalManager {
155162 // Hide cursor
156163 self . terminal_pane . draw_cursor ( canvas, false ) ;
157164
165+ // If leaving the Shell tab, save its pixel content and cursor position
166+ if self . active_idx == TerminalId :: Shell as usize {
167+ self . shell_cursor_backup = self . terminal_pane . cursor ( ) ;
168+ self . shell_pixel_backup = Some ( self . save_terminal_pixels ( canvas) ) ;
169+ }
170+
158171 self . active_idx = new_idx;
159172 self . has_unread [ new_idx] = false ;
160173
@@ -165,8 +178,12 @@ impl TerminalManager {
165178 // Restore content for the new active terminal
166179 match id {
167180 TerminalId :: Shell => {
168- // Shell: just show prompt (shell will redraw its state)
169- self . terminal_pane . write_str ( canvas, "breenix> " ) ;
181+ // Restore the saved shell pixel content
182+ if let Some ( ref saved) = self . shell_pixel_backup {
183+ self . restore_terminal_pixels ( canvas, saved) ;
184+ }
185+ let ( col, row) = self . shell_cursor_backup ;
186+ self . terminal_pane . set_cursor ( col, row) ;
170187 }
171188 TerminalId :: Logs => {
172189 // Reset scroll to follow tail when switching to Logs
@@ -198,6 +215,46 @@ impl TerminalManager {
198215 self . terminal_pane . set_cursor ( 0 , 0 ) ;
199216 }
200217
218+ /// Save the terminal content area pixels to a Vec.
219+ fn save_terminal_pixels ( & self , canvas : & impl Canvas ) -> Vec < u8 > {
220+ let pane_y = self . region_y + TAB_HEIGHT + 2 ;
221+ let pane_height = self . region_height . saturating_sub ( TAB_HEIGHT + 2 ) ;
222+ let bpp = canvas. bytes_per_pixel ( ) ;
223+ let stride = canvas. stride ( ) ;
224+ let buffer = canvas. buffer ( ) ;
225+ let row_bytes = self . region_width * bpp;
226+
227+ let mut saved = Vec :: with_capacity ( row_bytes * pane_height) ;
228+ for row in 0 ..pane_height {
229+ let offset = ( pane_y + row) * stride * bpp + self . region_x * bpp;
230+ if offset + row_bytes <= buffer. len ( ) {
231+ saved. extend_from_slice ( & buffer[ offset..offset + row_bytes] ) ;
232+ }
233+ }
234+ saved
235+ }
236+
237+ /// Restore previously saved terminal content area pixels.
238+ fn restore_terminal_pixels ( & self , canvas : & mut impl Canvas , saved : & [ u8 ] ) {
239+ let pane_y = self . region_y + TAB_HEIGHT + 2 ;
240+ let pane_height = self . region_height . saturating_sub ( TAB_HEIGHT + 2 ) ;
241+ let bpp = canvas. bytes_per_pixel ( ) ;
242+ let stride = canvas. stride ( ) ;
243+ let row_bytes = self . region_width * bpp;
244+
245+ let buffer = canvas. buffer_mut ( ) ;
246+ let mut src_offset = 0 ;
247+ for row in 0 ..pane_height {
248+ let dst_offset = ( pane_y + row) * stride * bpp + self . region_x * bpp;
249+ if dst_offset + row_bytes <= buffer. len ( ) && src_offset + row_bytes <= saved. len ( ) {
250+ buffer[ dst_offset..dst_offset + row_bytes]
251+ . copy_from_slice ( & saved[ src_offset..src_offset + row_bytes] ) ;
252+ }
253+ src_offset += row_bytes;
254+ }
255+ canvas. mark_dirty_region ( self . region_x , pane_y, self . region_width , pane_height) ;
256+ }
257+
201258 /// Initialize the terminal manager.
202259 pub fn init ( & mut self , canvas : & mut impl Canvas ) {
203260 // Clear entire region
0 commit comments