diff --git a/CHANGELOG.md b/CHANGELOG.md index 75833c1..fc056df 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,23 @@ allowed to change behaviour, not just add to it. ## [Unreleased] +## [0.2.8] — 2026-09-07 + +### Fixed + +- **The window MeshTerm opened for itself was too small, and it showed.** The startup + wordmark is 71 columns wide; below that the splash quietly swaps to the narrow one drawn + for the PicoCalc — so a desktop session came up wearing the handheld's mark, with every + menu description truncated onto the pager underneath it. + + MeshTerm was opening a *tab* in whatever Windows Terminal window happened to be around, + inheriting its size (64 columns on the machine this was found on). It now asks for a + window of its own, sized from the platform's own minimum plus a margin. Windows Terminal + clamps that to what the display can show, so a small screen degrades exactly as before. + +- The tab it opens is titled **MeshTerm**, not the executable's full path — which on a + downloaded build was a line of Downloads folder. + ## [0.2.7] — 2026-09-07 ### Changed diff --git a/README.md b/README.md index afa48fc..00c9eae 100644 --- a/README.md +++ b/README.md @@ -68,14 +68,14 @@ if anything goes wrong at startup the window closes before you can read why. **Windows** — open Windows Terminal or PowerShell, `cd` to your downloads, then: ```powershell -.\meshterm-0.2.7-windows-x64.exe +.\meshterm-0.2.8-windows-x64.exe ``` **macOS and Linux** — open Terminal, `cd` to your downloads, then: ```bash -chmod +x meshterm-0.2.7-* -./meshterm-0.2.7-* +chmod +x meshterm-0.2.8-* +./meshterm-0.2.8-* ``` ### A word about terminals, on Windows @@ -113,7 +113,7 @@ becomes just `meshterm` from anywhere. > project. > > - **macOS**: *"cannot be opened because the developer cannot be verified"*. Clear it with -> `xattr -d com.apple.quarantine meshterm-0.2.7-*` and run it again. +> `xattr -d com.apple.quarantine meshterm-0.2.8-*` and run it again. > - **Windows**: *"Windows protected your PC"*. Click **More info → Run anyway**. > > Every release ships a `SHA256SUMS` file if you'd rather check the download first. @@ -123,10 +123,10 @@ becomes just `meshterm` from anywhere. > MeshTerm uses that same folder. Set `MESHTERM_HOME` to try one in isolation: > > ```bash -> MESHTERM_HOME=~/meshterm-test ./meshterm-0.2.7-* # macOS, Linux +> MESHTERM_HOME=~/meshterm-test ./meshterm-0.2.8-* # macOS, Linux > ``` > ```powershell -> $env:MESHTERM_HOME = "$HOME\meshterm-test"; .\meshterm-0.2.7-windows-x64.exe +> $env:MESHTERM_HOME = "$HOME\meshterm-test"; .\meshterm-0.2.8-windows-x64.exe > ``` > > Same variable if you run two radios and want them kept apart. diff --git a/meshterm/__init__.py b/meshterm/__init__.py index 14d0179..bc24961 100644 --- a/meshterm/__init__.py +++ b/meshterm/__init__.py @@ -5,7 +5,7 @@ Supports USB, Bluetooth and TCP companion connection. For Windows, macOS and Lin from datetime import datetime -__version__ = "0.2.7" +__version__ = "0.2.8" __author__ = "Jean-Pierre Martineau" #: The year MeshTerm was first published; the copyright span starts here. diff --git a/meshterm/core/winterminal.py b/meshterm/core/winterminal.py index 786b8a8..29ede89 100644 --- a/meshterm/core/winterminal.py +++ b/meshterm/core/winterminal.py @@ -119,10 +119,48 @@ def reopen() -> bool: # arrive intact). `-d` keeps the working directory, which relative paths given # on the command line depend on. subprocess.Popen( # noqa: S603 - the argv is ours, not the reader's - [terminal, "-d", os.getcwd(), "--", *own_command()], + [ + terminal, + "-w", + "new", + "--size", + _wanted_size(), + # Otherwise the tab is titled with the executable's full path, which on a + # downloaded build is a line of Downloads folder. The icon is not ours to + # set: Windows Terminal takes that from a profile, and a bare command line + # is not one, so it gets the generic console glyph. + "--title", + "MeshTerm", + "-d", + os.getcwd(), + "--", + *own_command(), + ], env=child_environment(), close_fds=True, ) return True except OSError: return False + + +def _wanted_size() -> str: + """The window to ask Windows Terminal for, as ``cols,rows``. + + Asked for, because a window MeshTerm opens should be one MeshTerm fits in. Without + ``-w new`` the session lands as a *tab* in whatever window happens to be open and + inherits its size; without ``--size`` a new window takes the reader's global launch + size, which is a setting about their shell and not about this app. Either way the app + can arrive in a window too small for it, and the failure is quiet and cosmetic: the + startup wordmark is 71 columns, so at 70 it silently swaps to the narrow one drawn for + the PicoCalc, and a short window truncates every description onto the pager. + + The numbers come from the platform's own stated minimum plus a margin, so they follow + it rather than repeating it. Windows Terminal clamps to what the display can show, so + this is a request and not a demand — on a small screen the app degrades exactly as it + would have anyway. + """ + from ..platforms import get_platform + + platform = get_platform() + return f"{platform.readable_cols + 8},{platform.readable_rows + 6}" diff --git a/tests/test_winterminal.py b/tests/test_winterminal.py index bdda937..77f2fe6 100644 --- a/tests/test_winterminal.py +++ b/tests/test_winterminal.py @@ -131,3 +131,46 @@ def test_the_loader_path_the_bootloader_replaced_is_put_back( assert environment["LD_LIBRARY_PATH"] == "/opt/mine/lib" assert "LD_LIBRARY_PATH_ORIG" not in environment assert "DYLD_LIBRARY_PATH" not in environment + + +def test_the_window_asked_for_fits_the_startup_wordmark() -> None: + """The size request exists because a too-small window fails quietly, not loudly. + + The startup wordmark is 71 columns; below that the splash silently swaps to the narrow + one drawn for the PicoCalc, which is how this was found — a desktop session showing the + handheld's mark. The request has to clear that, not merely the platform's minimum. + """ + from meshterm.platforms import REGULAR, set_platform + from meshterm.ui.logo import load_logo, logo_width + + set_platform(REGULAR) + cols, rows = (int(part) for part in winterminal._wanted_size().split(",")) + + assert logo_width(load_logo(cols)) == 71, "the window asked for would get the narrow mark" + assert cols >= REGULAR.readable_cols + assert rows >= REGULAR.readable_rows + + +def test_the_session_gets_its_own_window_at_that_size(monkeypatch: pytest.MonkeyPatch) -> None: + """Both halves matter, and each was a separate way to arrive somewhere too small. + + Without ``-w new`` the session lands as a tab in whatever window is already open and + inherits its size — measured at 64 columns on a real machine, which is why the wrong + mark appeared. Without ``--size`` a new window takes the reader's global launch size, + a setting about their shell rather than about this app. + """ + started: list[list[str]] = [] + monkeypatch.setattr(sys, "platform", "win32") + monkeypatch.delenv(winterminal.REOPENED_ENV, raising=False) + monkeypatch.setattr(winterminal.shutil, "which", lambda _: r"C:\wt.exe") + monkeypatch.setattr( + winterminal.subprocess, "Popen", lambda argv, **_: started.append(argv) or None + ) + + assert winterminal.reopen() is True + argv = started[0] + assert argv[:3] == [r"C:\wt.exe", "-w", "new"] + assert "--size" in argv + assert argv[argv.index("--size") + 1] == winterminal._wanted_size() + # `--` must still separate wt's options from MeshTerm's, or `--mock` becomes wt's. + assert "--" in argv and argv.index("--") > argv.index("--size")