Simplify terminal resize - no more size toggling

Remove all the -1 column toggle tricks for forcing tmux redraws.
Just set the size directly.
This commit is contained in:
GitHub Copilot
2026-01-24 16:53:53 +00:00
parent a771e1469e
commit 1a5222ab2a
2 changed files with 4 additions and 30 deletions
+3 -26
View File
@@ -113,12 +113,11 @@ class TerminalSession(Session):
return (buf[1], buf[0]) # cols, rows return (buf[1], buf[0]) # cols, rows
async def _sync_pyte_to_pty(self) -> None: async def _sync_pyte_to_pty(self) -> None:
"""Sync pyte screen size to actual PTY size and trigger redraw.""" """Sync pyte screen size to actual PTY size."""
if self.master_fd is None: if self.master_fd is None:
return return
loop = asyncio.get_running_loop() loop = asyncio.get_running_loop()
width, height = await loop.run_in_executor(None, self._get_terminal_size) width, height = await loop.run_in_executor(None, self._get_terminal_size)
needs_redraw = False
async with self._screen_lock: async with self._screen_lock:
if self._screen.columns != width or self._screen.lines != height: if self._screen.columns != width or self._screen.lines != height:
log.debug("Syncing pyte screen from %dx%d to %dx%d", log.debug("Syncing pyte screen from %dx%d to %dx%d",
@@ -126,42 +125,20 @@ class TerminalSession(Session):
self._screen.resize(height, width) self._screen.resize(height, width)
self._last_width = width self._last_width = width
self._last_height = height self._last_height = height
needs_redraw = True
# Toggle PTY size outside lock to force tmux to redraw
if needs_redraw:
await loop.run_in_executor(
None, self._set_terminal_size, width - 1, height
)
await loop.run_in_executor(
None, self._set_terminal_size, width, height
)
# Brief delay to let redraw data arrive
await asyncio.sleep(0.1)
async def set_terminal_size(self, width: int, height: int) -> None: async def set_terminal_size(self, width: int, height: int) -> None:
"""Set terminal size and force a redraw.""" """Set terminal size."""
# Track the size for reconnection
self._last_width = width self._last_width = width
self._last_height = height self._last_height = height
loop = asyncio.get_running_loop() loop = asyncio.get_running_loop()
# Toggle size to force tmux to redraw, then set final size
await loop.run_in_executor(None, self._set_terminal_size, width - 1, height)
await loop.run_in_executor(None, self._set_terminal_size, width, height) await loop.run_in_executor(None, self._set_terminal_size, width, height)
# Resize pyte screen to match # Resize pyte screen to match
async with self._screen_lock: async with self._screen_lock:
self._screen.resize(height, width) self._screen.resize(height, width)
async def force_redraw(self) -> None: async def force_redraw(self) -> None:
"""Force a terminal redraw by toggling the size. """Force a terminal redraw by re-sending current size."""
Briefly changes the terminal size then restores it, which forces
applications like tmux to fully redraw all panes.
"""
loop = asyncio.get_running_loop() loop = asyncio.get_running_loop()
# Briefly shrink by 1 column then restore - this forces a full redraw
await loop.run_in_executor(
None, self._set_terminal_size, self._last_width - 1, self._last_height
)
await loop.run_in_executor( await loop.run_in_executor(
None, self._set_terminal_size, self._last_width, self._last_height None, self._set_terminal_size, self._last_width, self._last_height
) )
+1 -4
View File
@@ -377,10 +377,7 @@ class TestTerminalSession:
with patch.object(loop, "run_in_executor", new=AsyncMock()) as run_in_executor: with patch.object(loop, "run_in_executor", new=AsyncMock()) as run_in_executor:
await session.set_terminal_size(80, 24) await session.set_terminal_size(80, 24)
# set_terminal_size toggles size (-1 then restore) to force redraw run_in_executor.assert_awaited_once_with(None, session._set_terminal_size, 80, 24)
assert run_in_executor.await_count == 2
run_in_executor.assert_any_await(None, session._set_terminal_size, 79, 24)
run_in_executor.assert_any_await(None, session._set_terminal_size, 80, 24)
def test__set_terminal_size_calls_ioctl(self): def test__set_terminal_size_calls_ioctl(self):
from textual_webterm.terminal_session import TerminalSession from textual_webterm.terminal_session import TerminalSession