Skip to content

iOS: fix VM toolbar and external display when built with the iOS 27 SDK - #7873

Merged
osy merged 3 commits into
mainfrom
fix/ios27
Sep 17, 2026
Merged

osy merged 3 commits into
mainfrom
fix/ios27

Conversation

@osy

@osy osy commented Sep 16, 2026

Copy link
Copy Markdown
Contributor

Rebuilding UTM with Xcode 27 and the iOS 27 SDK broke two parts of the VM window on iOS.

VM toolbar. On iOS 27, .buttonStyle(.glass) with a circle border shape sizes each button from its label, so the buttons ended up uneven and packed together. On iOS 26.1 the glass adapts to the black VM display behind it and turns almost black, leaving only a faint outline. The toolbar now uses a custom style that draws each icon in the same fixed frame as the pre-iOS 26 style, with interactive glass tinted neutral gray and white icons. It reads the same over dark and light guest content on both versions. The pre-iOS 26 style is unchanged.

External display. Apps built with the iOS 27 SDK are no longer offered external display scenes from the Info.plist scene manifest, so the external display stayed black on iOS 27. On iOS 27 the external display content is now registered as a SwiftUI scene accessory. iOS 26 and earlier keep using the Info.plist configuration and the existing scene delegate.

Testing: Tested by a human on the iOS 27, iOS 26.1, iOS 17 and visionOS 27 simulators. The toolbar was confirmed broken before the change and working after it. The external display was confirmed working on iOS 27 and still working on iOS 26. iOS 17 and visionOS 27 were checked as controls and are unchanged.
The author acknowledges that this change has been tested and/or reviewed by a human in accordance with UTM's AI contribution guidelines.

🤖 Generated with Claude Code

osy added 3 commits September 16, 2026 07:56
Apps built with the iOS 27 SDK are no longer offered
UIWindowSceneSessionRoleExternalDisplayNonInteractive scenes from the
Info.plist scene manifest, so on iOS 27 the external display stayed black
while the VM ran on the device. Offer UTMSingleWindowView through the
SwiftUI scene accessory API instead; iOS 26 and earlier keep using the
Info.plist configuration and UTMExternalSceneDelegate.

The delegate now checks for the NonInteractive role explicitly, which is
what sessions report since iOS 16, instead of the deprecated constant.

Verified on the iPhone 18 Pro simulator (iOS 27.0) with the TVOut screen
powered on via simctl: the placeholder window appears on connect and the
VM display renders once selected; iPad (A16) on iOS 26.1 is unchanged.

Assisted-by: Claude:claude-fable-5-1
Building with the iOS 27 SDK broke the VM toolbar on both iOS 26.1 and
iOS 27. On iOS 27 `.buttonStyle(.glass)` with a circle border shape sizes
each button from its label, so narrow glyphs got smaller circles than the
menus and the implicit gap iOS 26 added between buttons disappeared. On
iOS 26.1 the glass adapts to the backdrop and turns almost black over the
VM display, leaving only a faint outline of each button.

Replace the system glass button style with a custom style that draws the
icon in the same fixed frame as the pre-iOS 26 style and applies
interactive glass in a circle. A neutral gray tint with white icons keeps
the buttons readable over both dark and light guest content on either
runtime. Stack spacing no longer depends on the OS version, and the
pre-iOS 26 path is unchanged.

Assisted-by: Claude:claude-fable-5-1
From iOS 26 the arrow edge passed to popoverTip is only a preference.
When the VM toolbar spans most of the screen width, the system attaches
the "Tap to hide/show toolbar" tip beside the chevron instead of below
it, covering the other toolbar buttons until the tip is dismissed. This
happened on iPhone on iOS 26.1 and on iPhone and iPad on iOS 27.

On iOS 26 and later, restrict the tip's arrow to the edge facing the
toolbar, using the top edge when the toolbar is docked at the top and
the bottom edge when it is docked at the bottom, so the tip always opens
toward the middle of the screen. iOS 17 through 25 keep the existing
behavior.

Assisted-by: Claude:claude-opus-5
@osy
osy merged commit fe86a17 into main Sep 17, 2026
54 checks passed
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.

1 participant