Repository navigation
Seed headful window restore bounds and keep the window maximized - #503
Conversation
A --start-maximized headful window never records a normal-state geometry of its own. The first transition out of maximized — a CDP Browser.setWindowBounds demote, the viewport-resize restore step, a WM un-maximize — falls back to chromium's default initial bounds (~1050x1080 at +10+0 on a 1920x1080 root), leaving most of the desktop background visible beside a portrait sliver of browser. Two changes fix that: - chromium-launcher seeds --window-size/--window-position from the live X root when the caller passes --start-maximized, so the window manager and chromium both carry a sane geometry to restore to. Chromium 155 ships a --window-size window in normal state (it overrides the maximized startup state), so: - the api promotes the window back to maximized once per chromium start, driven by devtools upstream discovery (the upstream URL changes on every restart). SetWindowBoundsMaximized is idempotent and leaves fullscreen kiosk windows alone. Verified on a built image: boot and chromium restart end maximized as before; un-maximizing now restores to a root-sized window at +0+0 instead of the 1050px sliver; kiosk and headless paths are untouched.
|
Picked chruffins to review: touched the changed code in |
chruffins
left a comment
There was a problem hiding this comment.
requesting changes on three bugs. all three were reproduced with smoke tests against a fake cdp endpoint on head 6a91d20. the smoke tests are not committed; happy to share the harness.
Bugs
server/cmd/api/api/window_promotion.go:53,66—seenis set before the promotion attempt, so a failed initial dial is never retried for that url. the dial failure path at:85returns straight away. reproduced: the endpoint returned 503 once, then accepted; there was no further upgrade attempt over 3s, and the window stayed in normal state until the next chromium restart. consider markingseenonly after a successful promotion, or retrying the dial within the deadline.server/cmd/api/api/window_promotion.go:93-104— after the connection drops mid-retry, the loop keeps issuing commands on the closed client and never redials, even once a page target exists. reproduced: one upgrade attempt in total; every retry failed with "CDP command outcome is unknown" until the 30s deadline. reconnect after a transport error.server/e2e/e2e_unmaximize_restore_test.go:92-95— the restore assertions only bound width and height from below and left/top from above. a window atleft=-500with full root width passes all four, leaving 500px of desktop exposed on the right. reproduced by evaluating these exact expressions on that geometry; the docker e2e suite was not run. consider asserting thatLeft+WidthandTop+Heightalso reach the root edges.
status: review complete; no tests run on the PR branch; smoke results above are from a scratch copy
promoteWindowMaximized retried only the maximize command: a failed initial dial abandoned the url for good, and after a mid-attempt transport drop the loop kept issuing commands on the closed client. Dial failures and dropped transports now retry within the deadline, redialing on the next pass. New unit tests cover both paths against a fake devtools endpoint; they fail on the previous code. The unmaximize-restore e2e assertions bounded width/height from below and left/top from above, so a large window shifted off-screen (e.g. Left=-500) passed while exposing the desktop. Assert the window also reaches the right and bottom root edges.
|
Addressed all three in 07b8d7d — thanks for the smoke repros, they translated directly into committed regression coverage. Dial failure never retried — Closed client never redials — after a command failure the loop checks Both paths are covered by unit tests against a fake devtools endpoint ( Off-screen restore passes the assertions — added right/bottom-edge coverage: Validation summary: new unit tests + full api package with -race, e2e on the rebuilt image (commit includes both). |
chruffins
left a comment
There was a problem hiding this comment.
re-reviewed 07b8d7d — the three reproduced bugs are fixed, approving.
- dial failures are retried within the deadline, and a dropped transport is redialed (
window_promotion.go). reran the repro scenarios on 07b8d7d: the endpoint now gets a second upgrade attempt and the window is promoted; the dropped-connection case redials and promotes. - the e2e restore assertions now check the far edges (
Left+Width,Top+Height). the new expressions reject theleft=-500geometry and accept a full-root window. - your three new tests pass, including under
-race(3 runs).
not blocking, unchanged in this pass, for a separate decision: promotion still maximizes a window that was launched with explicit --window-size/--window-position, and a fresh api loop still re-maximizes an already-running browser that a client un-maximized.
status: review complete; no tests run on the PR branch beyond the targeted runs above in a scratch copy; no GitHub comment beyond this review
|
Thanks — approval noted, and thanks for re-running the repro scenarios on 07b8d7d. On the two deferred items: both confirmed real against the code, and tracked for a decision on KERNEL-2781 rather than changed here —
Both are edge cases (explicit geometry on headful, api-crash-restart coinciding with a deliberate un-maximize) and fixable later without migration, so this PR stays scoped to the restore-geometry regression. |
Summary
Fixes the "browser opens halfway on the desktop" headful regression: on a 1920x1080 root, any transition of the main window out of maximized state (CDP
Browser.setWindowBounds, the viewport-resize demote, a WM restore) landed on chromium's default initial geometry — a ~1050x1080 window at +10+0 — leaving most of the desktop background visible beside a portrait sliver of browser. Reproduced on the current image; mutter never showed this because its constraint logic clamped the restore geometry.Root cause: a
--start-maximizedwindow never records a normal-state geometry of its own, so the WM has nothing sane to restore to.Changes
--window-size=W,H --window-position=0,0from the live X root (x11.RootSize, new helper) when the merged flags contain--start-maximized. Skipped when the caller passed explicit--window-size/--window-position, or--kiosk(kiosk must stay fullscreen), or the root size can't be read.StartWindowPromotionre-asserts the maximized state once per chromium start, driven by devtools upstream discovery (the upstream URL changes on every restart). This is needed because chromium 155 ships a--window-sizewindow in normal state — the size flag overrides the maximized startup state.SetWindowBoundsMaximizedis idempotent and leaves fullscreen (kiosk) windows alone, so the promotion is safe on every variant. No-op on headless (Xvfb).TestHeadfulUnmaximizeRestoreGeometryboots production-equivalent flags, demotes the window via CDP, and asserts the restored window covers the root. Fails on the current image (restores 1050px wide); passes with this change. The existing resize test's baseline-state assertion now polls briefly since the maximized state settles asynchronously.Validation (built image, docker backend)
--kiosk): fullscreen untouched through resizesgo vet ./...,go test -race(non-e2e): passheadful_start_maximized,headful_kiosk,headful_xorg_no_neko,TestHeadfulUnmaximizeRestoreGeometry): pass against a locally built image with this changeKnown limitation
After a display resize, the seeded restore bounds are stale (last boot's root size), so an un-maximize after a resize restores a window larger than the new root — it still covers the desktop. Re-seeding on resize can be a follow-up if it matters in practice.
Note
Medium Risk
Changes headful Chromium flags and adds background CDP window control on every browser restart; scoped to xorg and reuses existing SetWindowBoundsMaximized behavior (kiosk/fullscreen left alone).
Overview
Fixes headful regression where un-maximizing left a narrow default window and visible desktop by giving Chromium a root-sized normal-state geometry at launch and re-applying maximized state after each browser start.
chromium-launcher (non-headless only) reads the X root via new
x11.RootSizeand, when flags include--start-maximizedwithout explicit--window-size/--window-positionor--kiosk, appends--window-size=W,Hand--window-position=0,0so restore/un-maximize lands on full-screen bounds instead of Chromium’s default sliver.API adds
StartWindowPromotion(wired frommain.go): on xorg headful only, it subscribes to devtools upstream changes and callsSetWindowBoundsMaximizedonce per Chromium restart, with retries for slow targets, refused dials, and dropped CDP connections. Seeded--window-sizestarts the window in normal state (Chromium 155), so promotion restores the expected maximized boot behavior.Tests: unit coverage for bound seeding,
RootSizeparsing, and promotion retry/redial paths; e2eTestHeadfulUnmaximizeRestoreGeometryand display-resize baseline now poll until the window reaches maximized because promotion is asynchronous.Reviewed by Cursor Bugbot for commit 07b8d7d. Bugbot is set up for automated code reviews on this repo. Configure here.