Commit Graph
1903 Commits
Author SHA1 Message Date
osy f33763ebcd Merge pull request #7890 from utmapp/vm/ios-close-confirmation
vm(iOS): confirm before closing the window of a running VM
2026-09-21 09:06:58 -05:00
osy cbbacec96b Merge pull request #7889 from utmapp/display/fullscreen-hot-corners
display: turn off Hot Corners while a VM is in full screen
2026-09-21 09:06:44 -05:00
Tiffany Fung 43720e14b0 Add more translations for zh-Hans & zh-HK (#7887)
* Add more translations for zh-HK

* Add more translations for zh-Hans

* Add more translations for zh-HK

* Add more translations for zh-Hans

* Fix translations for zh-HK
2026-09-21 09:06:28 -05:00
osy beb2ce330f Merge pull request #7886 from utmapp/feature/apple-secure-boot
config: add Secure Boot option for Apple UEFI guests
2026-09-21 09:05:59 -05:00
osy 24fc103404 welcome: offer opening an existing VM instead of the gallery
The welcome placeholder's second tile linked out to the UTM Gallery
website, which is already reachable from the Help menu and from the new
VM wizard. Opening an existing .utm bundle had no tile at all, so the
most common way to get a VM into a fresh install was the least
discoverable. Point the tile at the existing OpenVirtualMachine
notification instead.

Assisted-by: Claude:claude-opus-5
2026-09-21 09:04:53 -05:00
osy d6306ed8c3 vm(iOS): confirm before closing the window of a running VM
On iPad, closing the last window quits the app: the system ends the process
about 100 ms after the scene disconnects, so a running VM was lost without
any warning. macOS already asks through windowShouldClose.

iOS 27 lets a scene ask for confirmation first, so do that for the last
interactive window unless the VM is stopped or paused with its state saved.
Stop replaces the Close button.

There is no Suspend button because the process does not live long enough
after the window closes to save the state; a button that started the save
was tried and the state was never written.

Not available on visionOS, and not needed for UTM Remote where the VM keeps
running on the server.

Assisted-by: Claude:claude-fable-5-1
2026-09-20 03:45:31 -05:00
osy 04b38aec87 display: turn off Hot Corners while a VM is in full screen
A guest in full screen owns the whole display, and its own corners are
commonly used (Start button, Show Desktop, Apple menu). Moving the pointer
there also triggered the Hot Corner configured on the host, e.g. Quick Note
or Mission Control popping up over the guest.

macOS 27 adds NSApplication.PresentationOptions.disableScreenCornerInteractions,
which we now request for the full screen space. The camera housing mode
forces its own options and has to carry the flag over.

On macOS 27.0 the window server keeps the corners disabled for the app after
the full screen space is gone, even though AppKit reports no options, until
the options change again. Reset them when leaving full screen.

Nothing is done for a captured mouse: the pointer is detached from the
cursor and parked in the middle of the screen, so it never reaches a corner.

Assisted-by: Claude:claude-fable-5-1
2026-09-20 03:45:30 -05:00
osy 855bc0d2df config: add Secure Boot option for Apple UEFI guests
macOS 27 lets the host manage Secure Boot state in the EFI variable
store. Add a persisted flag and a toggle in the Boot settings so generic
UEFI guests on the Apple backend can opt in. The state is reconciled when
the configuration is saved, using the default platform key and the
default Microsoft signatures so that mainstream Linux distributions boot
unmodified. The store is only written when its state differs from the
configuration, and a virtual machine with the option off never fails to
save because of it. The option defaults to off because guests without a
Microsoft-signed bootloader would otherwise stop booting.

Assisted-by: Claude:claude-fable-5-1
2026-09-19 23:18:45 -05:00
osy 9d00a54833 Merge pull request #7885 from utmapp/feature/fullscreen-notch
display: fill the area beside the camera housing in full screen
2026-09-19 22:45:35 -05:00
osy 230f400ddc display: fill the area beside the camera housing in full screen
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
2026-09-19 18:27:21 -05:00
osy 3b0da37c46 apple: run without saving changes on macOS 27
"Run without saving changes" has only been available for QEMU, where it
maps to `-snapshot`. Apple Virtualization has no such option, but
DiskImageKit on macOS 27 can stack a copy-on-write layer on top of an
image and Virtualization accepts the stacked image as a storage
attachment.

When started with the disposable option, the Apple backend now creates a
temporary directory in the sandbox and gives every writable drive an
ephemeral ASIF overlay there. The base image is opened read-only and is
never touched. The EFI variable store and the macOS auxiliary storage are
cloned into the same directory so firmware settings are not persisted
either. The directory is deleted when the guest stops or when start
fails, any leftover from a previous start is discarded before the next
start, and directories orphaned by a crash are swept at app launch.
Removable drives attached at start or hot-plugged during the run are
covered as well.

A disposable run boots fresh and leaves any saved suspend state and the
modification date alone, and reports the save/restore path as
unsupported so closing the window offers to kill the VM instead of
suspending it, matching the QEMU behaviour. The stop paths that delete a
saved suspend state skip that while running disposably.

The context menu, the Start intent and the menu bar extra now check the
backend capability instead of assuming QEMU, and the Apple display window
shows the same "Disposable Mode" subtitle as QEMU.

Assisted-by: Claude:claude-fable-5-1
2026-09-19 10:51:06 -05:00
osy fa92ca48ed asif: use DiskImageKit on macOS 27
ASIF drives for Apple Virtualization are created, inspected and resized
through the private DiskImages2 framework, loaded by path and called via
NSInvocation. macOS 27 ships DiskImageKit, a public Swift-only framework
that covers the same operations and is what Virtualization.framework now
consumes directly.

Add UTMAppleDiskImage, a Swift wrapper that uses DiskImageKit on macOS 27
and later and falls back to the existing UTMASIFImage helper on macOS 13
through 26. The legacy path is confined to one private extension so it
can be deleted together with UTMASIFImage once the minimum host is
macOS 27. DiskImageKit is weak linked because the deployment target is
below macOS 27.

Callers switch to the wrapper; the resize path no longer force-unwraps
the helper.

Assisted-by: Claude:claude-fable-5-1
2026-09-19 10:49:50 -05:00
osy b4e22be198 Merge pull request #7872 from changanmoon/l10n
Update translations for zh-Hans & zh-HK
2026-09-19 10:46:42 -05:00
Tiffany Fung 18be937cb1 Add MS-DOS logo 2026-09-19 10:46:23 -05:00
osy 56ebf381f9 Merge pull request #7854 from lprazdnik/fix/browse-button-accessibility
ui(macOS): identify file browse fields as accessibility groups
2026-09-19 08:58:43 -05:00
osy 47eadda150 apple: make the vmnet modes predictable and simpler
Follow-up to the vmnet networking modes:

- Rename "Shared Network (VM to VM)" to "NAT Network" (config value
  "NATNetwork", scripting term "nat network") so the picker does not offer
  two "Shared" modes that differ only by a suffix.
- Request a fixed subnet per mode outside of the ranges vmnet hands out by
  default. Those ranges are also used by NAT attachments and QEMU, so guest
  addresses depended on what else was running whenever the network was
  (re)created. Fall back to a vmnet chosen subnet when ours is taken.
- Show the mode description with DetailedSection. The bare Text row widened
  the form and clipped the labels and controls in the settings window.
- Only require macOS 26 when a network is actually created, so a VM using
  one of these modes can still be edited and saved on older hosts.
- Do not apply locale digit grouping to the vmnet error code.
- Fold the validation flag into the existing one that skipped drives and
  leave the device unattached instead of using a NAT placeholder, remove
  the unused reverse mapping, key the networks by vmnet_mode_t, and isolate
  the manager to the main actor in place of a lock with no concurrent users.

Use .1 as the host-side address within each preferred /24. As reproduced
in PR #7865, vmnet accepts .0 during network creation but the interface
fails later at startup.

Assisted-by: Claude:claude-fable-5-1
Assisted-by: ChatGPT:GPT-6-Astra-Pro
2026-09-18 20:43:49 -04:00
lovon-spec 31b431f8b5 apple: let virtual machines connect to each other
Apple Virtualization's existing Shared Network uses a separate NAT
attachment per VM, so guests cannot use it to reach each other. macOS 26
adds VZVmnetNetworkDeviceAttachment, which lets multiple VMs attach to the
same process-owned vmnet network.

Add two macOS 26+ modes:

- "Shared Network (VM to VM)": guests share a NAT-backed vmnet network and
  can reach each other, the host, and external networks.
- "Host Only": guests share a host-only vmnet network and can reach each
  other and the host without external routing.

UTMAppleVmnetNetworkManager keeps a weak attachment cache per mode while
Virtualization configuration and runtime objects own the attachment and its
native network. The network therefore follows the actual VZ object lifetime
rather than UTM's presentation state, including failure paths where a VZ VM
can remain alive after UTM reports it stopped. Configuration validation uses
a side-effect-free placeholder so saving a VM does not create a live vmnet
network.

Hide both modes before macOS 26 and add matching scripting enumerators and
round-trip parsing.

Resolves #6975.
Related to #7418 and #7380.

Assisted-by: Claude:claude-fable-5-1
Assisted-by: ChatGPT:GPT-6-Pro
Assisted-by: ChatGPT:GPT-5.6-Sol
2026-09-18 13:26:24 +02:00
osy 5534ffab7d Merge pull request #7879 from utmapp/feature/toolbar-power-control
toolbar(macOS): draw VM power controls as one segmented control
2026-09-18 09:33:32 +02:00
osy 73f875c915 toolbar(macOS): draw VM power controls as one segmented control
macOS 26 draws a single Liquid Glass background behind a run of adjacent
toolbar items, so stop, start/pause, and restart read as one undivided
button. A space item only splits that background into separate groups.
The divider Safari's back/forward and Xcode's run/stop show comes from a
segmented control inside one toolbar item, so the nib now defines the
three controls as segments of one.

Clicking the stop segment still stops the VM, and clicking and holding
it still shows the shutdown menu, which now hangs off the segment rather
than an NSMenuToolbarItem. Enabling moves to the individual segments.
Segment tooltips are localizable, so the existing translations move from
the removed items to the segments. An autosaved toolbar item list that
names the removed items falls back to the nib default, so existing
installs pick up the new control.

Segments have no label, so VoiceOver reads their image descriptions.
The stop and restart images get localized descriptions the way the USB
item's image does, and start/pause already had them. German lacked a
"Restart" translation, so the one the removed toolbar item carried moves
to Localizable.strings, where the main menu's Restart item uses it too.
The group's "Power" label reuses the existing Chinese translations.

Assisted-by: Claude:claude-opus-5
2026-09-18 07:10:45 +02:00
osy 800dfc1f14 apple: add USB passthrough on macOS 27
Apple Virtualization VMs could not share host USB devices. macOS 27 adds
public APIs for this: AccessoryAccess.framework reports devices the user
assigned to UTM in the system "Virtual Machine Accessories" menu bar item and
VZUSBPassthroughDevice captures them, so the private API approach from the
abandoned branch is no longer needed.

Devices are reported once per process to UTMAppleUSBManager. A newly assigned
device is connected to the only running VM, or to the VM whose window is in
front when several are running, so the user does not have to select it twice.
The USB menu of the Apple VM window lists assigned devices and can move a
device from another VM after confirmation. A device the user disconnects from
the menu stays assigned to UTM but is not connected again until asked, since
the system reports it again right after it is detached. The VM label is set so
the system menu names the VM.

Connected devices are recorded with their UUID when the VM state is saved and
added to the configuration before the state is restored, so the guest keeps
the device across a suspend. A device that is missing at restore is skipped
and the guest sees it unplugged; the restore itself still succeeds.

Requires the com.apple.developer.accessory-access.usb entitlement.

Assisted-by: Claude:claude-fable-5-1
2026-09-17 22:15:30 +02:00
osy 28a91b6385 toolbar(iOS): keep hide toolbar tip off the toolbar on iOS 26+
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
2026-09-16 23:58:41 +02:00
osy 6fef92f151 toolbar(iOS): size Liquid Glass buttons explicitly for iOS 27
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
2026-09-16 23:58:41 +02:00
Tiffany Fung 0872928121 Fix translations for zh-Hans 2026-09-16 16:24:23 +08:00
Tiffany Fung 10cf208f12 Update translations for zh-Hans 2026-09-16 16:22:41 +08:00
Tiffany Fung e84e59e161 Update translations for zh-HK 2026-09-16 16:21:52 +08:00
osy e0943608a5 display(iOS): register external display as scene accessory on iOS 27
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
2026-09-16 07:56:09 +02:00
osy 8521d24995 list: separate create VM and donate glass buttons
On iOS 26, adjacent toolbar items in the same placement merge into a
single Liquid Glass capsule, so the create VM and donate buttons render
as one control with no visual break between the two unrelated actions.
Insert a fixed ToolbarSpacer to split them into their own capsules.

ToolbarSpacer is unavailable on visionOS, hence the platform guard.

Assisted-by: Claude:claude-opus-5[1m]
2026-09-16 07:02:02 +02:00
osy f3645d5018 project: remove code for versions below the new minimum
Now that the deployment targets are iOS 15 and macOS 12, every guard,
fallback and workaround for an older release is dead code that only
obscures what the supported path is. Remove them:

- Drop the `@available` attributes for iOS 15, macOS 11 and macOS 12, and
  unwrap the matching `#available`/`#unavailable` guards in Swift and the
  `@available`/`API_AVAILABLE`/`NS_AVAILABLE_IOS` ones in Objective-C.
- Delete the legacy-only views and helpers left unreachable by that:
  NumberTextFieldOld, VMConfigNetworkPortForwardLegacyView,
  VMContextMenuModifier.bodyBigSur, the nonbrokenSheet, uniqued,
  customBadge, borderedList and legacySettingsToolbar shims, the
  .unsupported BootloaderSelection case, and the iOS 14 sacrificial
  version Section in the QEMU settings list.
- jb_has_cs_execseg_allow_unsigned() has returned false for every host
  since iOS 14.4, so drop it along with the is_device_A12_or_newer()
  helper that only it used. The entitlement parser no longer needs to
  copy the blob either, since that copy existed only so the psychic paper
  needle could be blanked in place.
- VMDisplayTerminalViewController tracked the keyboard frame by hand for
  iOS 14. `useAutoLayout` is a constant that cannot be overridden, so
  nothing ever registered the notification observers and only the
  keyboardLayoutGuide path is reachable.
- VMConfigQEMUView's additionalArguments is now referenced on iOS only,
  which leaves its macOS branch, and the macOS 11 ForEach crash
  workaround inside it, unreachable.
- Raise the Cydia package floor and the postinst/prerm helpers to match
  the new minimum.

Two of the removed guards dropped an error path rather than just a
branch. The shared directory `featureNotSupported` throw covered
VZVirtioFileSystemDeviceConfiguration and friends being macOS 12+, which
no longer applies to any supported host. The macOS guest
`platformUnsupported` throw when decoding a boot config on Intel only
fired on macOS 11; the Apple Silicon requirement it really guards is
enforced unconditionally in
UTMAppleConfigurationSystem.fillVZConfiguration, which both the start and
the save path go through.

Assisted-by: Claude:claude-opus-5
2026-09-16 04:48:37 +02:00
Leo e198587991 ui(macOS): identify file browse fields as accessibility groups
VoiceOver announces the file selection row as a Browse button even though users must interact with it to reach the actual button. Explicitly contain the child controls and label the group with the existing field title so its announced role matches its behavior.

Assisted-by: Codex:gpt-6
2026-09-05 16:37:31 -07:00
osy 18b718226d Merge pull request #7802 from changanmoon/l10n
Update translations for zh-Hans & zh-HK
2026-09-01 21:50:30 -07:00
osy 37712f82b4 Merge pull request #7845 from utmapp/display-upscaling-default-linear
config: use linear upscaling except on classic guests
2026-09-01 18:57:28 -07:00
osy 8b13f491b3 Merge pull request #7840 from lprazdnik/fix/caps-lock-release
input(macOS): preserve Caps Lock key releases
2026-09-01 18:57:11 -07:00
osy ba1b183e44 Merge pull request #7837 from lprazdnik/feature/command-option-swap
input(macOS): add command and option key swap
2026-09-01 18:56:52 -07:00
osy 99259da016 Merge pull request #7829 from synrest/upstream/graceful-quit
macOS: add graceful power-down quit policy
2026-09-01 18:55:55 -07:00
Leo 8f7a663054 input(macOS): preserve Caps Lock key releases
macOS treats Caps Lock as a locking modifier and never delivers its
physical release, so once "Caps Lock is treated as a key" is enabled a
guest that uses it as a held modifier (e.g. a screen reader's NVDA key)
never sees it let go.

While VM input is captured, remap Caps Lock to F20 on each attached
keyboard through IOHIDEventSystemClient (Apple TN2450) so macOS delivers
a normal key down/up pair, which VMMetalView translates back to the Caps
Lock scan code. The keyboard's previous mapping is put back when capture
ends, and a remap left behind by a crash is removed at the next launch.
F20 is the highest function key macOS delivers and is on no Apple
keyboard, so no physical key is shadowed.

Fixes #7838

Assisted-by: Codex:gpt-5
Assisted-by: Claude:claude-fable-5-1
2026-09-01 14:57:42 -07:00
osy e2e37cf9b2 config: use linear upscaling except on classic guests
The nearest-neighbour default (ba5f7f7f, #3371) was chosen for
low-resolution guests, where linear washes out already-chunky text. It is
the wrong choice everywhere else: a modern guest rarely upscales by an
integer ratio, so nearest duplicates source pixels unevenly and looks
blocky rather than sharp -- the complaint behind #6209 and #6572.

Default to linear and let the wizard select nearest for the guests the
original change was about: Classic Mac OS, Windows 7 and below, and any OS
configured for legacy hardware. Legacy hardware is checked on its own
rather than folded into the Windows case so that choosing a legacy machine
opts in under any OS, and because the summary page can enable it after the
Windows page has already latched isWindows10OrHigher.

Existing VMs are unaffected: upscalingFilter is a required coding key, so
a saved configuration always carries its own value. The UTM 2.x migration
path is likewise unchanged, since an absent displayUpscaler already
defaulted to linear.

Assisted-by: Claude:claude-opus-5
2026-09-01 13:35:08 -07:00
osy 34d48fec66 download: never extract a symlink from a downloaded VM
Bumping ZIPFoundation to 0.9.20 brought in its symlink containment guard,
but that guard is not sufficient here. `URL.isContained(in:)` collapses
repeated separators in a single pass, so a link target ending in
`<package>///../elsewhere` is accepted while the filesystem resolves it to
`<package>/../elsewhere`. A crafted archive could pair such a link with a
later regular file underneath it, whose own path passes the containment
check, and write outside the package again.

Nothing in UTM ever stores a symlink inside a package, so reject them
outright instead of trying to validate the target.

Also remove the destination on failure. Extraction created the .utm
directory up front and a mid-loop error left the partial contents in
place, where the library would list them as a real virtual machine that
survives a relaunch.

Assisted-by: Claude:claude-fable-5-1
2026-09-01 12:30:12 -07:00
osy a22bac70ef download: show the real reason a VM download failed
The three error types in this file declare `errorDescription` but conform
only to `Error`, so the description is never consulted. `downloadUTMZip()`
alerts with `error.localizedDescription`, which for a plain `Error` falls
back to "The operation couldn't be completed. (UTM.UTMDownloadVMTask...
error 1.)" -- the localized strings here have never reached a user.

Conform them to `LocalizedError` instead, matching every other error type
in the codebase. No other type has this defect.

`CreateUTMFailed` is currently unthrown; it is included so the three stay
consistent rather than leaving one behind.

Assisted-by: Claude:claude-fable-5-1
2026-09-01 12:30:12 -07:00
osy ed73d11da0 download: reject ZIP entries escaping the .utm folder
A downloaded VM archive is attacker-controlled, so an entry named
`some.utm/../../elsewhere` must not be able to write outside the package
it claims to belong to. The extraction path was built by substituting the
archive's .utm prefix out of the entry path and appending the remainder,
and `appendingPathComponent()` does not resolve `..` -- the traversal was
only resolved by the filesystem at write time, landing anywhere in the
app container the depth reached.

Derive the relative path by dropping the prefix, and resolve every
destination through a containment check before extracting. Separators are
collapsed in a loop because `fopen()` and `URL.standardized` disagree on
a path such as `/../elsewhere`, and a single collapse pass still lets
`///../elsewhere` through.

Also bump ZIPFoundation to 0.9.20 for its accumulated fixes. This file is
the only call site in the tree and the deprecated failable initializer it
uses is still present, so the bump is source compatible.

Reported-by: Vo Duc Thang (ugvxb)
Assisted-by: Claude:claude-fable-5-1
2026-09-01 12:30:12 -07:00
Leo f851786d6d input(macOS): add command and option key swap
Add a single modifier-key mapping control that preserves the existing Control/Command preference while keeping swap modes mutually exclusive. Map both left and right Command and Option keys for QEMU guests.

Assisted-by: Codex:gpt-5
2026-08-27 19:54:36 -07:00
vectorseven c63afe8c11 macOS: add graceful power-down quit policy
Allow users to request guest shutdown when quitting UTM while preserving Save State as the default. Wait for all selected virtual machines to stop, resume paused non-suspended guests, and cancel termination with a visible error when shutdown fails or times out.

Related to #5912.

Assisted-by: Codex:gpt-5.6-sol
Assisted-by: ChatGPT:GPT-5.6-Sol
2026-08-18 11:59:49 -05:00
Tiffany Fung 0a7a1bfd20 Merge branch 'utmapp:main' into l10n 2026-08-11 07:00:15 +08:00
osy ea24d5e863 config(iOS): use physical RAM limit when limit is raised
Otherwise the checks won't kick in on a jailbroken device.
2026-08-04 23:06:52 -07:00
osy f93a7470b6 project: revert minver bump
We can selectively support DXMT on macOS 13, iOS 16 and so we can revert
the minver bump.
2026-08-04 08:27:04 -07:00
osy 5f13bb356a project: add dxmt to iOS builds 2026-08-04 08:26:43 -07:00
Tiffany Fung d136158633 Update translations for zh-Hans 2026-08-02 09:35:26 +08:00
Tiffany Fung b04f737c80 Update translations for zh-HK 2026-08-02 09:31:21 +08:00
osy c4c6164644 localization: fix typo in Italian 2026-08-01 09:04:53 -07:00
osy ec6d46ecfb Merge pull request #7718 from tan9/fix/usb-toolbar-icon
ui: use cable.connector SF Symbol for USB toolbar item
2026-07-31 22:43:31 -07:00
osy cb1b8be650 Merge pull request #7723 from Benjamin123-tech/main
Update German localization strings for consistency
2026-07-31 22:42:38 -07:00