-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSingleFileApp.swift
More file actions
150 lines (131 loc) · 5.96 KB
/
Copy pathSingleFileApp.swift
File metadata and controls
150 lines (131 loc) · 5.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
import Cocoa
import AVFoundation
// MARK: - Automation Logic
struct Automation {
static func selectHeadPointerCamera(named cameraName: String) {
let scriptSource = """
tell application "System Settings" to activate
open location "x-apple.systempreferences:com.apple.Accessibility-Settings.extension?PointerControl"
tell application "System Events"
tell application process "System Settings"
repeat until exists (window "Pointer Control")
delay 0.5
end repeat
tell window "Pointer Control"
try
set rightGroup to group 1 of scroll area 1 of group 1 of splitter group 1 of group 1
set foundRow to missing value
repeat with uiGroup in groups of rightGroup
if (exists static text "Head pointer" of uiGroup) then
set foundRow to uiGroup
exit repeat
end if
end repeat
if foundRow is missing value then
display dialog "Could not find 'Head pointer' settings row." buttons {"OK"} default button "OK"
return
end if
click button 1 of foundRow
repeat until exists sheet 1
delay 0.1
end repeat
tell sheet 1
if (exists button "Camera Options…" of group 1 of scroll area 1) then
click button "Camera Options…" of group 1 of scroll area 1
delay 0.5
end if
set foundPopup to missing value
try
set foundPopup to pop up button "Camera" of group 1 of scroll area 1
on error
try
set foundPopup to pop up button 1 of group 1 of scroll area 1
end try
end try
if foundPopup is not missing value then
click foundPopup
delay 0.2
click menu item "\(cameraName)" of menu 1 of foundPopup
else
display dialog "Could not find Camera selection menu."
end if
if exists button "OK" then
click button "OK"
else if exists button "Done" then
click button "Done"
end if
end tell
on error errMsg
display dialog "Automation Error: " & errMsg
end try
end tell
end tell
end tell
"""
var error: NSDictionary?
if let scriptObject = NSAppleScript(source: scriptSource) {
scriptObject.executeAndReturnError(&error)
}
if let err = error {
print("AppleScript Exec Error: \(err)")
}
}
}
// MARK: - App Delegate & Main
class AppDelegate: NSObject, NSApplicationDelegate {
var statusItem: NSStatusItem!
var cameraDiscovery: AVCaptureDevice.DiscoverySession!
func applicationDidFinishLaunching(_ aNotification: Notification) {
statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength)
if let button = statusItem.button {
button.image = NSImage(systemSymbolName: "video.fill", accessibilityDescription: "Camera Switcher")
}
cameraDiscovery = AVCaptureDevice.DiscoverySession(
deviceTypes: [.builtInWideAngleCamera, .externalUnknown],
mediaType: .video,
position: .unspecified
)
constructMenu()
NotificationCenter.default.addObserver(self, selector: #selector(deviceChanged), name: .AVCaptureDeviceWasConnected, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(deviceChanged), name: .AVCaptureDeviceWasDisconnected, object: nil)
}
@objc func deviceChanged() {
DispatchQueue.main.async {
self.constructMenu()
}
}
func constructMenu() {
let menu = NSMenu()
menu.addItem(NSMenuItem(title: "Head Pointer Camera", action: nil, keyEquivalent: ""))
menu.addItem(NSMenuItem.separator())
let devices = cameraDiscovery.devices
if devices.isEmpty {
menu.addItem(NSMenuItem(title: "No Cameras Found", action: nil, keyEquivalent: ""))
} else {
for device in devices {
let item = NSMenuItem(title: device.localizedName, action: #selector(cameraSelected(_:)), keyEquivalent: "")
item.target = self
item.representedObject = device.localizedName
menu.addItem(item)
}
}
menu.addItem(NSMenuItem.separator())
menu.addItem(NSMenuItem(title: "Quit", action: #selector(quitApp), keyEquivalent: "q"))
statusItem.menu = menu
}
@objc func cameraSelected(_ sender: NSMenuItem) {
guard let cameraName = sender.representedObject as? String else { return }
print("Switching to camera: \(cameraName)")
DispatchQueue.global(qos: .userInitiated).async {
Automation.selectHeadPointerCamera(named: cameraName)
}
}
@objc func quitApp() {
NSApplication.shared.terminate(self)
}
}
// Application Entry Point
let app = NSApplication.shared
let delegate = AppDelegate()
app.delegate = delegate
_ = NSApplicationMain(CommandLine.argc, CommandLine.unsafeArgv)