@@ -15,11 +15,30 @@ public final class OverlayWindowController {
1515 [ IDEWorkspaceWindowOverlayWindowControllerContentProviderFactory ] = [ ]
1616
1717 var ideWindowOverlayWindowControllers : [ URL : IDEWorkspaceWindowOverlayWindowController ] = [ : ]
18+ var updateWindowStateTask : Task < Void , Error > ?
19+
20+ @MainActor
21+ lazy var fullscreenDetector = {
22+ let it = NSWindow (
23+ contentRect: . zero,
24+ styleMask: . borderless,
25+ backing: . buffered,
26+ defer: false
27+ )
28+ it. isReleasedWhenClosed = false
29+ it. isOpaque = false
30+ it. backgroundColor = . clear
31+ it. collectionBehavior = [ . canJoinAllSpaces, . fullScreenAuxiliary, . transient]
32+ it. hasShadow = false
33+ it. setIsVisible ( false )
34+ return it
35+ } ( )
1836
1937 public init ( ) { }
2038
2139 public func start( ) {
2240 observeEvents ( )
41+ _ = fullscreenDetector
2342 }
2443
2544 public nonisolated static func registerIDEWorkspaceWindowOverlayWindowControllerContentProviderFactory(
@@ -34,6 +53,23 @@ public final class OverlayWindowController {
3453extension OverlayWindowController {
3554 func observeEvents( ) {
3655 observeWindowChange ( )
56+
57+ updateWindowStateTask = Task { [ weak self] in
58+ if let self { await handleSpaceChange ( ) }
59+
60+ await withThrowingTaskGroup ( of: Void . self) { [ weak self] group in
61+ // active space did change
62+ _ = group. addTaskUnlessCancelled { [ weak self] in
63+ let sequence = NSWorkspace . shared. notificationCenter
64+ . notifications ( named: NSWorkspace . activeSpaceDidChangeNotification)
65+ for await _ in sequence {
66+ guard let self else { return }
67+ try Task . checkCancellation ( )
68+ await handleSpaceChange ( )
69+ }
70+ }
71+ }
72+ }
3773 }
3874}
3975
@@ -68,7 +104,7 @@ private extension OverlayWindowController {
68104 }
69105 return
70106 }
71-
107+
72108 guard let app = XcodeInspector . shared. activeXcode else {
73109 for (_, controller) in self . ideWindowOverlayWindowControllers {
74110 controller. hide ( )
@@ -122,5 +158,27 @@ private extension OverlayWindowController {
122158 newController. access ( )
123159 ideWindowOverlayWindowControllers [ workspaceURL] = newController
124160 }
161+
162+ func handleSpaceChange( ) async {
163+ let windowInspector = XcodeInspector . shared. focusedWindow
164+ guard let activeWindowController = {
165+ if let windowInspector = windowInspector as? WorkspaceXcodeWindowInspector {
166+ return ideWindowOverlayWindowControllers [ windowInspector. workspaceURL]
167+ } else {
168+ return nil
169+ }
170+ } ( ) else { return }
171+
172+ let activeXcode = XcodeInspector . shared. activeXcode
173+ let xcode = activeXcode? . appElement
174+ let isXcodeActive = xcode? . isFrontmost ?? false
175+ if isXcodeActive {
176+ activeWindowController. maskPanel. moveToActiveSpace ( )
177+ }
178+
179+ if fullscreenDetector. isOnActiveSpace, xcode? . focusedWindow != nil {
180+ activeWindowController. maskPanel. orderFrontRegardless ( )
181+ }
182+ }
125183}
126184
0 commit comments