UTMMenuBarExtraScene.swift 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. //
  2. // Copyright © 2022 osy. All rights reserved.
  3. //
  4. // Licensed under the Apache License, Version 2.0 (the "License");
  5. // you may not use this file except in compliance with the License.
  6. // You may obtain a copy of the License at
  7. //
  8. // http://www.apache.org/licenses/LICENSE-2.0
  9. //
  10. // Unless required by applicable law or agreed to in writing, software
  11. // distributed under the License is distributed on an "AS IS" BASIS,
  12. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. // See the License for the specific language governing permissions and
  14. // limitations under the License.
  15. //
  16. import Combine
  17. import SwiftUI
  18. @available(macOS 13, *)
  19. struct UTMMenuBarExtraScene: Scene {
  20. @ObservedObject var data: UTMData
  21. @AppStorage("ShowMenuIcon") private var isMenuIconShown: Bool = false
  22. @AppStorage("HideDockIcon") private var isDockIconHidden: Bool = false
  23. @Environment(\.openWindow) private var openWindow
  24. var body: some Scene {
  25. MenuBarExtra(isInserted: $isMenuIconShown) {
  26. Button("Show UTM") {
  27. openWindow(id: "home")
  28. }.keyboardShortcut("0")
  29. .help("Show the main window.")
  30. Toggle("Hide dock icon on next launch", isOn: $isDockIconHidden)
  31. .help("Requires restarting UTM to take affect.")
  32. Divider()
  33. if data.virtualMachines.isEmpty {
  34. Text("No virtual machines found.")
  35. } else {
  36. ForEach(data.virtualMachines) { vm in
  37. VMMenuItem(vm: vm).environmentObject(data)
  38. }
  39. }
  40. Divider()
  41. Button("Quit") {
  42. NSApp.terminate(self)
  43. }.keyboardShortcut("Q")
  44. .help("Terminate UTM and stop all running VMs.")
  45. } label: {
  46. Image("MenuBarExtra")
  47. }
  48. }
  49. }
  50. private struct VMMenuItem: View {
  51. @ObservedObject var vm: VMData
  52. @EnvironmentObject private var data: UTMData
  53. var body: some View {
  54. Menu(vm.detailsTitleLabel) {
  55. if vm.isStopped {
  56. Button("Start") {
  57. data.run(vm: vm)
  58. }
  59. } else if !vm.isBusy {
  60. Button("Stop") {
  61. data.stop(vm: vm)
  62. }
  63. Button("Suspend") {
  64. let isSnapshot = (vm.wrapped as? UTMQemuVirtualMachine)?.isRunningAsDisposible ?? false
  65. vm.wrapped!.requestVmPause(save: !isSnapshot)
  66. }
  67. Button("Reset") {
  68. vm.wrapped!.requestVmReset()
  69. }
  70. } else {
  71. Text("Busy…")
  72. }
  73. }
  74. }
  75. }