Repository navigation
fix(editor): let the editor un-maximize on Wayland and stop its bounds drifting - #1271
Conversation
…s drifting On GNOME Wayland the editor opened maximized could not be restored: its title-bar restore button did nothing. Electron 41's Chromium latches its "restore to maximized" flag when maximize() is asked for while a configure without the maximized state is still on its way, which is always the case for the maximize issued right after construction (electron/electron#53063, fixed in Electron 42+, not backported to 41). Under Wayland the editor now maximizes once the compositor has mapped and focused it, after a short settle; the bench keeps its immediate maximize. editor-window.json also grew on every maximized close (+30x+41 px, origin -15/-10): under Wayland getNormalBounds() read while maximized subtracts the maximized frame insets from the restored, shadow-carrying widget rect. The normal bounds are now taken from getBounds() while the window is in its normal state. What is saved is clamped to the work area, which under Wayland is the whole output, so a tenth of each dimension is left to panels; and a saved position, which a Wayland client can neither set nor read, is no longer handed back to the window there. Windows, macOS and X11 (including --ozone-platform=x11) keep the immediate maximize and getNormalBounds(); the hand-edited zero-size or non-boolean state still falls back to the default window.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info
📝 Walkthrough
Merge Risk: 🔵 Low · up to
|
|
@coderabbitai review |
✅ Action performedReview finished.
|
Summary
On GNOME Wayland the editor opens maximized and cannot be un-maximized. Its
editor-window.jsonalso ends up holding normal bounds the display cannot contain, and they grow with every session. Found in the manual pass of the installedv2.1.0-rc.1.deb: Ubuntu 24.04, GNOME Shell 46, native Wayland, Electron 41.2.1, one 1920×1080 display at 100 %, 32 px top bar, Ubuntu dock at the bottom.Observed
editor-window.jsonbefore the session was{"x":271,"y":24,"width":1410,"height":1087,"maximized":true}. After closing the editor it was{"x":256,"y":-10,"width":1440,"height":1121,"maximized":true}: taller than the 1080 px display, with a negativey.Root cause. These are two separate Electron 41 bugs, both reached through code we control.
win.maximize()right after construction. Electron then shows the window and asks for maximize in the same breath. The compositor's state-less reply to the initial commit gets compared against the optimistically appliedkMaximized, and that latchespreviously_maximized_ = trueinWaylandToplevelWindow. After that,Restore()asks forkMaximizedagain, Chromium deduplicates it, andxdg_toplevel.unset_maximizedis never sent. Upstream fixed this in a Chromium patch that went into Electron 42-x-y, 43-x-y and 44-x-y (#53126, #53125, #53124). It was not backported to 41.getNormalBounds()under Wayland CSD. While the window is maximized,getNormalBounds()takes the restored widget rect, which carries the client-side shadow (insets TLBR 10/16/32/16). It then subtracts the maximized insets (0/1/1/1) instead of the restored ones (native_window_views.cc, unchanged on Electronmain). Each maximized close therefore writes the normal rect back 30×41 px larger and 15/10 px up and to the left. The arithmetic reproduces the observed file exactly: rc.1 clamped{271,24,1410,1087}to{271,0,1410,1080}and wrote back{256,-10,1440,1121}.There is also a contributing factor. Wayland gives clients no work area, so Chromium reports the whole output (
{0,0,1920,1080}), and the existing clamp let a 1080 px-tall normal window through under a 32 px top bar plus the dock.x/ymean nothing to a Wayland client either: it can neither set nor read its position.Fix, Wayland backend only (
usesWaylandBackend: Linux, Wayland session, and no explicit--ozone-platform=x11):focuscomes fromwl_keyboard.enter, which only reaches a mapped surface), plus a 200 ms settle (WAYLAND_MAXIMIZE_SETTLE_MS) that waits out the activated/suspended configures sent with mapping. Until it lands, the saved state still saysmaximized: true, so an early close keeps the choice. A maximize the user makes first cancels ours. The export bench keeps its immediate maximize, because a maximize landing mid-run would resize what it measures.getBounds()read in the normal state, tracked onresize(resized/movednever fire on Linux), instead ofgetNormalBounds().fitEditorRect). Under Wayland, a centred tenth of each dimension is left for panels it cannot see: 1728×972 of a 1080p output.Windows, macOS and X11 keep the immediate maximize, the saved position and
getNormalBounds(). The only change there is that the saved rect is clamped to the work area on write as well as on read. Restore was already clamping to the same display, so the window comes back identically. The checklist rule still holds: a hand-edited zero size or a non-booleanmaximizedfalls back to the default window.Known limits
Related issue
Found during the manual e2e pass of
v2.1.0-rc.1on Ubuntu 24.04 / GNOME 46 Wayland. No issue filed. Intended for cherry-pick ontorelease/v2.1.0.Type of change
Release impact
Desktop impact
Screenshots / video
None: the GUI was not launched for this change (see Testing).
Testing
Unit (platform pinned in every platform-dependent test):
electron/editorWindowState.test.ts:fitEditorRectwith and without Wayland. The drifted rc.1 file becomes{256,54,1440,972}under Wayland and{256,0,1440,1080}elsewhere.resolveEditorCreationdrops the position and defers the maximize under Wayland only, and never for the bench.maximized: "yes"file still opens the default window.electron/wayland.test.ts:usesWaylandBackendis on in a Linux Wayland session, and off under Xwayland (--ozone-platform=x11), in an X11 session, and on win32/darwin.electron/windows.editorWindow.test.ts, new. It drivescreateEditorWindowagainst a fakeBrowserWindowthat reproduces Electron 41's Wayland CSD bounds arithmetic. One test pins the fake to the field measurement ({271,0,1410,1080}→{256,-10,1440,1121}). The tests check that:maximized;getNormalBounds(), and clamps what it saves.All of the save-path tests fail against
origin/main'swindows.ts(the +30×+41 drift shows up as 1300×900 → 1330×941) and pass with the fix.Commands:
npx vitest --run electron/editorWindowState.test.ts electron/wayland.test.ts electron/windows.editorWindow.test.ts electron/windows.test.ts electron/windows.contentProtection.test.ts electron/hudWindowBounds.test.ts: 77 passed.npm run test: 4737 passed. The fiveelectron/mcp/*suites fail locally only because the sharednode_moduleslacks@modelcontextprotocol/sdk. CI'snpm ciinstalls it.npx tsc --noEmitandnpx tsc -p tsconfig.test.json --noEmitare clean outsideelectron/mcp, which fails for the same missing package.npm run lint: exit 0. No diagnostics in the touched files.Not run: the app itself. Another session was driving the desktop, so this change has not been seen on screen yet. The manual verification below is required before cherry-picking.
Manual verification on GNOME Wayland (Ubuntu 24.04, an installed build of this branch or
npm run dev,echo $XDG_SESSION_TYPE→wayland):~/.config/openscreen/editor-window.json(dev build:~/.config/Electron/…or whateveruserDatais), then write the drifted rc.1 value into it:{"x":256,"y":-10,"width":1440,"height":1121,"maximized":true}."maximized":true,width/heightof1440/972, andx/ywithin the output (no negative value). Reopen and close maximized twice more, and confirm the file stays byte-identical across sessions (no growth)."maximized":false. Reopen and expect that size, not maximized.{"x":10,"y":20,"width":0,"height":0,"maximized":"true"}, then relaunch. Expect the default window (1200×800, then maximized) and the restore button working.--ozone-platform=x11(Xwayland) and confirm the editor maximizes at once, with no normal frame first, and still restores.🤖 Generated with Claude Code
Summary by CodeRabbit