forked from intitni/CopilotForXcode
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathActiveApplicationMonitor.swift
More file actions
83 lines (72 loc) · 2.42 KB
/
ActiveApplicationMonitor.swift
File metadata and controls
83 lines (72 loc) · 2.42 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
import AppKit
public final class ActiveApplicationMonitor {
public static let shared = ActiveApplicationMonitor()
public private(set) var latestXcode: NSRunningApplication? = NSWorkspace.shared
.runningApplications
.first(where: \.isXcode)
public private(set) var previousApp: NSRunningApplication?
public private(set) var activeApplication = NSWorkspace.shared.runningApplications
.first(where: \.isActive)
{
didSet {
if activeApplication?.isXcode ?? false {
latestXcode = activeApplication
}
previousApp = oldValue
}
}
private var continuations: [UUID: AsyncStream<NSRunningApplication?>.Continuation] = [:]
private init() {
Task {
let sequence = NSWorkspace.shared.notificationCenter
.notifications(named: NSWorkspace.didActivateApplicationNotification)
for await notification in sequence {
guard let app = notification
.userInfo?[NSWorkspace.applicationUserInfoKey] as? NSRunningApplication
else { continue }
activeApplication = app
notifyContinuations()
}
}
}
deinit {
for continuation in continuations {
continuation.value.finish()
}
}
public var activeXcode: NSRunningApplication? {
if activeApplication?.isXcode ?? false {
return activeApplication
}
return nil
}
public func createStream() -> AsyncStream<NSRunningApplication?> {
.init { continuation in
let id = UUID()
Task { @MainActor in
continuation.onTermination = { _ in
self.removeContinuation(id: id)
}
addContinuation(continuation, id: id)
continuation.yield(activeApplication)
}
}
}
func addContinuation(
_ continuation: AsyncStream<NSRunningApplication?>.Continuation,
id: UUID
) {
continuations[id] = continuation
}
func removeContinuation(id: UUID) {
continuations[id] = nil
}
private func notifyContinuations() {
for continuation in continuations {
continuation.value.yield(activeApplication)
}
}
}
public extension NSRunningApplication {
var isXcode: Bool { bundleIdentifier == "com.apple.dt.Xcode" }
}