Skip to content

fix(desktop): resync renderer after Windows maximize - #3472

Open
1625567290 wants to merge 4 commits into
apache:mainfrom
1625567290:fix/windows-maximize-renderer-resize
Open

fix(desktop): resync renderer after Windows maximize#3472
1625567290 wants to merge 4 commits into
apache:mainfrom
1625567290:fix/windows-maximize-renderer-resize

Conversation

@1625567290

Copy link
Copy Markdown
Contributor

Summary

  • Re-run Electron's root view layout after a native Windows maximize so the primary renderer fills the new client area.
  • Coalesce maximize and resize notifications, and skip work after restore or teardown.
  • Add focused coverage for platform gating, event coalescing, layout/repaint order, and destroyed-window guards.

Fixes #3416

Verification

  • npm --workspace @maka/desktop run typecheck
  • Windows maximize renderer sync tests: 4/4 passed.
  • Desktop suite on the refreshed base: 1095/1096 passed. The only failure was the existing shell environment timeout test reading its temporary PID file before creation under full-suite concurrency.
  • Re-ran apps/desktop/dist/main/__tests__/shell-env.test.js three times in isolation: 12/12 passed on every run.

Validation limit

The current host is macOS, so the packaged Windows 11 maximize transition still needs Windows CI or a Windows machine for final visual confirmation.

@Astro-Han Astro-Han left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for isolating the workaround behind a small Windows-only scheduler. The lifecycle guards and coalescing look sound, and I did not find a production correctness issue in the implementation. The remaining gap is that the test proves calls against a mock, while the bug and the proposed fix both live in Electron's real Windows layout behavior; I left that boundary inline.

AI-assisted review disclosure: OpenAI Codex performed an independent exact-head review. I verified the implementation, lifecycle guards, test scope, and live PR state, and I made the final review decision.

assert.deepEqual(fixture.calls, []);

fixture.deferred.shift()?.();
assert.deepEqual(fixture.calls, ['layout', 'invalidate']);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] This unit test proves only that the two mocked methods are called; it cannot show that Electron 43 actually expands and repaints the renderer after the native Windows maximize transition, which is the entire user-visible contract of this PR. Could we add a Windows packaged/CI smoke that restores → maximizes → waits one frame, then checks renderer innerWidth/innerHeight (or WebContents size) against the maximized client bounds and restores again? If we keep only one additional test, the real Windows transition is more valuable than another mock branch.

@1625567290
1625567290 force-pushed the fix/windows-maximize-renderer-resize branch from ea8bb87 to bd88d4b Compare August 22, 2026 10:29
@Astro-Han

Copy link
Copy Markdown
Contributor

Heads up on the failing Release Windows checkit isn't caused by anything in this PR.

It fails at scripts/verify-windows-sandbox-e2e.mjs:97 with:

FilesystemWorkerClientError: The target was created while this call waited for the lock; re-read before writing.

That's a regression from #3001, which merged into main earlier today: FilesystemWorkerClient now rejects a write to an existing file when the caller doesn't supply expectedIdentity, and the Windows sandbox verifier calls the client directly rather than through FilesystemExecutor. Tracked in #3484 — nothing for you to fix here.

The CI job on this head is green, and the review of the actual change is clean: the native GetClientRect/IsZoomed probes are a stronger check than the CDP path they replace, and adding rendererViewportMatchesNativeClient catches DPI-scaling mismatches the previous viewport comparison couldn't. We also confirmed the 108 removed lines are the superseded CDP helpers rather than unrelated checks, and that the packaged-Git verification strengthened in #3473 is untouched.

We'll approve once #3484 is resolved and the Windows job can go green on this head.


AI-assisted review.

@1625567290

1625567290 commented Aug 22, 2026 via email

Copy link
Copy Markdown
Contributor Author

@Astro-Han Astro-Han left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks — the diagnosis here is the part that matters, and it is right: maximize is where this reproduces, but the actual gap is that Electron 43's root View layout/repaint does not follow the native maximize. Naming the trigger and the cause separately is what keeps this from becoming a CSS patch.

Reviewed at exact head 83d3d12174620640ea8475cde7673534c8c3142a against base f83b469b557a30036d11572d3c14d69bc0766eaa. No P0–P3.

What we checked, since 495 lines for a window-resize fix invites the question:

  • The production change is 48 lines and sits inside the existing main-window lifecycle. Re-calling setContentView(window.contentView) is not a workaround — NativeWindowViews::SetContentView detaches and re-attaches the content view and then runs FlushPendingRootLayout, which is exactly the layout flush that did not happen. Reusing the same contentView means no new size state is introduced; pending only coalesces events. There is no second size authority here.
  • The remaining ~270 lines are the verifier, and they buy something real: the previous coverage asserted that a mock was called. This reads the native client area through PowerShell GetClientRect/IsZoomed and the renderer viewport through CDP, then walks normal → maximized → normal checking DPR and html/body/#root/.appFrame alignment against the native client. For a bug that only exists at the native/renderer boundary on Windows, that is the only evidence that means anything from a macOS checkout.
  • Guards cover the failure paths: window destroyed, WebContents destroyed, restore, non-Windows. We looked for a stale-pending path that could fire against a destroyed window and did not find one.

Verified locally: helper tests 4/4, node --test scripts/verify-packaged-app.test.mjs scripts/verify-windows-harness.test.mjs 51/51, strict TS compile clean, git diff --check clean.

Not approving yet, and it is not about the code. The red test and package runs on this head are stale merge refs — they were created at 11:23Z against a base that predates the midTurn fix that landed on main at 11:49Z, and the failure in the log is packages/cli/src/pi-tui-runner.ts missing midTurn, which has nothing to do with this PR. A rerun will not help; pull_request runs test the merge commit computed at event time, so only a new push recomputes it. Please rebase, and we will take the result on the new head.


This review was AI-assisted. Findings were verified against the exact head listed above; any mistakes are ours to correct — please push back where we got it wrong.

@Astro-Han

Copy link
Copy Markdown
Contributor

Heads up — this has drifted into conflict with main and can't be merged or reviewed as-is.

Worth knowing before you rebase: #3397 landed on 2026-08-22 and added ASF license headers across ~2685 files, so a rebase will touch more than you'd expect, and any file you add now needs a header (npm run write:asf-headers). A green check from before that date no longer proves anything about the current tree.

I'd like to review this — just ping me once it's rebased and CI is green.

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.

bug(desktop): maximizing from a restored window on Windows leaves the renderer at the old size — unpainted area shows as a white edge

2 participants