Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions effex.py
Original file line number Diff line number Diff line change
Expand Up @@ -3100,12 +3100,22 @@ def on_progress(done: float, total: Optional[float], elapsed: float) -> None:
# terminal: geometry, key input
# ---------------------------------------------------------------------------

def terminal_size() -> os.terminal_size:
"""Use the live TTY size so stale COLUMNS/LINES env vars cannot clip frames."""
if sys.stdout.isatty():
try:
return os.get_terminal_size(sys.stdout.fileno())
except OSError:
pass
return shutil.get_terminal_size((84, 24))


def term_cols() -> int:
return max(48, min(shutil.get_terminal_size((84, 24)).columns, 140))
return max(1, terminal_size().columns)


def term_rows() -> int:
return max(12, shutil.get_terminal_size((84, 24)).lines)
return max(1, terminal_size().lines)


def _read_key(fd: int) -> str:
Expand Down
16 changes: 10 additions & 6 deletions tests/layout.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@
SGR = re.compile(r"\033\[[0-9;]*m")
ENTER = b"\r"

# sizes to check: a phone-ish pty, the classic 80x24, and something wide
SIZES = [(60, 20), (80, 24), (120, 40)]
# sizes to check: narrow/wide scaling, the classic 80x24, and something wide
SIZES = [(36, 20), (60, 20), (80, 24), (120, 40), (160, 40)]


def vis(line: str) -> int:
Expand Down Expand Up @@ -71,7 +71,8 @@ def scenario_fit(c: Checker, cols: int, rows: int) -> PtyDriver:
in_dir, out_dir = temp_folders()
make_clip(in_dir / "a_long_video_name_for_testing_columns.mp4", seconds=1)
make_clip(in_dir / "b.mp4", seconds=1)
env = env_for(in_dir, out_dir)
# Stale shell dimensions must not override a resized TTY.
env = {**env_for(in_dir, out_dir), "COLUMNS": "84", "LINES": "24"}

d = PtyDriver([sys.executable, str(EFFEX)], rows=rows, cols=cols,
env_extra=env, timeout=10)
Expand All @@ -92,12 +93,15 @@ def check_frame(c: Checker, label: str, frame: str, cols: int) -> None:
plain_of(frame).count("\u2500" * 10) >= 2)


def check_rows_aligned(c: Checker, label: str, frame: str) -> None:
def check_rows_aligned(c: Checker, label: str, frame: str,
expected_width: int) -> None:
"""list rows are padded to one width, so their columns line up"""
rows = body_of(frame)
widths = {vis(line) for line in rows}
c.check(f"{label}: rows share one width", len(widths) == 1,
f"{len(rows)} rows, widths seen: {sorted(widths)}")
c.check(f"{label}: rows fill the available width", widths == {expected_width},
f"expected {expected_width}, got {sorted(widths)}")


def scenario_sizes(c: Checker) -> None:
Expand All @@ -109,13 +113,13 @@ def scenario_sizes(c: Checker) -> None:

menu = frame_with(stream, "main menu")
check_frame(c, f"{cols}x{rows} main menu", menu, cols)
check_rows_aligned(c, f"{cols}x{rows} main menu", menu)
check_rows_aligned(c, f"{cols}x{rows} main menu", menu, cols - 2)

d.send(b"p")
d.wait_for("pick a video")
picker = frame_with(d.text(), "pick a video")
check_frame(c, f"{cols}x{rows} video list", picker, cols)
check_rows_aligned(c, f"{cols}x{rows} video list", picker)
check_rows_aligned(c, f"{cols}x{rows} video list", picker, cols - 2)
c.check(f"{cols}x{rows}: long file names are cut, not wrapped",
"a_long_video_name_for_testing_columns.mp4" in
SGR.sub("", picker)
Expand Down
Loading