@@ -2,11 +2,97 @@ import AppKit
22import Service
33import SwiftUI
44import UserNotifications
5+ import XPCShared
56
67class AppDelegate : NSObject , NSApplicationDelegate , NSWindowDelegate {
78 let scheduledCleaner = ScheduledCleaner ( )
9+ private let userDefaultsObserver = UserDefaultsObserver ( )
10+ private var statusBarItem : NSStatusItem !
811
912 func applicationDidFinishLaunching( _: Notification ) {
1013 NSApp . setActivationPolicy ( . accessory)
14+ buildStatusBarMenu ( )
15+ }
16+
17+ @objc private func buildStatusBarMenu( ) {
18+ let statusBar = NSStatusBar . system
19+ statusBarItem = statusBar. statusItem (
20+ withLength: NSStatusItem . squareLength
21+ )
22+ statusBarItem. button? . image = NSImage (
23+ systemSymbolName: " steeringwheel " ,
24+ accessibilityDescription: nil
25+ )
26+
27+ let statusBarMenu = NSMenu ( title: " Status Bar Menu " )
28+ statusBarItem. menu = statusBarMenu
29+
30+ let copilotName = NSMenuItem (
31+ title: " Copilot for Xcode " ,
32+ action: nil ,
33+ keyEquivalent: " "
34+ )
35+
36+ let toggleRealtimeSuggestions = NSMenuItem (
37+ title: " Real-time Suggestions " ,
38+ action: #selector( toggleRealtimeSuggestions) ,
39+ keyEquivalent: " "
40+ )
41+ toggleRealtimeSuggestions. state = UserDefaults . shared
42+ . bool ( forKey: SettingsKey . realtimeSuggestionToggle) ? . on : . off
43+ toggleRealtimeSuggestions. target = self
44+
45+ let quitItem = NSMenuItem (
46+ title: " Quit " ,
47+ action: #selector( quit) ,
48+ keyEquivalent: " "
49+ )
50+ quitItem. target = self
51+
52+ statusBarMenu. addItem ( copilotName)
53+ statusBarMenu. addItem ( . separator( ) )
54+ statusBarMenu. addItem ( toggleRealtimeSuggestions)
55+ statusBarMenu. addItem ( . separator( ) )
56+ statusBarMenu. addItem ( quitItem)
57+
58+ userDefaultsObserver. onChange = { key in
59+ switch key {
60+ case SettingsKey . realtimeSuggestionToggle:
61+ toggleRealtimeSuggestions. state = UserDefaults . shared
62+ . bool ( forKey: SettingsKey . realtimeSuggestionToggle) ? . on : . off
63+ default :
64+ break
65+ }
66+ }
67+ UserDefaults . shared. addObserver (
68+ userDefaultsObserver,
69+ forKeyPath: SettingsKey . realtimeSuggestionToggle,
70+ options: . new,
71+ context: nil
72+ )
73+ }
74+
75+ @objc func quit( ) {
76+ exit ( 0 )
77+ }
78+
79+ @objc func toggleRealtimeSuggestions( ) {
80+ UserDefaults . shared. set (
81+ !UserDefaults. shared. bool ( forKey: SettingsKey . realtimeSuggestionToggle) ,
82+ forKey: SettingsKey . realtimeSuggestionToggle
83+ )
84+ }
85+ }
86+
87+ private class UserDefaultsObserver : NSObject {
88+ var onChange : ( ( String ? ) -> Void ) ?
89+
90+ override func observeValue(
91+ forKeyPath keyPath: String ? ,
92+ of object: Any ? ,
93+ change: [ NSKeyValueChangeKey : Any ] ? ,
94+ context: UnsafeMutableRawPointer ?
95+ ) {
96+ onChange ? ( keyPath)
1197 }
1298}
0 commit comments