diff --git a/tests/test_terminal.py b/tests/test_terminal.py index ef46df3..c37ce78 100644 --- a/tests/test_terminal.py +++ b/tests/test_terminal.py @@ -62,6 +62,27 @@ def capture_terminal_response( assert get_cell_size() == (10, 20) +def test_get_cell_size_env_variable_fallback() -> None: + if hasattr(get_cell_size, "_result"): + delattr(get_cell_size, "_result") + + @contextmanager + def capture_terminal_response( + start_marker: str, end_marker: str, timeout: float | None = None + ) -> Iterator[SimpleNamespace]: + raise TimeoutError() + + env = {"TEXTUAL_CELL_WIDTH": "12", "TEXTUAL_CELL_HEIGHT": "24"} + with patch("sys.__stdout__"): + with patch("textual_image._terminal.get_tiocgwinsz", side_effect=OSError()): + with patch("textual_image._terminal.capture_terminal_response", capture_terminal_response): + with patch.dict("os.environ", env, clear=True): + result = get_cell_size() + + assert result.width == 12 + assert result.height == 24 + + def test_get_cell_size_stdout_not_a_tty() -> None: if hasattr(get_cell_size, "_result"): delattr(get_cell_size, "_result") diff --git a/textual_image/_terminal.py b/textual_image/_terminal.py index 21ef15d..81c846c 100644 --- a/textual_image/_terminal.py +++ b/textual_image/_terminal.py @@ -1,6 +1,7 @@ """Functionality to interact with the terminal.""" import logging +import os import sys from contextlib import contextmanager from types import SimpleNamespace @@ -70,6 +71,16 @@ def get_cell_size() -> CellSize: except (TerminalError, TimeoutError) as e: logger.warning("Failed to get cell size via escape sequence, assuming VT340 sizes", exc_info=e) + if height == 0 or width == 0: + # Try environment variables (set by textual-serve for web terminals) + match os.environ: + case { + "TEXTUAL_CELL_WIDTH": str(width_str), + "TEXTUAL_CELL_HEIGHT": str(height_str), + } if width_str.isdigit() and height_str.isdigit(): + width = int(width_str) + height = int(height_str) + if height == 0 or width == 0: # Still didn't work, use VT340 sizes as default width = 10