Don't resize terminal on session disconnect

Rename DISCONNECT_RESIZE to DEFAULT_TERMINAL_SIZE
Update tests for removed _resize_on_disconnect and stricter available check

Bump version to 0.2.7
This commit is contained in:
GitHub Copilot
2026-01-24 16:09:53 +00:00
parent b5b144dcd0
commit 2f61bd7747
4 changed files with 11 additions and 28 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
[tool.poetry] [tool.poetry]
name = "textual-webterm" name = "textual-webterm"
version = "0.2.6" version = "0.2.7"
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"
+5 -14
View File
@@ -33,7 +33,7 @@ if TYPE_CHECKING:
log = logging.getLogger("textual-web") log = logging.getLogger("textual-web")
DISCONNECT_RESIZE = (132, 45) DEFAULT_TERMINAL_SIZE = (132, 45)
SCREENSHOT_CACHE_SECONDS = 1.0 SCREENSHOT_CACHE_SECONDS = 1.0
SCREENSHOT_MAX_CACHE_SECONDS = 60.0 SCREENSHOT_MAX_CACHE_SECONDS = 60.0
@@ -431,14 +431,6 @@ class LocalServer:
return session_created return session_created
async def _resize_on_disconnect(self, route_key: str) -> None:
session_process = self.session_manager.get_session_by_route_key(RouteKey(route_key))
if session_process is None or not hasattr(session_process, "set_terminal_size"):
return
width, height = DISCONNECT_RESIZE
with contextlib.suppress(OSError):
await session_process.set_terminal_size(width, height)
async def _handle_websocket(self, request: web.Request) -> web.WebSocketResponse: async def _handle_websocket(self, request: web.Request) -> web.WebSocketResponse:
route_key = request.match_info["route_key"] route_key = request.match_info["route_key"]
ws = web.WebSocketResponse(heartbeat=30.0, max_msg_size=64 * 1024) ws = web.WebSocketResponse(heartbeat=30.0, max_msg_size=64 * 1024)
@@ -478,7 +470,6 @@ class LocalServer:
finally: finally:
log.info("WebSocket connection closed for route %s", route_key) log.info("WebSocket connection closed for route %s", route_key)
self._websocket_connections.pop(route_key, None) self._websocket_connections.pop(route_key, None)
await self._resize_on_disconnect(route_key)
return ws return ws
@@ -535,15 +526,15 @@ class LocalServer:
# Parse requested dimensions (used when creating new sessions) # Parse requested dimensions (used when creating new sessions)
try: try:
req_width = int(request.query.get("width", str(DISCONNECT_RESIZE[0]))) req_width = int(request.query.get("width", str(DEFAULT_TERMINAL_SIZE[0])))
except ValueError: except ValueError:
req_width = DISCONNECT_RESIZE[0] req_width = DEFAULT_TERMINAL_SIZE[0]
req_width = max(10, min(400, req_width)) req_width = max(10, min(400, req_width))
try: try:
req_height = int(request.query.get("height", str(DISCONNECT_RESIZE[1]))) req_height = int(request.query.get("height", str(DEFAULT_TERMINAL_SIZE[1])))
except ValueError: except ValueError:
req_height = DISCONNECT_RESIZE[1] req_height = DEFAULT_TERMINAL_SIZE[1]
req_height = max(5, min(200, req_height)) req_height = max(5, min(200, req_height))
session_process = self.session_manager.get_session_by_route_key(RouteKey(route_key)) session_process = self.session_manager.get_session_by_route_key(RouteKey(route_key))
+5 -2
View File
@@ -67,13 +67,16 @@ class TestDockerStatsCollector:
"""Tests for Docker stats collector.""" """Tests for Docker stats collector."""
def test_available_checks_socket(self, tmp_path): def test_available_checks_socket(self, tmp_path):
"""available property checks socket existence.""" """available property checks socket existence and connectivity."""
socket_path = tmp_path / "docker.sock" socket_path = tmp_path / "docker.sock"
collector = DockerStatsCollector(str(socket_path)) collector = DockerStatsCollector(str(socket_path))
assert collector.available is False assert collector.available is False
# Just touching the file isn't enough - need actual socket connectivity
# Since we can't easily create a real Unix socket in tests,
# verify that a non-socket file returns False
socket_path.touch() socket_path.touch()
assert collector.available is True assert collector.available is False # File exists but can't connect
def test_get_cpu_history_empty(self): def test_get_cpu_history_empty(self):
"""Empty history returns empty list.""" """Empty history returns empty list."""
-11
View File
@@ -167,17 +167,6 @@ class TestLocalServerHelpers:
assert session_created is True assert session_created is True
ws.send_json.assert_awaited_once_with(["error", "No app configured"]) ws.send_json.assert_awaited_once_with(["error", "No app configured"])
@pytest.mark.asyncio
async def test_resize_on_disconnect_calls_set_terminal_size(self, server, monkeypatch):
session = MagicMock()
session.set_terminal_size = AsyncMock()
monkeypatch.setattr(server.session_manager, "get_session_by_route_key", lambda _rk: session)
await server._resize_on_disconnect("rk")
session.set_terminal_size.assert_called_once_with(132, 45)
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_create_terminal_session_sends_error_if_no_apps(self, server): async def test_create_terminal_session_sends_error_if_no_apps(self, server):
ws = MagicMock() ws = MagicMock()