fix(menubar): fix popover layout-recursion crash on macOS 26/27#265
Open
Leewallace017 wants to merge 1 commit into
Open
fix(menubar): fix popover layout-recursion crash on macOS 26/27#265Leewallace017 wants to merge 1 commit into
Leewallace017 wants to merge 1 commit into
Conversation
Clicking the menu bar icon could crash the app with EXC_BAD_ACCESS
("Thread stack size exceeded due to excessive recursion") on macOS 26/27.
The NSHostingController's sizingOptions = .preferredContentSize (added in
hamed-elfayome#200 for positioning) continuously re-pushes the SwiftUI content size into
the popover window, and with NSPopover.animates = true the animated resize
never converges on the newer SwiftUI: windowDidLayout ->
updateAnimatedWindowSize -> setFrame -> layout, overflowing the main-thread
stack. This is the layout-recursion fragility noted in hamed-elfayome#64, escalated into
a hard crash.
- Disable the native popover animation (animates = false) in setupPopover()
and recreatePopover() so the animated resize can no longer loop. The fixed
preferredContentSize/sizingOptions keep hamed-elfayome#200's content sizing/positioning.
- Replace the lost open animation with a custom SwiftUI fade + scale-from-top
entrance in PopoverContentView, applied to the fixed-size view so it can't
re-trigger the window-resize loop.
- Fix a dismiss/re-open race surfaced by the timing change: clicking the
status item could close and immediately re-open the popover. Record the
last close time and have togglePopover ignore a re-open within 0.25s.
Tested on a running build (Xcode 27, macOS 27): repeated open/close with no
crash, animated open, polished sizing, reliable click-to-toggle.
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.
Description
On macOS 26/27, clicking the menu bar icon can crash the app with
EXC_BAD_ACCESS("Thread stack size exceeded due to excessive recursion"). The main thread overflows in an unbounded AppKit/SwiftUI layout loop while the popover is being shown.Root cause: the popover's
NSHostingControllerusessizingOptions = .preferredContentSize(added in #200 to fix positioning), which continuously re-pushes the SwiftUI content size into the popover window. WithNSPopover.animates = true, macOS 26/27's updated SwiftUI never converges the animated resize:This is the layout-recursion fragility flagged in #64, escalated from a warning into a hard crash by the newer SwiftUI. Reproduced on macOS 27.0 (build 26A5353q), Apple Silicon.
Changes
animates = false) insetupPopover()andrecreatePopover(), so the animated window resize can no longer feed the loop. ThepreferredContentSize/sizingOptionssizing from fix(popover): Fix popover positioning offset and menubar overlap #200 is left intact, so the popover's content-hugging size and position are unchanged.PopoverContentView. It runs purely as an opacity/transform on the fixed-size view, so it cannot re-trigger the window-resize loop.togglePopoverignores a re-open within 0.25s of a close.Screenshots / Screen Recordings
Screen recording (open animation + click-to-toggle + no crash) attached below.
Checklist
popover-crash-fix-demo.mp4