Files
vphone-cli/VPhoneExecutable/VPhoneVirtualization/UI/VPhoneGuestApp.swift
T
LakrandClaude Opus 5.5 8682c98aaa Sync the clipboard on ⌘C, ⌘X and ⌘V, and touch the drawn display
The Edit menu's Copy, Cut and Paste now reach the VM view, which carries
the clipboard through vphoned: paste sends a changed Mac clipboard to the
guest before the guest pastes, and copy and cut bring the guest clipboard
back once the guest has written it. Only small text and images are
synced (VPhoneClipboardTransfer); anything else stays on its own side.
Without a connected agent the items are disabled and the keys reach the
guest unchanged.

capturesSystemKeys makes VZVirtualMachineView swallow every key in a
local event monitor it re-adds on each focus change, so a monitor of ours
always ran after it. VPhoneApplication asks the main menu in
sendEvent(_:), which runs before any local monitor, and drops the key-up
of a key a menu item took.

A full-screen VM letterboxes the guest display, so touches measured
against the view mapped the bars onto the guest screen. They are now
measured against the drawn display (VPhoneDisplayGeometry): points on a
bar clamp to the nearest edge and count as near it for edge swipes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 23:22:00 +09:00

30 lines
1.3 KiB
Swift

import AppKit
import Foundation
import VPhoneCoreKit
/// The kit's entry point: turn parsed boot options into a running guest.
///
/// This exists so `vphone-vm`'s `main.swift` stays a parse and a call. The
/// NSApplication wiring is an implementation detail of running a guest, not
/// something an entry point should be spelling out, and keeping it here means
/// `VPhoneVirtualMachineAppDelegate` does not have to be public — which in turn keeps every
/// `NSApplicationDelegate` method it implements internal.
public enum VPhoneGuestApp {
/// Run the guest. Returns only when the application terminates.
///
/// `@MainActor` because NSApplication is: at the top of `main.swift` that
/// isolation was implicit, and moving the code into a function loses it.
@MainActor
public static func run(_ boot: VPhoneBootCommand) -> Never {
// The first `shared` call picks the class, so this must come first.
let app = VPhoneApplication.shared
let delegate = VPhoneVirtualMachineAppDelegate(command: boot)
app.delegate = delegate
app.run()
// NSApplication.run() does not return through here in practice: the
// terminate path exits the process. Spelling that out keeps the caller
// from having to invent a meaningless return value.
exit(0)
}
}