Browse Source

display(apple): enable drive menu for macOS 15

pull/6825/head
osy 8 months ago
parent
commit
1deed70e06
  1. 125
      Platform/macOS/Display/VMDisplayAppleWindowController.swift

125
Platform/macOS/Display/VMDisplayAppleWindowController.swift

@ -262,6 +262,131 @@ extension VMDisplayAppleWindowController {
}
}
@objc extension VMDisplayAppleWindowController {
@IBAction override func drivesButtonPressed(_ sender: Any) {
let menu = NSMenu()
menu.autoenablesItems = false
let item = NSMenuItem()
item.title = NSLocalizedString("Querying drives status...", comment: "VMDisplayWindowController")
item.isEnabled = false
menu.addItem(item)
updateDrivesMenu(menu, drives: appleConfig.drives)
menu.popUp(positioning: nil, at: NSEvent.mouseLocation, in: nil)
}
@nonobjc func updateDrivesMenu(_ menu: NSMenu, drives: [UTMAppleConfigurationDrive]) {
menu.removeAllItems()
if drives.count == 0 {
let item = NSMenuItem()
item.title = NSLocalizedString("No drives connected.", comment: "VMDisplayWindowController")
item.isEnabled = false
menu.addItem(item)
}
if #available(macOS 15, *), appleConfig.system.boot.operatingSystem == .macOS {
let item = NSMenuItem()
item.title = NSLocalizedString("Install Guest Tools…", comment: "VMDisplayAppleWindowController")
item.isEnabled = true
item.target = self
item.action = #selector(installGuestTools)
menu.addItem(item)
}
for i in drives.indices {
let drive = drives[i]
if !drive.isExternal {
continue // skip non-disks
}
let item = NSMenuItem()
item.title = label(for: drive)
if !drive.isExternal {
item.isEnabled = false
} else if #available(macOS 15, *) {
let submenu = NSMenu()
submenu.autoenablesItems = false
let eject = NSMenuItem(title: NSLocalizedString("Eject", comment: "VMDisplayWindowController"),
action: #selector(ejectDrive),
keyEquivalent: "")
eject.target = self
eject.tag = i
eject.isEnabled = drive.imageURL != nil
submenu.addItem(eject)
let change = NSMenuItem(title: NSLocalizedString("Change", comment: "VMDisplayWindowController"),
action: #selector(changeDriveImage),
keyEquivalent: "")
change.target = self
change.tag = i
change.isEnabled = true
submenu.addItem(change)
item.submenu = submenu
}
menu.addItem(item)
}
menu.update()
}
@available(macOS 15, *)
func ejectDrive(sender: AnyObject) {
guard let menu = sender as? NSMenuItem else {
logger.error("wrong sender for ejectDrive")
return
}
let drive = appleConfig.drives[menu.tag]
Task.detached(priority: .background) { [self] in
do {
try await appleVM.eject(drive)
} catch {
Task { @MainActor in
showErrorAlert(error.localizedDescription)
}
}
}
}
@available(macOS 15, *)
func openDriveImage(forDriveIndex index: Int) {
let drive = appleConfig.drives[index]
let openPanel = NSOpenPanel()
openPanel.title = NSLocalizedString("Select Drive Image", comment: "VMDisplayWindowController")
openPanel.allowedContentTypes = [.data]
openPanel.beginSheetModal(for: window!) { response in
guard response == .OK else {
return
}
guard let url = openPanel.url else {
logger.debug("no file selected")
return
}
Task.detached(priority: .background) { [self] in
do {
try await appleVM.changeMedium(drive, to: url)
} catch {
Task { @MainActor in
showErrorAlert(error.localizedDescription)
}
}
}
}
}
@available(macOS 15, *)
func changeDriveImage(sender: AnyObject) {
guard let menu = sender as? NSMenuItem else {
logger.error("wrong sender for ejectDrive")
return
}
openDriveImage(forDriveIndex: menu.tag)
}
@nonobjc private func label(for drive: UTMAppleConfigurationDrive) -> String {
let imageURL = drive.imageURL
return String.localizedStringWithFormat(NSLocalizedString("USB Mass Storage: %@", comment: "VMDisplayAppleDisplayController"),
imageURL?.lastPathComponent ?? NSLocalizedString("none", comment: "VMDisplayAppleDisplayController"))
}
@available(macOS 15, *)
@MainActor private func installGuestTools(sender: AnyObject) {
}
}
extension VMDisplayAppleWindowController: UTMScreenshotProvider {
var screenshot: UTMVirtualMachineScreenshot? {
if let image = mainView?.image() {

Loading…
Cancel
Save