@@ -11,194 +11,10 @@ import XcodeInspector
1111
1212@MainActor
1313public final class SuggestionWidgetController : NSObject {
14- // you should make these window `.transient` so they never show up in the mission control.
15-
16- private lazy var fullscreenDetector = {
17- let it = CanBecomeKeyWindow (
18- contentRect: . zero,
19- styleMask: . borderless,
20- backing: . buffered,
21- defer: false
22- )
23- it. isReleasedWhenClosed = false
24- it. isOpaque = false
25- it. backgroundColor = . clear
26- it. collectionBehavior = [ . canJoinAllSpaces, . fullScreenAuxiliary, . transient]
27- it. hasShadow = false
28- it. setIsVisible ( false )
29- it. canBecomeKeyChecker = { false }
30- return it
31- } ( )
32-
33- private lazy var widgetWindow = {
34- let it = CanBecomeKeyWindow (
35- contentRect: . zero,
36- styleMask: . borderless,
37- backing: . buffered,
38- defer: false
39- )
40- it. isReleasedWhenClosed = false
41- it. isOpaque = false
42- it. backgroundColor = . clear
43- it. level = . floating
44- it. collectionBehavior = [ . fullScreenAuxiliary, . transient]
45- it. hasShadow = true
46- it. contentView = NSHostingView (
47- rootView: WidgetView (
48- store: store. scope (
49- state: \. _circularWidgetState,
50- action: WidgetFeature . Action. circularWidget
51- )
52- )
53- )
54- it. setIsVisible ( true )
55- it. canBecomeKeyChecker = { false }
56- return it
57- } ( )
58-
59- private lazy var sharedPanelWindow = {
60- let it = CanBecomeKeyWindow (
61- contentRect: . init( x: 0 , y: 0 , width: Style . panelWidth, height: Style . panelHeight) ,
62- styleMask: . borderless,
63- backing: . buffered,
64- defer: false
65- )
66- it. isReleasedWhenClosed = false
67- it. isOpaque = false
68- it. backgroundColor = . clear
69- it. level = . init( NSWindow . Level. floating. rawValue + 2 )
70- it. collectionBehavior = [ . fullScreenAuxiliary, . transient]
71- it. hasShadow = true
72- it. contentView = NSHostingView (
73- rootView: SharedPanelView (
74- store: store. scope (
75- state: \. panelState,
76- action: WidgetFeature . Action. panel
77- ) . scope (
78- state: \. sharedPanelState,
79- action: PanelFeature . Action. sharedPanel
80- )
81- )
82- )
83- it. setIsVisible ( true )
84- it. canBecomeKeyChecker = { [ store] in
85- store. withState { state in
86- state. panelState. sharedPanelState. content. promptToCode != nil
87- }
88- }
89- return it
90- } ( )
91-
92- private lazy var suggestionPanelWindow = {
93- let it = CanBecomeKeyWindow (
94- contentRect: . init( x: 0 , y: 0 , width: Style . panelWidth, height: Style . panelHeight) ,
95- styleMask: . borderless,
96- backing: . buffered,
97- defer: false
98- )
99- it. isReleasedWhenClosed = false
100- it. isOpaque = false
101- it. backgroundColor = . clear
102- it. level = . init( NSWindow . Level. floating. rawValue + 2 )
103- it. collectionBehavior = [ . fullScreenAuxiliary, . transient]
104- it. hasShadow = true
105- it. contentView = NSHostingView (
106- rootView: SuggestionPanelView (
107- store: store. scope (
108- state: \. panelState,
109- action: WidgetFeature . Action. panel
110- ) . scope (
111- state: \. suggestionPanelState,
112- action: PanelFeature . Action. suggestionPanel
113- )
114- )
115- )
116- it. canBecomeKeyChecker = { false }
117- it. setIsVisible ( true )
118- return it
119- } ( )
120-
121- private lazy var chatPanelWindow = {
122- let it = ChatWindow (
123- contentRect: . zero,
124- styleMask: [ . resizable, . titled, . miniaturizable, . fullSizeContentView] ,
125- backing: . buffered,
126- defer: false
127- )
128- it. minimizeWindow = { [ weak self] in
129- self ? . store. send ( . chatPanel( . hideButtonClicked) )
130- }
131- it. titleVisibility = . hidden
132- it. addTitlebarAccessoryViewController ( {
133- let controller = NSTitlebarAccessoryViewController ( )
134- let view = NSHostingView ( rootView: ChatTitleBar ( store: store. scope (
135- state: \. chatPanelState,
136- action: WidgetFeature . Action. chatPanel
137- ) ) )
138- controller. view = view
139- view. frame = . init( x: 0 , y: 0 , width: 100 , height: 40 )
140- controller. layoutAttribute = . right
141- return controller
142- } ( ) )
143- it. titlebarAppearsTransparent = true
144- it. isReleasedWhenClosed = false
145- it. isOpaque = false
146- it. backgroundColor = . clear
147- it. level = . init( NSWindow . Level. floating. rawValue + 1 )
148- it. collectionBehavior = [
149- . fullScreenAuxiliary,
150- . transient,
151- . fullScreenPrimary,
152- . fullScreenAllowsTiling,
153- ]
154- it. hasShadow = true
155- it. contentView = NSHostingView (
156- rootView: ChatWindowView (
157- store: store. scope (
158- state: \. chatPanelState,
159- action: WidgetFeature . Action. chatPanel
160- ) ,
161- toggleVisibility: { [ weak it] isDisplayed in
162- guard let window = it else { return }
163- window. isPanelDisplayed = isDisplayed
164- }
165- )
166- . environment ( \. chatTabPool, chatTabPool)
167- )
168- it. setIsVisible ( true )
169- it. isPanelDisplayed = false
170- it. delegate = self
171- return it
172- } ( )
173-
174- private lazy var toastWindow = {
175- let it = CanBecomeKeyWindow (
176- contentRect: . zero,
177- styleMask: [ . borderless] ,
178- backing: . buffered,
179- defer: false
180- )
181- it. isReleasedWhenClosed = false
182- it. isOpaque = true
183- it. backgroundColor = . clear
184- it. level = . floating
185- it. collectionBehavior = [ . fullScreenAuxiliary, . transient]
186- it. hasShadow = false
187- it. contentView = NSHostingView (
188- rootView: ToastPanelView ( store: store. scope (
189- state: \. toastPanel,
190- action: WidgetFeature . Action. toastPanel
191- ) )
192- )
193- it. setIsVisible ( true )
194- it. ignoresMouseEvents = true
195- it. canBecomeKeyChecker = { false }
196- return it
197- } ( )
198-
19914 let store : StoreOf < WidgetFeature >
20015 let viewStore : ViewStoreOf < WidgetFeature >
20116 let chatTabPool : ChatTabPool
17+ let windowsController : WindowsController
20218 private var cancellable = Set < AnyCancellable > ( )
20319
20420 public let dependency : SuggestionWidgetControllerDependency
@@ -212,19 +28,16 @@ public final class SuggestionWidgetController: NSObject {
21228 self . store = store
21329 self . chatTabPool = chatTabPool
21430 viewStore = . init( store, observe: { $0 } )
31+ windowsController = . init( store: store, chatTabPool: chatTabPool)
21532
21633 super. init ( )
21734
21835 if ProcessInfo . processInfo. environment [ " IS_UNIT_TEST " ] == " YES " { return }
21936
220- dependency. windows. chatPanelWindow = chatPanelWindow
221- dependency. windows. toastWindow = toastWindow
222- dependency. windows. sharedPanelWindow = sharedPanelWindow
223- dependency. windows. suggestionPanelWindow = suggestionPanelWindow
224- dependency. windows. fullscreenDetector = fullscreenDetector
225- dependency. windows. widgetWindow = widgetWindow
226-
37+ dependency. windowsController = windowsController
38+
22739 store. send ( . startup)
40+ windowsController. start ( )
22841 }
22942}
23043
@@ -267,69 +80,3 @@ public extension SuggestionWidgetController {
26780 }
26881}
26982
270- // MARK: - NSWindowDelegate
271-
272- extension SuggestionWidgetController : NSWindowDelegate {
273- public func windowWillMove( _ notification: Notification ) {
274- guard ( notification. object as? NSWindow ) === chatPanelWindow else { return }
275- Task { @MainActor in
276- await Task . yield ( )
277- store. send ( . chatPanel( . detachChatPanel) )
278- }
279- }
280-
281- public func windowWillEnterFullScreen( _ notification: Notification ) {
282- guard ( notification. object as? NSWindow ) === chatPanelWindow else { return }
283- Task { @MainActor in
284- await Task . yield ( )
285- store. send ( . chatPanel( . enterFullScreen) )
286- }
287- }
288-
289- public func windowWillExitFullScreen( _ notification: Notification ) {
290- guard ( notification. object as? NSWindow ) === chatPanelWindow else { return }
291- Task { @MainActor in
292- await Task . yield ( )
293- store. send ( . chatPanel( . exitFullScreen) )
294- }
295- }
296- }
297-
298- // MARK: - Window Subclasses
299-
300- class CanBecomeKeyWindow : NSWindow {
301- var canBecomeKeyChecker : ( ) -> Bool = { true }
302- override var canBecomeKey : Bool { canBecomeKeyChecker ( ) }
303- override var canBecomeMain : Bool { canBecomeKeyChecker ( ) }
304- }
305-
306- class ChatWindow : NSWindow {
307- override var canBecomeKey : Bool { true }
308- override var canBecomeMain : Bool { true }
309-
310-
311- var minimizeWindow : ( ) -> Void = { }
312-
313- var isWindowHidden : Bool = false {
314- didSet {
315- alphaValue = isPanelDisplayed && !isWindowHidden ? 1 : 0
316- }
317- }
318-
319- var isPanelDisplayed : Bool = false {
320- didSet {
321- alphaValue = isPanelDisplayed && !isWindowHidden ? 1 : 0
322- }
323- }
324-
325- override var alphaValue : CGFloat {
326- didSet {
327- ignoresMouseEvents = alphaValue <= 0
328- }
329- }
330-
331- override func miniaturize( _: Any ? ) {
332- minimizeWindow ( )
333- }
334- }
335-
0 commit comments