A full screen VM on a Mac with a camera housing loses the strip beside it, which the guest could otherwise use. Two things keep a native full screen window out of that strip: AppKit insets the full screen frame and the window server covers the strip with an opaque menu bar. There is no public way around either, and a borderless window is not an option because macOS would no longer treat the VM as a full screen app. Add an opt-in preference (macOS 27+) and a window subclass that returns the whole screen as the full screen frame and makes the menu bar of its own full screen space transparent while it is not revealed. When the menu bar is revealed it looks and behaves as it always did. It works within the App Sandbox. All of it relies on private AppKit and SkyLight symbols. None of them are used or hooked until the option is enabled and a window enters full screen, so the window is unaffected by changes to them otherwise. They are looked up at runtime by name and checked against the signatures we expect, so no private symbol is linked or compiled into the binary and if any are missing or different the window behaves like any other. The window server reveals the menu bar as soon as the pointer is over the strip, which would make that area of the guest display unusable. It is instead only revealed when the pointer reaches the top edge of the screen: until then the space uses presentation options that hide the menu bar, which also hides the Dock. AppKit applies the options of the space again when it changes spaces, so they are kept up to date. The window server only lets a window cover the strip if it does so from the moment it enters the full screen space, which shapes the rest: - Every frame query in the transition is answered with the whole screen, and later requests to resize the window are ignored, because asking for any frame again, even the current one, moves it out of the strip. Our window controllers do so to fit the guest display, and AppKit does when the space becomes active again. - Once the strip has been left, such as when tiled in Split View, it is not asked for again until full screen is next entered. - The QEMU window is no longer resized to fit a display the guest just changed while the transition to full screen is still running. The flag the controller kept for that is only set once the transition is over, so the window ended up taller than the screen and lost the strip. - AppKit parks the auto hidden toolbar behind the menu bar, or over our content while the menu bar is hidden, so it is hidden along with it. The window stands down when tiled, on a screen without a camera housing, and when the menu bar is set to always be visible in full screen. Terminal windows do not opt in. Resolves #6183 Assisted-by: Claude:claude-fable-5-1 Assisted-by: Claude:claude-opus-5
UTM
It is possible to invent a single machine which can be used to compute any computable sequence.
-- Alan Turing, 1936
UTM is a full featured system emulator and virtual machine host for iOS and macOS. It is based off of QEMU. In short, it allows you to run Windows, Linux, and more on your Mac, iPhone, and iPad. More information at https://getutm.app/ and https://mac.getutm.app/
Features
- Full system emulation (MMU, devices, etc) using QEMU
- 30+ processors supported including x86_64, ARM64, and RISC-V
- VGA graphics mode using SPICE and QXL
- Text terminal mode
- USB devices
- JIT based acceleration using QEMU TCG
- Frontend designed from scratch for macOS 11 and iOS 11+ using the latest and greatest APIs
- Create, manage, run VMs directly from your device
Additional macOS Features
- Hardware accelerated virtualization using Hypervisor.framework and QEMU
- Boot macOS guests with Virtualization.framework on macOS 12+
UTM SE
UTM/QEMU requires dynamic code generation (JIT) for maximum performance. JIT on iOS devices require either a jailbroken device, or one of the various workarounds found for specific versions of iOS (see "Install" for more details).
UTM SE ("slow edition") uses a threaded interpreter which performs better than a traditional interpreter but still slower than JIT. This technique is similar to what iSH does for dynamic execution. As a result, UTM SE does not require jailbreaking or any JIT workarounds and can be sideloaded as a regular app.
To optimize for size and build times, only the following architectures are included in UTM SE: ARM, PPC, RISC-V, and x86 (all with both 32-bit and 64-bit variants).
Install
UTM (SE) for iOS: https://getutm.app/install/
UTM is also available for macOS: https://mac.getutm.app/
Development
macOS Development
iOS Development
Related
- iSH: emulates a usermode Linux terminal interface for running x86 Linux applications on iOS
- a-shell: packages common Unix commands and utilities built natively for iOS and accessible through a terminal interface
License
UTM is distributed under the permissive Apache 2.0 license. However, it uses several (L)GPL components. Most are dynamically linked but the gstreamer plugins are statically linked and parts of the code are taken from qemu. Please be aware of this if you intend on redistributing this application.
Some icons made by Freepik from www.flaticon.com.
Additionally, UTM frontend depends on the following MIT/BSD License components:
Continuous integration hosting is provided by MacStadium


