Skip to content

PDF Tools: Read mode takes the screen (window.fullscreen) - #522

Merged
ymote merged 2 commits into
mainfrom
feat/pdftools-read-fullscreen
Oct 19, 2026
Merged

ymote merged 2 commits into
mainfrom
feat/pdftools-read-fullscreen

Conversation

@ymote

@ymote ymote commented Oct 13, 2026

Copy link
Copy Markdown
Contributor

PDF Tools' Read mode now takes the whole screen in a desktop shell, through #520's window.fullscreen. Stacked on #520 (base feat/app-fullscreen): merge #520 first, then retarget this to main.

What changes

All in apps/pdftools/bundle/main.splash:

  • Entering Read mode (the pill's full-screen button, a tap) also asks window.fullscreen {on: true}. The window covers the desk with no bar, title bar or dock, and no screen edge brings them back.
  • Leaving Read mode, however it ends (Exit read mode, the corner control, a closed document), asks {on: false}. show() checks after every change (screen_back), so no path is missed.
  • on_app_fullscreen(on): when the shell ends the full screen (Esc, ⌘F, another window taking the focus), Read mode ends too, on the same page at the same zoom. If the full screen arrives after Read mode already ended, it goes straight back.
  • No error noise. The answer is never shown. If the shell refuses, or the host has no window service (card-host answers no service answers "window" on this device), Read mode fills the window as before.
  • The state is mod.pdftools.screen_full, which survives a restyle like the rest of st.

Quick Deck is not touched.

Tests

  • Model tests: cargo test --locked -p octosense-shell --lib pdftools_model passed 22 of 22 on the Linux build host, with this main.splash. They also parse the whole script.
  • tests/ui.py, shell run. The journey now checks that Read mode puts the window in full screen and gives it back when Read mode is left by Exit read mode (light) or the corner control (dark). It then has a new step, read_mode_escape: enter Read mode, check full screen, press Esc, and check that Read mode ended on the same page at the same zoom and the window is back.
    • Its OctoSense check (on macOS a run waits while another OctoSense runs) now matches any octosense* executable, demo copies such as octosense-playback-<sha> included, or the packaged app.
    • Passed on the Linux build host (Ubuntu 26.04, x86_64, a private headless weston and Makepad's Wayland backend), light and dark, at the runtime's 64 ms script budget, with no panic and no budget overrun in the shell's log. It passed on window.fullscreen: an app's own window in presentation full screen, from a tap #520 at 95214d9, then again after the rebase onto 18c1164.

Evidence (Linux, on #520 at 18c1164)

apps/pdftools/tests/evidence/read-fullscreen-20261013/ (README in both languages, four frames, receipt.json):

Step App window Result
Before Read mode [54,76,1292,662] in a 1400×900 window bar, title bar and dock showing
Read mode from the pill, on 2 / 4 [0,0,1400,900] no bar, title bar or dock
Page to 3 / 4, zoom 100% → 125%, Exit read mode (light) / corner control (dark) [54,76,1292,662] on 3 / 4 at 125%, bar and dock back
Read mode again, then Esc [0,0,1400,900] → [54,76,1292,662] Read mode ended on 3 / 4 at 100%

From the shell's log, three presentations:

  1. {on: true} was answered {"applied":true,"fills_screen":true,"fullscreen":true}, and the presentation was ended by the app (App) with {on: false} after Exit read mode.
  2. {on: true}, then Escape. PDF Tools sent nothing after Esc: it heard on_app_fullscreen(false), left Read mode, and didn't bounce.
  3. {on: true}, then the app's {on: false} after the corner control.

Each time the log notes that the host window wasn't asked to enter full screen, because the windows are hidden.

A macOS run of the same journey is pending: the Mac's shared shell lock is held by the maintainer's demo.

Unverified

🤖 Generated with Claude Code

Read mode's tap also asks the shell for window.fullscreen {on: true}
(#520), and Read mode ending in any way asks {on: false}: show() checks
after every change. on_app_fullscreen(false), from Esc, ⌘F or the focus
leaving, ends Read mode too, on the same page at the same zoom, and a
full screen that starts after Read mode already ended goes straight
back. The answer is never shown: refused, or with no window service
(card-host), Read mode fills the window as before.

tests/ui.py's shell run checks the full screen and the window coming
back after Exit read mode and the corner control, and a new step leaves
Read mode by Esc. Its OctoSense check matches any octosense* executable,
demo copies included. Evidence from the Linux build host is in
tests/evidence/read-fullscreen-20261013.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ymote

ymote commented Oct 15, 2026

Copy link
Copy Markdown
Contributor Author

macOS run on this head (9c486f5)

python3 apps/pdftools/tests/ui.py --shell <this head's desktop build> --only shell --budget-ms 10000, in a hidden shell. The Mac was loaded, hence the budget.

All journeys passed, light and dark. That includes:

  • Read mode from the bar taking the window full screen.
  • A page turned and the zoom changed in Read mode.
  • Leaving by Exit read mode (light) and by the corner control (dark), on the same page and zoom.
  • The Esc step.

The maintainer also used Read mode in a visible window on 13 Oct. The real macOS window entered full screen and came back out both times: first ended by the app's exit, then by Esc.

@ymote
ymote changed the base branch from feat/app-fullscreen to main October 19, 2026 17:54
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ymote
ymote marked this pull request as ready for review October 19, 2026 17:55
@ymote

ymote commented Oct 19, 2026

Copy link
Copy Markdown
Contributor Author

Local CI passed on 48fa6d4 (tools/ci-local.sh --only all --linux-host --offload, 14m37s, Darwin arm64; the ubuntu jobs and the macOS jobs' portable steps (their macOS steps ran here) on the Linux build host, Linux x86_64).

GitHub would run for this PR: desktop.yml, phone.yml, apps.yml. Merged on this local pass (macOS runner queue); GitHub CI runs on the merge commit on main.

Job Step Result Time
ci-local / drift The local mapping fits the workflows PASS -
desktop.yml / desktop Prepare the pinned framework sources PASS 1s
desktop.yml / desktop Compile the desktop with the shared runtime PASS 3m36s
desktop.yml / desktop Desktop tools and scripts PASS 18s
desktop.yml / desktop (linux) Prepare the pinned framework sources PASS 1s
desktop.yml / desktop (linux) One copy of every shell source PASS -
desktop.yml / desktop (linux) In-app updater and installer handoff PASS 1m42s
desktop.yml / desktop (linux) One Makepad, App Hub, octos and Rinx in the locked graph PASS 2s
desktop.yml / desktop (linux) The native apps' generated places match native-apps.json PASS 0s
desktop.yml / native-host-api Prepare the pinned framework sources PASS 1s
desktop.yml / native-host-api Build the native acceptance host and pinned Hub CLI PASS 11s
desktop.yml / native-host-api Signed app tool calls a real OS permission API PASS 3s
phone.yml / home Prepare pinned sources and the reviewed runtime patch PASS 1s
phone.yml / home Validate launcher icons and Apple asset catalogs PASS 3s
phone.yml / home Compile Home and its bundled modules PASS 3m16s
phone.yml / home (linux) Prepare pinned sources and the reviewed runtime patch PASS 0s
phone.yml / home (linux) Verify the single runtime graph PASS 2s
phone.yml / home (linux) The native apps' generated places match native-apps.json PASS 0s
phone.yml / home (linux) The pinned octos revision PASS 0s
phone.yml / home (linux) Build octos (unless cached) PASS -
phone.yml / home (linux) Build Home, App Hub admission and runtime policy tests PASS 3m22s
phone.yml / home (linux) Test Home, App Hub admission and runtime policy PASS 43s
phone.yml / home (linux) Two-lane scenario (real kernel, scripted model) PASS 27s
phone.yml / home (linux) Build opt-in AppCard tests PASS 2m49s
phone.yml / home (linux) Test opt-in AppCard PASS 1s
phone.yml / home (linux) Build craft-engine relay and system-chat tests PASS 2m48s
phone.yml / home (linux) Test craft-engine relay and system chat PASS 13s
phone.yml / home (linux) Build linked Terminal tests PASS 2m30s
phone.yml / home (linux) Test linked Terminal PASS 1s
phone.yml / home (linux) Build Wasm and runtime policy tests PASS 1m16s
phone.yml / home (linux) Test Wasm and runtime policy PASS 11s
apps.yml / services (linux) python3 tools/setup.py PASS 0s
apps.yml / services (linux) Shared system app interface PASS 0s
apps.yml / services (linux) Kernel service PASS 19s
apps.yml / services (linux) OctoSense release updater PASS 6s
apps.yml / services (linux) App peers PASS 29s
apps.yml / services (linux) AI providers config PASS 5s
apps.yml / services (linux) Connected provider protocols and Linux host adapter PASS 47s
apps.yml / services (linux) L0 in-card chat (sys.chat, host side) PASS 9s
apps.yml / services (linux) System toolbox (workflow templates) PASS 1m30s
apps.yml / kernel-security (linux) python3 tools/setup.py PASS 0s
apps.yml / kernel-security (linux) The pinned octos revision PASS 0s
apps.yml / kernel-security (linux) Build octos (unless cached) PASS -
apps.yml / kernel-security (linux) Real-kernel tests PASS 39s
apps.yml / apps (linux) python3 tools/setup.py PASS 0s
apps.yml / apps (linux) Host services (Mail, AI providers, News) PASS 2m07s
apps.yml / apps (linux) Connected accounts and Rinx editor PASS 1m30s
apps.yml / apps (linux) Shell AI services (crates/ai-host) PASS 2m56s
apps.yml / apps (linux) AppCard runtime setup safeguards PASS 0s
apps.yml / apps (linux) AppCard clippy (own crates; shared runtime compiles) PASS 27s
apps.yml / apps (linux) AppCard transport and store PASS 7s
apps.yml / apps (linux) One Makepad, App Hub, octos and Rinx in the locked graph PASS 3s
rom.yml / product (linux) python3 -m unittest discover -s tests -v SKIPPED (!) -
rom.yml / product (linux) Check generated Agent Binder client SKIPPED (!) -
rom.yml / product (linux) bash -n scripts/stage-forks.sh scripts/publish-release.sh scripts/apply-to-tree.sh scripts/build-rom.sh PASS -
rom.yml / web-installer (linux) npm ci --ignore-scripts --no-audit --no-fund SKIPPED (!) -
rom.yml / web-installer (linux) npm test SKIPPED (!) -
rom.yml / web-installer (linux) npx playwright install --with-deps chromium SKIPPED (!) -
rom.yml / web-installer (linux) npm run test:browser SKIPPED (!) -
rom.yml / web-installer (linux) python3 -m unittest discover -s tests -p test_installer_manifest.py -v SKIPPED (!) -
rom.yml / web-installer (linux) bash -n scripts/release.sh SKIPPED (!) -
linux-host / sandbox (linux) python3 tools/setup.py PASS 0s
linux-host / sandbox (linux) Process sandbox on Linux (Landlock, seccomp) PASS 1m51s

Skipped (these did NOT pass; (!) marks a skip that blocks tools/ci-local-merge.sh):

  • rom.yml / product (linux): python3 -m unittest discover -s tests -v: javac -version does not work here: install a JDK (17 or newer) and put its bin/ on PATH or set JAVA_HOME
  • rom.yml / product (linux): Check generated Agent Binder client: needs build-tools/35.0.0/aidl, platforms/android-35/framework.aidl in the Android SDK (no Android SDK found): install the SDK packages 'build-tools;35.0.0' and 'platforms;android-35' (sdkmanager) and set ANDROID_HOME
  • rom.yml / web-installer (linux): npm ci --ignore-scripts --no-audit --no-fund: no node, npm, npx on PATH (the workflow uses node 24); put node on PATH
  • rom.yml / web-installer (linux): npm test: no node, npm, npx on PATH (the workflow uses node 24); put node on PATH
  • rom.yml / web-installer (linux): npx playwright install --with-deps chromium: no node, npm, npx on PATH (the workflow uses node 24); put node on PATH
  • rom.yml / web-installer (linux): npm run test:browser: no node, npm, npx on PATH (the workflow uses node 24); put node on PATH
  • rom.yml / web-installer (linux): python3 -m unittest discover -s tests -p test_installer_manifest.py -v: no node, npm, npx on PATH (the workflow uses node 24); put node on PATH
  • rom.yml / web-installer (linux): bash -n scripts/release.sh: no node, npm, npx on PATH (the workflow uses node 24); put node on PATH

Notes:

  • GitHub runs Python 3.12; this run used Python 3.9.6
  • GitHub runs Python 3.12; the Linux host used Python 3.14.4

@ymote
ymote merged commit 8e85234 into main Oct 19, 2026
5 of 6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant