-
-
Notifications
You must be signed in to change notification settings - Fork 174
/
Copy pathmain.swift
138 lines (114 loc) · 4.79 KB
/
main.swift
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
import AppKit
func getActiveBrowserTabURLAppleScriptCommand(_ appId: String) -> String? {
switch appId {
case "com.google.Chrome", "com.google.Chrome.beta", "com.google.Chrome.dev", "com.google.Chrome.canary", "com.brave.Browser", "com.brave.Browser.beta", "com.brave.Browser.nightly", "com.microsoft.edgemac", "com.microsoft.edgemac.Beta", "com.microsoft.edgemac.Dev", "com.microsoft.edgemac.Canary", "com.mighty.app", "com.ghostbrowser.gb1", "com.bookry.wavebox", "com.pushplaylabs.sidekick", "com.operasoftware.Opera", "com.operasoftware.OperaNext", "com.operasoftware.OperaDeveloper", "com.vivaldi.Vivaldi", "company.thebrowser.Browser":
return "tell app id \"\(appId)\" to get the URL of active tab of front window"
case "com.apple.Safari", "com.apple.SafariTechnologyPreview":
return "tell app id \"\(appId)\" to get URL of front document"
default:
return nil
}
}
func exitWithoutResult() -> Never {
print("null")
exit(0)
}
func printOutput(_ output: Any) -> Never {
guard let string = try? toJson(output) else {
exitWithoutResult()
}
print(string)
exit(0)
}
func getWindowInformation(window: [String: Any], windowOwnerPID: pid_t) -> [String: Any]? {
// Skip transparent windows, like with Chrome.
if (window[kCGWindowAlpha as String] as! Double) == 0 { // Documented to always exist.
return nil
}
let bounds = CGRect(dictionaryRepresentation: window[kCGWindowBounds as String] as! CFDictionary)! // Documented to always exist.
// Skip tiny windows, like the Chrome link hover statusbar.
let minWinSize: CGFloat = 50
if bounds.width < minWinSize || bounds.height < minWinSize {
return nil
}
// This should not fail as we're only dealing with apps, but we guard it just to be safe.
guard let app = NSRunningApplication(processIdentifier: windowOwnerPID) else {
return nil
}
let appName = window[kCGWindowOwnerName as String] as? String ?? app.bundleIdentifier ?? "<Unknown>"
let windowTitle = disableScreenRecordingPermission ? "" : window[kCGWindowName as String] as? String ?? ""
if app.bundleIdentifier == "com.apple.dock" {
return nil
}
var output: [String: Any] = [
"platform": "macos",
"title": windowTitle,
"id": window[kCGWindowNumber as String] as! Int, // Documented to always exist.
"bounds": [
"x": bounds.origin.x,
"y": bounds.origin.y,
"width": bounds.width,
"height": bounds.height
],
"owner": [
"name": appName,
"processId": windowOwnerPID,
"bundleId": app.bundleIdentifier ?? "", // I don't think this could happen, but we also don't want to crash.
"path": app.bundleURL?.path ?? "" // I don't think this could happen, but we also don't want to crash.
],
"memoryUsage": window[kCGWindowMemoryUsage as String] as? Int ?? 0
]
// Run the AppleScript to get the URL if the active window is a compatible browser and accessibility permissions are enabled.
if
!disableAccessibilityPermission,
let bundleIdentifier = app.bundleIdentifier,
let script = getActiveBrowserTabURLAppleScriptCommand(bundleIdentifier),
let url = runAppleScript(source: script)
{
output["url"] = url
}
return output
}
let disableAccessibilityPermission = CommandLine.arguments.contains("--no-accessibility-permission")
let disableScreenRecordingPermission = CommandLine.arguments.contains("--no-screen-recording-permission")
let enableOpenWindowsList = CommandLine.arguments.contains("--open-windows-list")
// Show accessibility permission prompt if needed. Required to get the URL of the active tab in browsers.
if !disableAccessibilityPermission {
if !AXIsProcessTrustedWithOptions(["AXTrustedCheckOptionPrompt": true] as CFDictionary) {
print("active-win requires the accessibility permission in “System Settings › Privacy & Security › Accessibility”.")
exit(1)
}
}
// Show screen recording permission prompt if needed. Required to get the complete window title.
if
!disableScreenRecordingPermission,
!hasScreenRecordingPermission()
{
print("active-win requires the screen recording permission in “System Settings › Privacy & Security › Screen Recording”.")
exit(1)
}
guard
let frontmostAppPID = NSWorkspace.shared.frontmostApplication?.processIdentifier,
let windows = CGWindowListCopyWindowInfo([.optionOnScreenOnly, .excludeDesktopElements], kCGNullWindowID) as? [[String: Any]]
else {
exitWithoutResult()
}
var openWindows = [[String: Any]]();
for window in windows {
let windowOwnerPID = window[kCGWindowOwnerPID as String] as! pid_t // Documented to always exist.
if !enableOpenWindowsList && windowOwnerPID != frontmostAppPID {
continue
}
guard let windowInformation = getWindowInformation(window: window, windowOwnerPID: windowOwnerPID) else {
continue
}
if !enableOpenWindowsList {
printOutput(windowInformation)
} else {
openWindows.append(windowInformation)
}
}
if !openWindows.isEmpty {
printOutput(openWindows)
}
exitWithoutResult()