osy 70e5e95ec6 ios: add a keyboard or touchpad deck when iPhone Duo is folded like a laptop
With the device partially folded on a table, the guest display takes the
half above the fold and the half below becomes an input deck holding one
of two things the user can swap: the on-screen keyboard with UTM's
accessory row, or a new touchpad drawn like the keyboard. The trigger is
the fold itself, reported by the iOS 27.1 SDK as an active horizontal
division region; Apple keeps the hinge angle for effects and the
reserved regions for layout. The deck is remembered per window so
folding again brings the same one back. Only the guest display gets the
touchpad; a terminal window keeps the keyboard in the deck.

The display controller now constrains the Metal view above the deck,
the fold and the accessory row, and requests the guest resolution for
that area instead of the whole view, which is also what the dynamic
resolution needs when the device opens or closes. Setting the deck from
a SwiftUI update defers the resize to the next turn of the run loop, and
a resize before the guest display exists no longer divides by its zero
size. The hosted display takes whatever size SwiftUI proposes: SwiftUI
measures the window against the part above the keyboard and centres a
window that reports more, so a display sized from its own constraints
lifted the whole window off the top of the screen once the reserved
space below the guest display exceeded the keyboard's height. The
toolbar keeps above the deck with a padding inside its own reader for
the same reason, and leaves the keyboard to the system as before.

The touchpad feeds the same relative pointer path as a connected mouse:
one finger moves the pointer with the drag speed setting applied, a tap
clicks, a two finger tap right-clicks, two fingers scroll with inertia
and a finger held down drags. Clicks come with a rigid haptic tap and a
lighter one on release of a drag, so a press feels like a physical
trackpad; nothing for motion or scrolling. A key on the accessory row
swaps to the touchpad, a key on the touchpad swaps back and the
toolbar's keyboard button steps between the two while folded.

The layout is done by hand from the division's frame rather than with
ArrangementView so the hosted display keeps its identity across the
fold and is not torn down and recreated. A fold becoming active does
not change the window's size, so the region is read again whenever the
hinge moves, and the deck passes the count of those readings down to
the other readers in the window. Without the 27.1 SDK the deck code is
compiled out and Xcode 27.0 still builds the project.

While the deck is active the accessory row leaves the keyboard and sits
between the guest display and the fold, so that the guest display and
the toolbar can lay out around it. The swap dismisses and re-shows the
keyboard, since reloading the input views while the keyboard moves
between the panels crashes inside UIKit. The keyboard itself is asked
for once the pose has settled, with one retry. A keyboard the system
places off the screen while it moves between the panels is not counted
as shown, since reacting to it asks for the keyboard again and the two
keep bouncing. The display controller learns whether the keyboard is
shown from the window instead of watching the notifications itself.

Touches on the deck reach the display controller through the responder
chain, so its touch handling only takes touches on the guest display.
Folding locks the zoom to fit and shows the keyboard, and restores the
window's own choices when the device opens again; neither forced value
is persisted, and a window restored while folded keeps them forced.

Assisted-by: Claude:claude-fable-5-1
Assisted-by: Claude:claude-opus-5-5
2026-09-24 20:52:49 -05:00
2026-09-19 10:46:23 -05:00
2023-09-12 08:52:50 +08:00
2026-07-30 22:11:21 -07:00
2026-09-24 00:35:16 -05:00
2026-07-30 22:11:21 -07:00
2022-06-23 12:45:27 +02:00

UTM

Build

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/

UTM running on an iPhone
UTM running on a MacBook

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

  • 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

MacStadium logo

S
Description
Virtual machines for iOS and macOS
Readme Apache-2.0
55 MiB
Languages
Swift 85%
Objective-C 10.8%
Shell 2.9%
C 0.8%
Python 0.5%