fix(macos): emit the content rect for WINDOW_FRAME events#133
Open
iAmCorey wants to merge 1 commit into
Open
Conversation
|
@iAmCorey is attempting to deploy a commit to the Vercel Labs Team on Vercel. A member of the Team first needs to authorize it. |
On macOS the WINDOW_FRAME event carried window.frame — the OUTER frame, one titlebar taller than the content area. Everything else in the pipeline speaks content-rect: windows are created with initWithContentRect:, the runtime's shellBoundsForWindow uses the event's size as the shell-view layout viewport, and the window state store round-trips the saved frame back into initWithContentRect:. Consequences of the mismatch: - Shell views (e.g. a UiApp's fill gpu_surface) relayout to the outer frame's height on every window_frame_changed, then snap back to the content height on the next RESIZE event — the two events fight every frame, and whichever lands last wins. When WINDOW_FRAME wins, the canvas is laid out one titlebar taller than the content area and the bottom of the UI (status bars) renders clipped. Dragging the window to another display reliably parks the war on the clipped side; clicking another app and back parks it on the correct side, which made the bug look like a multi-display issue. - restore_state windows grow by one titlebar height per launch (outer frame saved, restored as a content rect). Emit [window contentRectForFrameRect:window.frame] instead, and add the missing windowDidChangeScreen:/windowDidChangeBackingProperties: delegate re-emits so crossing displays refreshes geometry immediately rather than at the next key-window change. Verified on a dual-display setup (built-in Retina + external monitor): before, dragging across displays clipped the bottom 32pt of the canvas; after, layout is stable across display moves, focus changes, and resizes. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2726790 to
03f8436
Compare
| // frame makes shell views a titlebar taller than the content area | ||
| // (clipping the bottom) and makes restored windows grow by one | ||
| // titlebar per launch. | ||
| NSRect frame = [window contentRectForFrameRect:window.frame]; |
There was a problem hiding this comment.
On macOS, emitWindowFrameForWindowId: reports contentRectForFrameRect: (frame minus titlebar) which under-reports the height of NSWindowStyleMaskFullSizeContentView windows (titlebarStyle 1/2), so WINDOW_FRAME disagrees with the RESIZE event's contentView.bounds and reintroduces the shell-layout oscillation/bottom-clipping for hidden-inset windows.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Symptom
On a multi-display setup (built-in Retina + external monitor), dragging a window to the other display and back leaves the bottom of the canvas clipped — a UiApp's bottom
status-bardisappears. Clicking another app and back (key-window change), or manually resizing, heals it. Single-display apps can also hit it intermittently.Root cause
The macOS host's
WINDOW_FRAMEevent carriedwindow.frame— the outer frame, one titlebar (~32pt) taller than the content area. Everything else in the pipeline speaks content-rect:initWithContentRect:shellBoundsForWindowuses the event's size as the shell-view layout viewport (window_frame_changed→relayoutShellViews)initWithContentRect:So every
window_frame_changedrelayouts shell views to the outer-frame height (the fillgpu_surfacegetsframe={{0,-32},{560,592}}inside a 560-tall contentView — bottom 32pt clipped), and everyRESIZEevent snaps them back to the content height. The two events fight continuously; whichever lands last wins. Instrumented log of an idle app:Dragging across displays reliably parks the war on the clipped side; a key-window change parks it on the correct side — which made the bug masquerade as a multi-display issue.
Separately,
restore_statewindows grow by one titlebar height per launch (outer frame saved, restored as a content rect).Fix
emitWindowFrameForWindowId:now emits[window contentRectForFrameRect:window.frame], matching the content-rect semantics of window creation, shell layout, and state restore.windowDidChangeScreen:/windowDidChangeBackingProperties:delegate re-emits (mirroringwindowDidBecomeKey:) so crossing displays refreshes geometry immediately instead of at the next key-window change.Verification
Dual-display MacBook (built-in Retina @2x + external monitor): before, dragging across displays clipped the bottom 32pt of a zig-core UiApp's canvas; after, layout is stable across display moves, focus changes, and resizes, and the per-frame relayout oscillation is gone.
🤖 Generated with Claude Code