diff --git a/.run/sign debug.run.xml b/.run/sign debug.run.xml
deleted file mode 100644
index 19d2cd6..0000000
--- a/.run/sign debug.run.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/.run/tart create.run.xml b/.run/tart create.run.xml
deleted file mode 100644
index 8831dfa..0000000
--- a/.run/tart create.run.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.run/tart run.run.xml b/.run/tart run.run.xml
deleted file mode 100644
index cf7968e..0000000
--- a/.run/tart run.run.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Sources/tart/Commands/Run.swift b/Sources/tart/Commands/Run.swift
index 23da9da..ce8264b 100644
--- a/Sources/tart/Commands/Run.swift
+++ b/Sources/tart/Commands/Run.swift
@@ -1,4 +1,5 @@
import ArgumentParser
+import Cocoa
import Dispatch
import SwiftUI
import Virtualization
@@ -391,6 +392,8 @@ struct Run: AsyncParsableCommand {
nsApp.applicationIconImage = NSImage(data: AppIconData)
struct MainApp: App {
+ @NSApplicationDelegateAdaptor private var appDelegate: MinimalMenuAppDelegate
+
var body: some Scene {
WindowGroup(vm!.name) {
Group {
@@ -415,7 +418,18 @@ struct Run: AsyncParsableCommand {
CommandGroup(replacing: .undoRedo, addition: {})
CommandGroup(replacing: .windowSize, addition: {})
// Replace some standard menu options
- CommandGroup(replacing: .appInfo) { AboutTart() }
+ CommandGroup(replacing: .appInfo) { AboutTart(config: vm!.config) }
+ CommandMenu("Control") {
+ Button("Start") {
+ Task { try await vm!.virtualMachine.start() }
+ }
+ Button("Stop") {
+ Task { try await vm!.virtualMachine.stop() }
+ }
+ Button("Request Stop") {
+ Task { try await vm!.virtualMachine.requestStop() }
+ }
+ }
}
}
}
@@ -424,14 +438,42 @@ struct Run: AsyncParsableCommand {
}
}
+// The only way to fully remove Edit menu item.
+class MinimalMenuAppDelegate: NSObject, NSApplicationDelegate, ObservableObject {
+ let indexOfEditMenu = 2
+
+ func applicationDidFinishLaunching(_ : Notification) {
+ NSApplication.shared.mainMenu?.removeItem(at: indexOfEditMenu)
+ }
+}
+
struct AboutTart: View {
+ var credits: NSAttributedString
+
+ init(config: VMConfig) {
+ let mutableAttrStr = NSMutableAttributedString()
+ let style = NSMutableParagraphStyle()
+ style.alignment = NSTextAlignment.center
+ let attrCenter: [NSAttributedString.Key : Any] = [
+ .paragraphStyle: style,
+ ]
+ mutableAttrStr.append(NSAttributedString(string: "CPU: \(config.cpuCount) cores\n", attributes: attrCenter))
+ mutableAttrStr.append(NSAttributedString(string: "Memory: \(config.memorySize / 1024 / 1024) MB\n", attributes: attrCenter))
+ mutableAttrStr.append(NSAttributedString(string: "Display: \(config.display.description)\n", attributes: attrCenter))
+ mutableAttrStr.append(NSAttributedString(string: "https://github.com/cirruslabs/tart", attributes: [
+ .paragraphStyle: style,
+ .link : "https://github.com/cirruslabs/tart"
+ ]))
+ credits = mutableAttrStr
+ }
+
var body: some View {
Button("About Tart") {
NSApplication.shared.orderFrontStandardAboutPanel(options: [
NSApplication.AboutPanelOptionKey.applicationIcon: NSApplication.shared.applicationIconImage as Any,
NSApplication.AboutPanelOptionKey.applicationName: "Tart",
NSApplication.AboutPanelOptionKey.applicationVersion: CI.version,
- NSApplication.AboutPanelOptionKey.credits: try! NSAttributedString(markdown: "https://github.com/cirruslabs/tart"),
+ NSApplication.AboutPanelOptionKey.credits: credits,
])
}
}
@@ -444,7 +486,8 @@ struct VMView: NSViewRepresentable {
func makeNSView(context: Context) -> NSViewType {
let machineView = VZVirtualMachineView()
- machineView.capturesSystemKeys = true
+ // so keys like take a windows screenshot (cmd+shift+4+space) works on the host and not guest
+ machineView.capturesSystemKeys = false
return machineView
}
diff --git a/scripts/run-signed.sh b/scripts/run-signed.sh
new file mode 100755
index 0000000..4d33e8c
--- /dev/null
+++ b/scripts/run-signed.sh
@@ -0,0 +1,11 @@
+#!/bin/sh
+
+# helper script to build and run a signed tart binary
+# usage: ./scripts/run-signed.sh run ventura-base
+
+set -e
+
+swift build --product tart
+codesign --sign - --entitlements Resources/tart-dev.entitlements --force .build/debug/tart
+
+.build/debug/tart "$@"