Add source

This commit is contained in:
2026-04-11 03:42:31 +09:00
parent b321703dd9
commit 5822d9b3a1
9 changed files with 413 additions and 0 deletions

165
src/AppDelegate.swift Normal file
View File

@@ -0,0 +1,165 @@
import Cocoa
final class AppDelegate: NSObject, NSApplicationDelegate, NSMenuDelegate {
private var statusItem: NSStatusItem!
private let menu = NSMenu()
private struct Physical {
let name: String
let pixelWidth: Int
let pixelHeight: Int
let refreshRate: Int
}
private var lastPhysical: Physical?
// lifecycle
func applicationDidFinishLaunching(_ notification: Notification) {
statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength)
if let button = statusItem.button {
if let img = NSImage(systemSymbolName: "rectangle.on.rectangle",
accessibilityDescription: "VirtualDisplay") {
img.isTemplate = true
button.image = img
} else {
button.title = "VD"
}
}
menu.delegate = self
menu.autoenablesItems = false
statusItem.menu = menu
ProcessInfo.processInfo.disableAutomaticTermination("VirtualDisplay running")
}
func applicationWillTerminate(_ notification: Notification) {
DisplayManager.shared.disable()
}
// NSMenuDelegate
func menuNeedsUpdate(_ menu: NSMenu) {
guard menu === self.menu else { return }
rebuild()
}
private func rebuild() {
menu.removeAllItems()
guard let phys = physicalDisplay() else {
addDisabled("No display detected")
menu.addItem(.separator())
addQuit()
return
}
addDisabled("\(phys.name) (\(phys.pixelWidth)×\(phys.pixelHeight) @ \(phys.refreshRate)Hz)")
menu.addItem(.separator())
let activeScale = DisplayManager.shared.currentScale
for s in availableScales(physicalPixelWidth: phys.pixelWidth,
physicalPixelHeight: phys.pixelHeight) {
let item = NSMenuItem(title: "\(s)%",
action: #selector(chooseScale(_:)),
keyEquivalent: "")
item.target = self
item.tag = s
item.state = (activeScale == s) ? .on : .off
menu.addItem(item)
}
if activeScale != nil {
menu.addItem(.separator())
addAction("Open Display Settings…", #selector(openDisplaySettings(_:)))
menu.addItem(.separator())
addAction("Disable", #selector(disable(_:)))
}
menu.addItem(.separator())
addQuit()
}
// Menu helpers
private func addDisabled(_ title: String) {
let item = NSMenuItem(title: title, action: nil, keyEquivalent: "")
item.isEnabled = false
menu.addItem(item)
}
private func addAction(_ title: String, _ action: Selector) {
let item = NSMenuItem(title: title, action: action, keyEquivalent: "")
item.target = self
menu.addItem(item)
}
private func addQuit() {
menu.addItem(NSMenuItem(title: "Quit",
action: #selector(NSApplication.terminate(_:)),
keyEquivalent: "q"))
}
// Physical display detection
private func physicalDisplay() -> Physical? {
if let live = liveLookup() { lastPhysical = live }
return lastPhysical
}
private func liveLookup() -> Physical? {
let ourID = DisplayManager.shared.virtualDisplayID
var count: UInt32 = 0
guard CGGetActiveDisplayList(0, nil, &count) == .success, count > 0 else {
return nil
}
var ids = [CGDirectDisplayID](repeating: 0, count: Int(count))
guard CGGetActiveDisplayList(count, &ids, &count) == .success,
let id = ids.first(where: { $0 != ourID }),
let mode = CGDisplayCopyDisplayMode(id) else {
return nil
}
let key = NSDeviceDescriptionKey("NSScreenNumber")
let name = NSScreen.screens.first {
($0.deviceDescription[key] as? NSNumber)?.uint32Value == id
}?.localizedName ?? lastPhysical?.name ?? "Display"
let hz = mode.refreshRate > 0 ? Int(mode.refreshRate.rounded()) : 60
return Physical(
name: name,
pixelWidth: mode.pixelWidth,
pixelHeight: mode.pixelHeight,
refreshRate: hz
)
}
// Actions
@objc private func chooseScale(_ sender: NSMenuItem) {
guard let phys = physicalDisplay() else { return }
let cfg = vdConfig(physicalPixelWidth: phys.pixelWidth,
physicalPixelHeight: phys.pixelHeight,
refreshRate: phys.refreshRate,
scalePercent: sender.tag)
DisplayManager.shared.setScale(sender.tag, config: cfg)
}
@objc private func openDisplaySettings(_ sender: NSMenuItem) {
let urls = [
"x-apple.systempreferences:com.apple.Displays-Settings.extension",
"x-apple.systempreferences:com.apple.preference.displays",
]
for str in urls {
if let url = URL(string: str), NSWorkspace.shared.open(url) {
return
}
}
}
@objc private func disable(_ sender: NSMenuItem) {
DisplayManager.shared.disable()
}
}