Skip to content

Commit 7d09c39

Browse files
committed
v0.3.6; regression fix: not popping up in full-screen windows
1 parent 65494c9 commit 7d09c39

5 files changed

Lines changed: 61 additions & 29 deletions

File tree

Sources/Core/AppInfo.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,5 @@ public enum AppInfo {
55
/// Reverse-DNS bundle identifier baked into `Info.plist`.
66
public static let bundleIdentifier = "com.spotnote.SpotNote"
77
/// Marketing version in `MAJOR.MINOR.PATCH` form.
8-
public static let version = "0.3.5"
8+
public static let version = "0.3.6"
99
}

Sources/Spotlight/SpotlightWindow.swift

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,19 @@ public final class SpotlightWindowController {
1010
nonisolated static let panelStyleMask: NSWindow.StyleMask = [
1111
.borderless, .fullSizeContentView
1212
]
13-
/// `.statusBar` floats the HUD above any fullscreen Space. `.floating`
14-
/// is below the menu-bar / fullscreen layer, so a fullscreen app
15-
/// would hide the panel even when ordered front.
16-
nonisolated static let panelLevel: NSWindow.Level = .statusBar
13+
/// `.screenSaver` keeps the HUD above the window layers used by
14+
/// fullscreen apps. Lower levels such as `.floating` and `.statusBar`
15+
/// can still be occluded by fullscreen windows on recent macOS
16+
/// releases even when the panel joins that Space.
17+
nonisolated static let panelLevel: NSWindow.Level = .screenSaver
1718
/// `.fullScreenAuxiliary` is the load-bearing flag -- it lets a panel
1819
/// appear in a fullscreen Space alongside the fullscreen app.
1920
/// `.canJoinAllSpaces` keeps the panel reachable from every Space,
20-
/// and `.stationary` stops it being dragged along during Space
21-
/// transitions (which would otherwise yank focus during the swipe).
21+
/// `.stationary` stops it being dragged along during Space
22+
/// transitions (which would otherwise yank focus during the swipe),
23+
/// and `.ignoresCycle` keeps this transient HUD out of Cmd-` cycling.
2224
nonisolated static let panelCollectionBehavior: NSWindow.CollectionBehavior = [
23-
.canJoinAllSpaces, .fullScreenAuxiliary, .stationary
25+
.canJoinAllSpaces, .fullScreenAuxiliary, .stationary, .ignoresCycle
2426
]
2527
nonisolated static let defaultUnfocusedAlpha: CGFloat = 0.55
2628

@@ -212,7 +214,7 @@ public final class SpotlightWindowController {
212214
focusOrShow()
213215
} else {
214216
NSApp.activate(ignoringOtherApps: true)
215-
panel?.makeKeyAndOrderFront(nil)
217+
if let panel { bringPanelToFront(panel) }
216218
}
217219
if let mostRecent = session.chats.first {
218220
session.jump(to: mostRecent)
@@ -258,10 +260,15 @@ public final class SpotlightWindowController {
258260
}
259261
panel.alphaValue = 1.0
260262
NSApp.activate(ignoringOtherApps: true)
261-
panel.makeKeyAndOrderFront(nil)
263+
bringPanelToFront(panel)
262264
focusTrigger.pulse()
263265
}
264266

267+
private func bringPanelToFront(_ panel: NSPanel) {
268+
panel.makeKeyAndOrderFront(nil)
269+
panel.orderFrontRegardless()
270+
}
271+
265272
private func repositionForShow(_ panel: NSPanel) {
266273
guard let screen = NSScreen.main else { return }
267274
let screenFrame = screen.visibleFrame
@@ -292,15 +299,7 @@ public final class SpotlightWindowController {
292299
backing: .buffered,
293300
defer: false
294301
)
295-
panel.isOpaque = false
296-
panel.backgroundColor = .clear
297-
panel.hasShadow = true
298-
panel.level = Self.panelLevel
299-
panel.isFloatingPanel = true
300-
panel.hidesOnDeactivate = false
301-
panel.becomesKeyOnlyIfNeeded = false
302-
panel.isMovableByWindowBackground = true
303-
panel.collectionBehavior = Self.panelCollectionBehavior
302+
Self.configurePanel(panel)
304303
panel.contentView = NSHostingView(
305304
rootView: SpotlightRootView(
306305
focusTrigger: focusTrigger,
@@ -327,6 +326,18 @@ public final class SpotlightWindowController {
327326
return panel
328327
}
329328

329+
static func configurePanel(_ panel: NSPanel) {
330+
panel.isOpaque = false
331+
panel.backgroundColor = .clear
332+
panel.hasShadow = true
333+
panel.isFloatingPanel = true
334+
panel.level = panelLevel
335+
panel.hidesOnDeactivate = false
336+
panel.becomesKeyOnlyIfNeeded = false
337+
panel.isMovableByWindowBackground = true
338+
panel.collectionBehavior = panelCollectionBehavior
339+
}
340+
330341
private static let driftCorrectionThreshold: CGFloat = 4
331342

332343
private func pinnedOrigin(for panel: NSPanel) -> NSPoint? {

Tests/SpotlightTests/SpotlightWindowControllerTests.swift

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ struct SpotlightWindowControllerTests {
1313
/// a visible, keyed window. `.nonactivatingPanel` was tried as part
1414
/// of an over-fullscreen fix and reproduced exactly that symptom
1515
/// (HUD never opens). The over-fullscreen path is handled instead
16-
/// by `panelLevel == .statusBar` + `.fullScreenAuxiliary` in the
16+
/// by `panelLevel == .screenSaver` + `.fullScreenAuxiliary` in the
1717
/// collection behavior -- see the dedicated tests below.
1818
@Test("panel style mask must NOT contain .nonactivatingPanel for an LSUIElement app")
1919
func panelStyleMaskExcludesNonactivating() {
@@ -41,12 +41,33 @@ struct SpotlightWindowControllerTests {
4141
#expect(behavior.contains(.canJoinAllSpaces))
4242
}
4343

44-
/// **Regression guard** -- anything below `.statusBar` is hidden by a
45-
/// fullscreen app's window layer. `.floating` was the previous level
46-
/// and was the proximate cause of the over-fullscreen bug.
47-
@Test("panel level is .statusBar or higher -- required for over-fullscreen HUD")
44+
/// **Regression guard** -- recent macOS releases can keep
45+
/// fullscreen windows above `.statusBar` auxiliary panels. The HUD is
46+
/// transient, so it uses the overlay-grade screen saver level.
47+
@Test("panel level is .screenSaver -- required for over-fullscreen HUD")
4848
func panelLevelIsAboveFullscreen() {
49-
#expect(SpotlightWindowController.panelLevel.rawValue >= NSWindow.Level.statusBar.rawValue)
49+
#expect(SpotlightWindowController.panelLevel == .screenSaver)
50+
}
51+
52+
@Test("configured panel applies fullscreen overlay behavior")
53+
@MainActor
54+
func configuredPanelAppliesFullscreenOverlayBehavior() {
55+
let panel = SpotlightPanel(
56+
contentRect: NSRect(x: 0, y: 0, width: 10, height: 10),
57+
styleMask: SpotlightWindowController.panelStyleMask,
58+
backing: .buffered,
59+
defer: false
60+
)
61+
62+
SpotlightWindowController.configurePanel(panel)
63+
64+
#expect(panel.level == .screenSaver)
65+
#expect(panel.collectionBehavior.contains(.canJoinAllSpaces))
66+
#expect(panel.collectionBehavior.contains(.fullScreenAuxiliary))
67+
#expect(panel.collectionBehavior.contains(.stationary))
68+
#expect(panel.collectionBehavior.contains(.ignoresCycle))
69+
#expect(panel.hidesOnDeactivate == false)
70+
#expect(panel.isFloatingPanel)
5071
}
5172

5273
@Test("default unfocused alpha is between 0.5 and 1.0 -- visible but clearly faded")

project.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ settings:
1313
SWIFT_VERSION: "6.0"
1414
MACOSX_DEPLOYMENT_TARGET: "14.0"
1515
SWIFT_STRICT_CONCURRENCY: complete
16-
MARKETING_VERSION: "0.3.5"
17-
CURRENT_PROJECT_VERSION: "8"
16+
MARKETING_VERSION: "0.3.6"
17+
CURRENT_PROJECT_VERSION: "9"
1818
configs:
1919
Debug:
2020
SWIFT_OPTIMIZATION_LEVEL: -Onone

scripts/build.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ cat > "$CONTENTS/Info.plist" <<'PLIST'
3333
<key>CFBundleName</key> <string>SpotNote</string>
3434
<key>CFBundleDisplayName</key> <string>SpotNote</string>
3535
<key>CFBundlePackageType</key> <string>APPL</string>
36-
<key>CFBundleShortVersionString</key> <string>0.3.5</string>
37-
<key>CFBundleVersion</key> <string>8</string>
36+
<key>CFBundleShortVersionString</key> <string>0.3.6</string>
37+
<key>CFBundleVersion</key> <string>9</string>
3838
<key>LSMinimumSystemVersion</key> <string>14.0</string>
3939
<key>LSUIElement</key> <true/>
4040
<key>CFBundleIconFile</key> <string>AppIcon</string>

0 commit comments

Comments
 (0)