From 6120a83180ee8756264d63f5627f178b058738a8 Mon Sep 17 00:00:00 2001 From: Greg Hendrickson Date: Tue, 27 Jan 2026 20:17:20 +0000 Subject: [PATCH] Fix terminal size detection + proper resize handling - Connect resize handler to process channel - Re-fetch terminal size before each render - Improved screen clearing to remove artifacts - Added debug logging for terminal size changes --- src/shellmate/ssh/server.py | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/src/shellmate/ssh/server.py b/src/shellmate/ssh/server.py index 3591b55..a27b09d 100644 --- a/src/shellmate/ssh/server.py +++ b/src/shellmate/ssh/server.py @@ -53,22 +53,32 @@ class TerminalSession: self.process = process self.width = 80 self.height = 24 - self._update_size() self._resize_event = asyncio.Event() + self._update_size() + + # Connect resize handler to process + process.channel.set_terminal_size_handler(self.handle_resize) def _update_size(self): """Update terminal size from process.""" - size = self.process.get_terminal_size() - if size: - self.width = max(size[0], 40) - self.height = max(size[1], 10) + try: + size = self.process.get_terminal_size() + if size and len(size) >= 2: + w, h = size[0], size[1] + if w > 0: + self.width = max(w, 40) + if h > 0: + self.height = max(h, 10) + logger.debug(f"Terminal size updated: {self.width}x{self.height}") + except Exception as e: + logger.warning(f"Could not get terminal size: {e}") def handle_resize(self, width, height, pixwidth, pixheight): """Handle terminal resize event.""" + logger.debug(f"Resize event: {width}x{height}") self.width = max(width, 40) self.height = max(height, 10) self._resize_event.set() - self._resize_event.clear() def write(self, data: str): """Write string data to terminal.""" @@ -77,8 +87,9 @@ class TerminalSession: self.process.stdout.write(data) def clear(self): - """Clear screen and move cursor home.""" - self.write("\033[2J\033[H") + """Clear screen completely and move cursor home.""" + # Reset scrolling region, clear entire screen, move to home + self.write("\033[r\033[2J\033[3J\033[H") def hide_cursor(self): self.write("\033[?25l") @@ -142,6 +153,9 @@ async def run_simple_menu(process, session: TerminalSession, username: str, mode def render_menu(): """Render the main menu centered on screen.""" + # Re-fetch terminal size before rendering + session._update_size() + writer = ProcessWriter(session) console = Console(file=writer, width=session.width, height=session.height, force_terminal=True, color_system="truecolor")