fix: subtle reminders no longer steal focus

This commit is contained in:
Michael Freno
2026-01-12 21:53:33 -05:00
parent d5c8f49bf9
commit cef69e4423

View File

@@ -119,6 +119,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, ObservableObject {
private func showReminder(_ event: ReminderEvent) { private func showReminder(_ event: ReminderEvent) {
let contentView: AnyView let contentView: AnyView
let requiresFocus: Bool
switch event { switch event {
case .lookAwayTriggered(let countdownSeconds): case .lookAwayTriggered(let countdownSeconds):
@@ -127,6 +128,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, ObservableObject {
self?.timerEngine?.dismissReminder() self?.timerEngine?.dismissReminder()
} }
) )
requiresFocus = true
case .blinkTriggered: case .blinkTriggered:
let sizePercentage = settingsManager.settings.subtleReminderSize.percentage let sizePercentage = settingsManager.settings.subtleReminderSize.percentage
contentView = AnyView( contentView = AnyView(
@@ -134,6 +136,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, ObservableObject {
self?.timerEngine?.dismissReminder() self?.timerEngine?.dismissReminder()
} }
) )
requiresFocus = false
case .postureTriggered: case .postureTriggered:
let sizePercentage = settingsManager.settings.subtleReminderSize.percentage let sizePercentage = settingsManager.settings.subtleReminderSize.percentage
contentView = AnyView( contentView = AnyView(
@@ -141,6 +144,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, ObservableObject {
self?.timerEngine?.dismissReminder() self?.timerEngine?.dismissReminder()
} }
) )
requiresFocus = false
case .userTimerTriggered(let timer): case .userTimerTriggered(let timer):
if timer.type == .overlay { if timer.type == .overlay {
contentView = AnyView( contentView = AnyView(
@@ -148,6 +152,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, ObservableObject {
self?.timerEngine?.dismissReminder() self?.timerEngine?.dismissReminder()
} }
) )
requiresFocus = true
} else { } else {
let sizePercentage = settingsManager.settings.subtleReminderSize.percentage let sizePercentage = settingsManager.settings.subtleReminderSize.percentage
contentView = AnyView( contentView = AnyView(
@@ -155,21 +160,32 @@ class AppDelegate: NSObject, NSApplicationDelegate, ObservableObject {
self?.timerEngine?.dismissReminder() self?.timerEngine?.dismissReminder()
} }
) )
requiresFocus = false
} }
} }
showReminderWindow(contentView) showReminderWindow(contentView, requiresFocus: requiresFocus)
} }
private func showReminderWindow(_ content: AnyView) { private func showReminderWindow(_ content: AnyView, requiresFocus: Bool) {
guard let screen = NSScreen.main else { return } guard let screen = NSScreen.main else { return }
let window = KeyableWindow( let window: NSWindow
if requiresFocus {
window = KeyableWindow(
contentRect: screen.frame, contentRect: screen.frame,
styleMask: [.borderless, .fullSizeContentView], styleMask: [.borderless, .fullSizeContentView],
backing: .buffered, backing: .buffered,
defer: false defer: false
) )
} else {
window = NonKeyWindow(
contentRect: screen.frame,
styleMask: [.borderless, .fullSizeContentView],
backing: .buffered,
defer: false
)
}
window.identifier = WindowIdentifiers.reminder window.identifier = WindowIdentifiers.reminder
window.level = .floating window.level = .floating
@@ -177,13 +193,18 @@ class AppDelegate: NSObject, NSApplicationDelegate, ObservableObject {
window.backgroundColor = .clear window.backgroundColor = .clear
window.contentView = NSHostingView(rootView: content) window.contentView = NSHostingView(rootView: content)
window.collectionBehavior = [.canJoinAllSpaces, .fullScreenAuxiliary] window.collectionBehavior = [.canJoinAllSpaces, .fullScreenAuxiliary]
window.acceptsMouseMovedEvents = true window.acceptsMouseMovedEvents = !requiresFocus
window.makeFirstResponder(window.contentView) window.ignoresMouseEvents = !requiresFocus
let windowController = NSWindowController(window: window) let windowController = NSWindowController(window: window)
windowController.showWindow(nil) windowController.showWindow(nil)
if requiresFocus {
window.makeKeyAndOrderFront(nil) window.makeKeyAndOrderFront(nil)
NSApp.activate(ignoringOtherApps: true) NSApp.activate(ignoringOtherApps: true)
} else {
window.orderFront(nil)
}
reminderWindowController = windowController reminderWindowController = windowController
} }
@@ -308,3 +329,14 @@ class KeyableWindow: NSWindow {
return true return true
} }
} }
// Non-key window class for subtle reminders that don't steal focus
class NonKeyWindow: NSWindow {
override var canBecomeKey: Bool {
return false
}
override var canBecomeMain: Bool {
return false
}
}