Skip to content

Maximize and snaps end above a floating dock; honour a native window's requested size - #487

Merged
ymote merged 1 commit into
mainfrom
fix/maximize-above-dock
Oct 11, 2026
Merged

ymote merged 1 commit into
mainfrom
fix/maximize-above-dock

Conversation

@ymote

@ymote ymote commented Oct 11, 2026 •

Copy link
Copy Markdown
Contributor

Why

#478 made a window that asks for its own size end 32 points above a dock that floats over the desk: OctoSense's and macOS's docks reserve no strip. The shell's own maximize, and snapping, still filled the whole work area, so their bottom edge went behind the dock. Native modules' window size requests were also still ignored. These are the known follow-ups from #478.

What changes

Maximize and snaps end above a floating dock

  • DesktopWindows::rects now fills desktop_layout::room for maximized and snapped windows: the work area, less what the dock covers.
    • That covers maximize from the title-bar button, from a double-click on the title, and from the maximize shortcut (toggle_fullscreen_mode in desktop mode).
    • It also covers every snap zone, including a window snapped in the Windows style before switching to OctoSense.
  • The window's own rect is untouched, so restoring brings it back.
  • Windows' taskbar reserves its strip and Omarchy has no dock: both get 0, so their maximize is unchanged.
  • Single source for the dock's height, wired to The dock hides while OctoSense is full screen, as macOS's Dock does #485 (merged; this branch is rebased onto main adb3f122). The height comes only from App::dock_overlay, the lookup new windows' sizes already use.
    • The shell copies it into DesktopWindows::dock before every draw, in a 4-line hunk next to sync_ai_pane_geometry. Clicks between frames read the same number.
    • While the dock auto-hides because the shell is full screen (desktop::dock_auto_hides), App::dock_overlay returns 0, so maximize and snaps use the whole desk. Nothing in this PR computes the dock separately.
    • This PR does not touch desktop.rs or desk.rs.

Native modules' requested window size

  • App::drain_module_windows now honours WindowRequest::Open { size }, clamped exactly like a script app's manifest window: preferred_size, above a floating dock, through insert_sized.
  • desktop_layout::requested_size counts a missing size, or one with a side that is zero, negative or not finite, as no request. Such a window opens at today's default.
  • A size larger than the desk is clamped to the room above the dock, less the margins. A tiny one gets the shell's 80 × 60 minimum.
  • Phones show no extra windows (ModuleWindows is unsupported there), and the request is ignored on a mobile style anyway.
  • Which native apps request a size today: none. At the pinned revisions:
    • Rinx's two host windows (Moments, Article editor) call ModuleWindows::open(…, None).
    • Calculator, Clock, Notes, Reminders, Weather, Terminal, Sheets, App Hub, OctosCode, Reference and AppCard open no extra windows.
    • So no window changes size until a module passes a size.

Tests (crates/shell/src/desktop_layout.rs)

  • maximize_and_snaps_end_above_a_dock_that_floats_over_the_desk, on the OctoSense style and the hidden shell's desk:
    • maximized: (10, 42, 1380, 769), ending at the dock's top;
    • restoring brings back the rect;
    • Left and BottomRight snaps fill their part of the room above the dock.
  • maximize_where_the_dock_reserves_its_strip_or_is_absent_is_unchanged: on Windows and Omarchy, maximize fills the work area and snaps use it as before.
  • a_native_window_size_request_is_clamped_like_a_hint:
    • no request, 0 × 0, negative or non-finite: the default rect;
    • 4000 × 3000: 1296 × 705;
    • 640 × 480: as asked;
    • 10 × 10: 80 × 60.
  • The existing maximize and snap tests are unchanged and pass (dock 0).

Proof in a hidden desktop shell

The binary was target/debug/octosense, built with cargo build --locked -p octosense --no-default-features --features app-hub,craft-engines at this head, on macOS (Apple silicon).

The run:

  • started from a Terminal.app tab with a fresh OCTOSENSE_HOME, MAKEPAD_HIDE_WINDOWS=1 and MAKEPAD_REMOTE=127.0.0.1:8915;
  • held the shell-run lock. It waited out the PDF Tools follow-ups' journeys, with no other OctoSense running;
  • took /g grabs only, and ended with /quit.

The shell window was 1400 × 897 and the dock's top was at y 809. All rects are the app's area (MpModuleView):

