Fix terminal resize issue and race condition. Bump version to 0.3.27

This commit is contained in:
GitHub Copilot
2026-01-28 00:21:39 +00:00
parent a1da841c45
commit 79fde1db2d
5 changed files with 14 additions and 11 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
[tool.poetry] [tool.poetry]
name = "textual-webterm" name = "textual-webterm"
version = "0.3.26" version = "0.3.27"
description = "Serve terminal sessions over the web" description = "Serve terminal sessions over the web"
authors = ["Will McGugan <will@textualize.io>"] authors = ["Will McGugan <will@textualize.io>"]
license = "MIT" license = "MIT"
+1 -1
View File
@@ -851,7 +851,7 @@ class LocalServer:
<style> <style>
html, body {{ width: 100%; height: 100%; }} html, body {{ width: 100%; height: 100%; }}
body {{ background: #0c181f; margin: 0; padding: 0; overflow: hidden; }} body {{ background: #0c181f; margin: 0; padding: 0; overflow: hidden; }}
.textual-terminal {{ width: 100%; height: 100%; }} .textual-terminal {{ width: 100%; height: 100%; display: block; overflow: hidden; }}
</style> </style>
</head> </head>
<body> <body>
File diff suppressed because one or more lines are too long
+4 -3
View File
@@ -146,8 +146,8 @@ class WebTerminal {
fit(): void { fit(): void {
try { try {
this.fitAddon.fit(); this.fitAddon.fit();
} catch { } catch (e) {
// Ignore fit errors during initialization console.warn("Fit failed:", e);
} }
} }
@@ -188,7 +188,8 @@ class WebTerminal {
const dims = (() => { const dims = (() => {
try { try {
return this.fitAddon.proposeDimensions(); return this.fitAddon.proposeDimensions();
} catch { } catch (e) {
console.warn("proposeDimensions failed:", e);
return undefined; return undefined;
} }
})(); })();
+7 -5
View File
@@ -114,8 +114,9 @@ class TerminalSession(Session):
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) # Hold lock during PTY read to ensure consistency with concurrent set_terminal_size
async with self._screen_lock: async with self._screen_lock:
width, height = await loop.run_in_executor(None, self._get_terminal_size)
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",
self._screen.columns, self._screen.lines, width, height) self._screen.columns, self._screen.lines, width, height)
@@ -125,12 +126,13 @@ class TerminalSession(Session):
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.""" """Set terminal size."""
self._last_width = width
self._last_height = height
loop = asyncio.get_running_loop() loop = asyncio.get_running_loop()
await loop.run_in_executor(None, self._set_terminal_size, width, height) # Hold lock during PTY write to ensure consistency with concurrent _sync_pyte_to_pty
# Resize pyte screen to match
async with self._screen_lock: async with self._screen_lock:
self._last_width = width
self._last_height = height
await loop.run_in_executor(None, self._set_terminal_size, width, height)
# Resize pyte screen to match
self._screen.resize(height, width) self._screen.resize(height, width)
async def force_redraw(self) -> None: async def force_redraw(self) -> None: