diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 8bb161b49..a4ee0ba18 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -23,7 +23,7 @@ on: default: 'false' env: - BUILD_XCODE_PATH: /Applications/Xcode_15.0.app + BUILD_XCODE_PATH: /Applications/Xcode_15.1.app RUNNER_IMAGE: macos-13 jobs: @@ -53,7 +53,7 @@ jobs: strategy: matrix: arch: [arm64] - platform: [ios, ios_simulator, ios-tci, macos] + platform: [ios, ios_simulator, ios-tci, macos, visionos, visionos_simulator, visionos-tci] include: # x86_64 supported only for macOS and simulators - arch: x86_64 @@ -153,7 +153,7 @@ jobs: strategy: matrix: arch: [arm64] - platform: [ios, ios_simulator, ios-tci, macos] + platform: [ios, ios_simulator, ios-tci, macos, visionos, visionos_simulator, visionos-tci] include: # x86_64 supported only for macOS and simulators - arch: x86_64 @@ -235,6 +235,8 @@ jobs: {platform: "ios-tci", mode: "ipa-se", name: "UTM-SE.ipa", path: "UTM SE.ipa"}, {platform: "ios", mode: "ipa-hv", name: "UTM-HV.ipa", path: "UTM.ipa"}, {platform: "ios", mode: "deb", name: "UTM.deb", path: "UTM.deb"}, + {platform: "visionos", mode: "ipa", name: "UTM-visionOS.ipa", path: "UTM.ipa"}, + {platform: "visionos-tci", mode: "ipa-se", name: "UTM-SE-visionOS.ipa", path: "UTM SE.ipa"} ] if: github.event_name == 'release' || github.event.inputs.test_release == 'true' steps: diff --git a/Platform/iOS/Settings.bundle/ja.lproj/Root.strings b/Platform/iOS/Settings.bundle/ja.lproj/Root.strings index 3aeb5b3cd..50cc7eab7 100644 --- a/Platform/iOS/Settings.bundle/ja.lproj/Root.strings +++ b/Platform/iOS/Settings.bundle/ja.lproj/Root.strings @@ -45,6 +45,9 @@ "Drag cursor" = "カーソルをドラッグ"; "Touch mode (always show cursor)" = "タッチモード(常にカーソルを表示)"; "Touch mode (try hiding cursor)" = "タッチモード(カーソルの非表示を試みる)"; +"Visibility" = "可視性"; +"Always show cursor" = "常にカーソルを表示"; +"Try hiding cursor" = "カーソルの非表示を試みる"; "Apple Pencil Input" = "Apple Pencil入力"; "Tablet mode (always show cursor)" = "タブレットモード(常にカーソルを表示)"; "Tablet mode (try hiding cursor)" = "タブレットモード(カーソルの非表示を試みる)"; diff --git a/Platform/ja.lproj/Localizable.strings b/Platform/ja.lproj/Localizable.strings index 9d65d1105..231204d01 100644 --- a/Platform/ja.lproj/Localizable.strings +++ b/Platform/ja.lproj/Localizable.strings @@ -48,8 +48,10 @@ // UTMAppleConfigurationVirtualization.swift "Disabled" = "無効"; -"Mouse" = "マウス"; -"Trackpad" = "トラックパッド"; +"Generic Mouse" = "汎用マウス"; +"Mac Trackpad (macOS 13+)" = "Macトラックパッド(macOS 13以降)"; +"Generic USB" = "汎用USB"; +"Mac Keyboard (macOS 14+)" = "Macキーボード(macOS 14以降)"; // UTMQemuConfiguration.swift "Failed to migrate configuration from a previous UTM version." = "以前のUTMバージョンからの構成の移行に失敗しました。"; @@ -397,8 +399,7 @@ "Enable Balloon Device" = "バルーンデバイスを有効にする"; "Enable Entropy Device" = "エントロピデバイスを有効にする"; "Enable Sound" = "サウンドを有効にする"; -"Enable Keyboard" = "キーボードを有効にする"; -"Enable Pointer" = "ポインタを有効にする"; +"Pointer" = "ポインタ"; "Use Trackpad" = "トラックパッドを使用"; "Allows passing through additional input from trackpads. Only supported on macOS 13+ guests." = "トラックパッドからの追加の入力をパススルーできるようになります。macOS 13以降のゲストでのみ対応しています。"; "Enable Rosetta on Linux (x86_64 Emulation)" = "Linux上でRosettaを有効にする(x86_64エミュレーション)"; @@ -454,6 +455,13 @@ "Select where to export QEMU command:" = "QEMUコマンドの書き出し先を選択してください:"; +/* Platform/visionOS */ + +// VMToolbarOrnamentModifier.swift +"Hide Controls" = "コントロールを非表示"; +"Show Controls" = "コントロールを表示"; + + /* Platform/Shared */ // DestructiveButton.swift @@ -720,6 +728,8 @@ "Stop selected VM" = "選択した仮想マシンを停止します"; "Run selected VM" = "選択した仮想マシンを実行します"; "Edit selected VM" = "選択した仮想マシンを編集します"; +"Preferences" = "環境設定"; +"Show UTM preferences" = "UTM環境設定を表示します"; // VMWizardDrivesView.swift "Storage" = "ストレージ"; @@ -727,7 +737,7 @@ // VMWizardHardwareView.swift "Hardware OpenGL Acceleration" = "ハードウェアOpenGLアクセラレーション"; -"There are known issues in some newer Linux drivers including black screen, broken compositing, and apps failing to render." = "一部の新しいLinuxドライバの中には、画面が黒くなる、表示が乱れる、Appのレンダリングに失敗するといった既知の問題があります。"; +"There are known issues in some newer Linux drivers including black screen, broken compositing, and apps failing to render." = "一部の新しいLinuxドライバの中には、画面が黒くなる、表示が乱れる、アプリのレンダリングに失敗するといった既知の問題があります。"; "Enable hardware OpenGL acceleration" = "ハードウェアOpenGLアクセラレーションを有効にする"; // VMWizardOSLinuxView.swift @@ -883,6 +893,11 @@ /* Scripting */ +// UTMScriptingUSBDeviceImpl.swift +"UTM is not ready to accept commands." = "UTMはコマンドを受け入れる準備ができていません。"; +"The device cannot be found." = "デバイスが見つかりません。"; +"The device is not currently connected." = "デバイスが現在接続されていません。"; + // UTMScriptingVirtualMachineImpl.swift "Operation not available." = "操作は利用できません。"; "Operation not supported by the backend." = "操作はバックエンドが対応していません。"; @@ -898,7 +913,6 @@ "This device is not supported by the target." = "このデバイスはターゲットが対応していません。"; // UTMScriptingCreateCommand.swift -"UTM is not ready to accept commands." = "UTMはコマンドを受け入れる準備ができていません。"; "A valid backend must be specified." = "有効なバックエンドを指定する必要があります。"; "This backend is not supported on your machine." = "このバックエンドはお使いのマシンでは対応していません。"; "A valid configuration must be specified." = "有効な構成を指定する必要があります。"; diff --git a/Platform/visionOS/VMToolbarOrnamentModifier.swift b/Platform/visionOS/VMToolbarOrnamentModifier.swift index b332e9ede..bc058a9de 100644 --- a/Platform/visionOS/VMToolbarOrnamentModifier.swift +++ b/Platform/visionOS/VMToolbarOrnamentModifier.swift @@ -19,10 +19,11 @@ import SwiftUI struct VMToolbarOrnamentModifier: ViewModifier { @Binding var state: VMWindowState @EnvironmentObject private var session: VMSessionState - + @AppStorage("ToolbarIsCollapsed") private var isCollapsed: Bool = false + func body(content: Content) -> some View { - content.toolbar { - ToolbarItem(placement: .bottomOrnament) { + content.ornament(visibility: isCollapsed ? .hidden : .visible, attachmentAnchor: .scene(.top)) { + HStack { Button { if session.vm.state == .started { state.alert = .powerDown @@ -33,28 +34,20 @@ struct VMToolbarOrnamentModifier: ViewModifier { Label(state.isRunning ? "Power Off" : "Quit", systemImage: state.isRunning ? "power" : "xmark") } .disabled(state.isBusy) - } - ToolbarItem(placement: .bottomOrnament) { Button { session.pauseResume() } label: { Label(state.isRunning ? "Pause" : "Play", systemImage: state.isRunning ? "pause" : "play") } .disabled(state.isBusy) - } - ToolbarItem(placement: .bottomOrnament) { Button { state.alert = .restart } label: { Label("Restart", systemImage: "restart") } .disabled(state.isBusy) - } - ToolbarItem(placement: .bottomOrnament) { Divider() - } - if case .serial(_, _) = state.device { - ToolbarItem(placement: .bottomOrnament) { + if case .serial(_, _) = state.device { Button { let template = session.qemuConfig.serials[state.device!.configIndex].terminal?.resizeCommand state.toggleDisplayResize(command: template) @@ -63,31 +56,50 @@ struct VMToolbarOrnamentModifier: ViewModifier { } .disabled(state.isBusy) } - } - #if !WITH_QEMU_TCI - ToolbarItem(placement: .bottomOrnament) { + #if !WITH_QEMU_TCI if session.vm.hasUsbRedirection { VMToolbarUSBMenuView() .disabled(state.isBusy) } - } - #endif - ToolbarItem(placement: .bottomOrnament) { + #endif VMToolbarDriveMenuView(config: session.qemuConfig) .disabled(state.isBusy) - } - ToolbarItem(placement: .bottomOrnament) { VMToolbarDisplayMenuView(state: $state) .disabled(state.isBusy) - } - ToolbarItem(placement: .bottomOrnament) { Button { state.isKeyboardRequested = true } label: { Label("Keyboard", systemImage: "keyboard") } .disabled(state.isBusy) + Divider() + Button { + isCollapsed = true + } label: { + Label("Hide Controls", systemImage: "chevron.right") + } } + .modifier(ToolbarOrnamentViewModifier()) + } + .ornament(visibility: isCollapsed ? .visible : .hidden, attachmentAnchor: .scene(.topTrailing)) { + Button { + isCollapsed = false + } label: { + Label("Show Controls", systemImage: "chevron.left") + } + .modifier(ToolbarOrnamentViewModifier()) } } } + +// the following was suggested by Apple via Feedback to look close to .toolbar() with .bottomOrnament +private struct ToolbarOrnamentViewModifier: ViewModifier { + func body(content: Content) -> some View { + content + .buttonBorderShape(.capsule) + .buttonStyle(.borderless) + .labelStyle(.iconOnly) + .padding(12) + .glassBackgroundEffect() + } +} diff --git a/Services/UTMQemuVirtualMachine.swift b/Services/UTMQemuVirtualMachine.swift index 2826ca278..c162e6a76 100644 --- a/Services/UTMQemuVirtualMachine.swift +++ b/Services/UTMQemuVirtualMachine.swift @@ -748,7 +748,7 @@ extension UTMQemuVirtualMachine { // an image bookmark was saved while QEMU was NOT running let url = try URL(resolvingPersistentBookmarkData: localBookmark) try await changeMedium(drive, to: url, isAccessOnly: !isMounting) - } else if isMounting { + } else if isMounting && (drive.imageType == .cd || drive.imageType == .disk) { // a placeholder image might have been mounted try await eject(drive) } diff --git a/patches/sources b/patches/sources index 5447a6b33..123dd9c08 100644 --- a/patches/sources +++ b/patches/sources @@ -37,7 +37,7 @@ SPICE_CLIENT_SRC="https://www.spice-space.org/download/gtk/spice-gtk-0.40.tar.xz # Source files for GPU acceleration WEBKIT_REPO="https://github.com/utmapp/WebKit.git" -WEBKIT_COMMIT="59f88f623d5547039760848f188ac961b6cc85e2" +WEBKIT_COMMIT="9ce1f852e15f6f322cee0ce727c8fd73657705c9" WEBKIT_SUBDIRS="Source/ThirdParty/ANGLE Configurations Tools/ccache" EPOXY_REPO="https://github.com/utmapp/libepoxy.git" EPOXY_COMMIT="266d2290a437c655f7419e85af06bfbb73a720c4"