Step App area (points) Bottom
PDF Tools opened from the menu (opens at 1296x703) 54, 108, 1292 × 667 775 (window 777, 32 above the dock)
Maximized with ⌘⌥F 12, 76, 1376 × 731 807 (window 809, at the dock's top)
Restored with ⌘⌥F 54, 108, 1292 × 667 the pre-maximize rect
Maximized with the title bar's maximize button 12, 76, 1376 × 731 807
App Hub, a native module, from the menu 84, 138, 990 × 606 the default window, cascaded; it requests no size
Rebased on #485: maximized with ⌘⌥F, in a window 12, 76, 1376 × 731 807 (window 809, at the dock's top)
Rebased on #485, --test-action host-fullscreen (dock hidden): maximized with ⌘⌥F 12, 76, 1376 × 809 885, the whole desk; PDF Tools also opened 1296 × 781, the dock covers 0 points

The maximized frame shows the status line ("0 bytes of 64 MB used") above the dock.

No native app requests a size, so a request could not be shown live. The unit test covers the clamp, and App Hub shows that no request keeps the default.

What ran

On the Linux build host, at this head (a71388f3, on main with #485), from a fresh clone:

  • python3 tools/setup.py --check --cargo.
  • cargo test --locked -p octosense-shell --features mobile-apps --lib -- desktop_layout desktop::tests apps::tests::a_script_apps_manifest_window_is_the_size_it_asks_for: 27 passed.
  • From phone/: cargo test --locked --features mobile-apps -p octosense-shell, with phone.yml's kernel and MAKEPAD_SPLASH_BUDGET_MS=10000: 1195 passed, 0 failed.
  • From desktop/: cargo check --locked -p octosense.

All passed.

Before the rebase, at 03347e4a, these also passed: cargo check --locked -p octosense-home --features mobile-apps, cargo check --locked -p octosense --features mobile-apps, and both check-shell-graph.sh runs. The suite then passed with 1181 tests.

On the Mac: python3 tools/setup.py --check --cargo after the rebase, the debug builds, and the hidden-shell runs above.

What did not run

Docs: desktop/docs/code-walkthrough.md and its Chinese twin describe maximize, snapping and native window sizes.

🤖 Generated with Claude Code

@ymote
ymote force-pushed the fix/maximize-above-dock branch from 03347e4 to a71388f Compare October 11, 2026 14:33
…s size

Maximizing a window (its title-bar button, a double-click on its title, the
maximize shortcut) or snapping it filled the whole work area, so under
OctoSense's and macOS's docks, which float over the desk and reserve no
strip, its bottom edge went behind the dock. `DesktopWindows::rects` now
fills `desktop_layout::room`, the work area less what the dock covers,
for maximized and snapped windows. The dock's height is
`DesktopWindows::dock`, which the shell sets before every draw from
`App::dock_overlay`, the one lookup new windows' sizes already use (so
#485's full-screen auto-hide flows through it unchanged), and clicks
between frames read the same number. The window's own rect is untouched,
so restoring brings it back. Windows (whose taskbar reserves its strip)
and the styles without a dock get 0: unchanged.

A native module's extra window (`WindowRequest::Open { size }`) now opens
at the size the module asks for, clamped as a script app's manifest
`window` is (`preferred_size`, above a floating dock), instead of the
default. `desktop_layout::requested_size` treats a missing size, a zero,
negative or non-finite one as no request, so such a window opens at the
default size; a phone shows no extra windows. No native app OctoSense
ships names a size today: Rinx's Moments and Article editor windows pass
none, and no other native app opens extra windows. So no window changes
size until one does.

Tests: maximize and snaps end at the dock's top on a floating-dock desk and
restoring brings back the rect; on Windows and Omarchy maximize fills the
work area as before; a native request larger than the desk is clamped, one
the desk holds is honoured, a tiny one takes the minimum, and no request,
or a zero or non-finite one, keeps today's default.

The code walkthrough (English and Chinese) describes both.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ymote
ymote force-pushed the fix/maximize-above-dock branch from a71388f to 091ecbd Compare October 11, 2026 14:52
@ymote
ymote marked this pull request as ready for review October 11, 2026 15:07
@ymote

ymote commented Oct 11, 2026

Copy link
Copy Markdown
Contributor Author

Local CI passed on 091ecbd (tools/ci-local.sh --only all --linux-host --offload, 14m19s, 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 0s
desktop.yml / desktop Compile the desktop with the shared runtime PASS 3m09s
desktop.yml / desktop Desktop tools and scripts PASS 15s
desktop.yml / desktop (linux) Prepare the pinned framework sources PASS 0s
desktop.yml / desktop (linux) One copy of every shell source PASS -
desktop.yml / desktop (linux) In-app updater and installer handoff PASS 1m39s
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 0s
desktop.yml / native-host-api Build the native acceptance host and pinned Hub CLI PASS 21s
desktop.yml / native-host-api Signed app tool calls a real OS permission API PASS 2s
phone.yml / home Prepare pinned sources and the reviewed runtime patch PASS 0s
phone.yml / home Validate launcher icons and Apple asset catalogs PASS 3s
phone.yml / home Compile Home and its bundled modules PASS 2m55s
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 3m16s
phone.yml / home (linux) Test Home, App Hub admission and runtime policy PASS 41s
phone.yml / home (linux) Two-lane scenario (real kernel, scripted model) PASS 27s
phone.yml / home (linux) Build opt-in AppCard tests PASS 2m45s
phone.yml / home (linux) Test opt-in AppCard PASS 2s
phone.yml / home (linux) Build craft-engine relay and system-chat tests PASS 2m49s
phone.yml / home (linux) Test craft-engine relay and system chat PASS 5s
phone.yml / home (linux) Build linked Terminal tests PASS 2m28s
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 12s
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 30s
apps.yml / services (linux) AI providers config PASS 6s
apps.yml / services (linux) Connected provider protocols and Linux host adapter PASS 46s
apps.yml / services (linux) L0 in-card chat (sys.chat, host side) PASS 10s
apps.yml / services (linux) System toolbox (workflow templates) PASS 1m32s
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 41s
apps.yml / apps (linux) python3 tools/setup.py PASS 0s
apps.yml / apps (linux) Host services (Mail, AI providers, News) PASS 2m06s
apps.yml / apps (linux) Connected accounts and Rinx editor PASS 1m32s
apps.yml / apps (linux) Shell AI services (crates/ai-host) PASS 2m58s
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 1m46s

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 3a56305 into main Oct 11, 2026
2 of 6 checks passed
@ymote
ymote deleted the fix/maximize-above-dock branch October 11, 2026 15:07
RoooyHe pushed a commit to woshuoduijiushidui/OctoSense that referenced this pull request Oct 13, 2026
On a floating desk (the OctoSense and macOS styles, and every other
floating style through SUPER+F), a window can now be full screen as on
macOS: it covers the whole screen, edge to edge, and the top bar, its own
title bar and the dock hide. Resting the pointer on the top edge slides
the bar and the window's title bar down over it together (the title bar's
green button leaves full screen); the bottom edge brings the dock up. Each
goes back shortly after the pointer leaves it, and stays out while a menu
it opened is showing (the launcher for the dock, a bar menu for the top).

- The green button makes a window full screen in the mac-family styles;
  Option-click, SUPER+ALT+F and a title-bar double-click still maximize
  (above the dock, as OctoSense-org#487 made it). SUPER+F toggles full screen on a
  floating desk (it maximized before). An app's SetFullscreen request
  follows the window's flag there.
- DesktopWindow.fullscreen, independent of maximized; WmLayout::rects_of
  gives it the outer desk rect (past the gaps), and is_fullscreen answers
  for both desks. A full-screen window neither moves nor resizes.
- The desk draws it as content alone (no frame, title bar, corners, shadow
  or glass); its title bar is drawn over the content, solid and without
  resize edges, while the top is out. The desk refreshes the outer rect
  from itself each draw, so a bar that just went is never left as a gap.
- The root body now overlays the bar on the scene: the scene keeps a top
  margin equal to the docked bar (App::place_bar, every draw), so nothing
  moves in a window; in full screen the margin is 0 and the bar, shown
  only while the top is out, slides down from above the edge. The pointer
  over the floating bar is the bar's alone (floating_bar_pointer).
- edge_reveal.rs: the edge timing (rest 0.15 s, leave 0.45 s, slide
  0.22 s) shared by the dock (now on it) and the top (App::top_edge,
  WmState.top_reveal / top_bar). The dock also hides beside a full-screen
  window (desktop::front_fullscreen), not only when OctoSense itself is
  full screen.
- desktop/README (en/zh), KEYBINDINGS: the behaviour and its test actions.

Tested: cargo test --locked -p octosense-shell --lib (1053 pass, with
empty OCTOSENSE_HOME and RINX_DATA_DIR, MAKEPAD_HIDE_WINDOWS=1; new tests in
desktop_layout, layout, desktop and edge_reveal). A hidden shell with the
Calculator, driven over the remote control: green button -> full screen at
[0,0,1400,899] with no bar, dock, title or gap; top edge -> bar and title
bar out over the app; bottom edge -> dock up; the revealed green button ->
back to the window [54,76,990,603], unchanged from main; SUPER+F in and out;
Option-click -> maximized above the dock. The iOS phone style renders as
before. The README's --test-action command was run. Unverified: a real
display, and the Windows, Linux and phone shells beyond compiling.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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