From 254ab69332b29884e40f326046ee52a9461469fb Mon Sep 17 00:00:00 2001 From: altic-dev Date: Mon, 20 Jul 2026 17:48:54 -0700 Subject: [PATCH 1/4] fix: keep main window hidden during dictation --- Sources/Fluid/AppDelegate.swift | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/Sources/Fluid/AppDelegate.swift b/Sources/Fluid/AppDelegate.swift index 82e9bf45..eb39b442 100644 --- a/Sources/Fluid/AppDelegate.swift +++ b/Sources/Fluid/AppDelegate.swift @@ -18,6 +18,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDele private var shouldSuppressNextReopenActivation = false private var wasLaunchedAsLoginItem = false private var hasDeferredMLXUpgradeOffer = false + private weak var mainWindowHiddenByAppHide: NSWindow? func applicationDidFinishLaunching(_ notification: Notification) { // Bring up file logging + crash handlers immediately during launch. @@ -123,6 +124,8 @@ class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDele } func applicationShouldHandleReopen(_ sender: NSApplication, hasVisibleWindows flag: Bool) -> Bool { + self.mainWindowHiddenByAppHide = nil + if self.shouldSuppressNextReopenActivation { self.shouldSuppressNextReopenActivation = false return true @@ -134,10 +137,30 @@ class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDele return !self.bringMainWindowToFrontIfPresent() } + func applicationWillHide(_ notification: Notification) { + // A nonactivating recording panel can make AppKit unhide the process. Remember + // the visible main window so the panel does not restore it along with itself. + self.didRevealMainWindowOnLaunch = true + self.mainWindowHiddenByAppHide = NSApp.windows.first { + self.isMainWindow($0) && $0.isVisible && !$0.isMiniaturized + } + } + + func applicationDidHide(_ notification: Notification) { + self.mainWindowHiddenByAppHide?.orderOut(nil) + } + func applicationDidBecomeActive(_ notification: Notification) { - guard self.hasDeferredMLXUpgradeOffer else { return } - self.hasDeferredMLXUpgradeOffer = false - self.scheduleMLXUpgradeOffer() + if let mainWindow = self.mainWindowHiddenByAppHide { + self.mainWindowHiddenByAppHide = nil + mainWindow.orderFrontRegardless() + mainWindow.makeKeyAndOrderFront(nil) + } + + if self.hasDeferredMLXUpgradeOffer { + self.hasDeferredMLXUpgradeOffer = false + self.scheduleMLXUpgradeOffer() + } } func userNotificationCenter( From e6455931dbdebd3fc0871878a3c0a04dde9385dd Mon Sep 17 00:00:00 2001 From: altic-dev Date: Mon, 20 Jul 2026 17:56:59 -0700 Subject: [PATCH 2/4] fix: preserve hidden launch retries --- Sources/Fluid/AppDelegate.swift | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/Sources/Fluid/AppDelegate.swift b/Sources/Fluid/AppDelegate.swift index eb39b442..ca0dbd46 100644 --- a/Sources/Fluid/AppDelegate.swift +++ b/Sources/Fluid/AppDelegate.swift @@ -19,6 +19,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDele private var wasLaunchedAsLoginItem = false private var hasDeferredMLXUpgradeOffer = false private weak var mainWindowHiddenByAppHide: NSWindow? + private var shouldSuppressMainWindowLaunchReveal = false func applicationDidFinishLaunching(_ notification: Notification) { // Bring up file logging + crash handlers immediately during launch. @@ -125,6 +126,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDele func applicationShouldHandleReopen(_ sender: NSApplication, hasVisibleWindows flag: Bool) -> Bool { self.mainWindowHiddenByAppHide = nil + self.shouldSuppressMainWindowLaunchReveal = false if self.shouldSuppressNextReopenActivation { self.shouldSuppressNextReopenActivation = false @@ -140,10 +142,13 @@ class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDele func applicationWillHide(_ notification: Notification) { // A nonactivating recording panel can make AppKit unhide the process. Remember // the visible main window so the panel does not restore it along with itself. - self.didRevealMainWindowOnLaunch = true + self.shouldSuppressMainWindowLaunchReveal = true self.mainWindowHiddenByAppHide = NSApp.windows.first { self.isMainWindow($0) && $0.isVisible && !$0.isMiniaturized } + if self.mainWindowHiddenByAppHide != nil { + self.didRevealMainWindowOnLaunch = true + } } func applicationDidHide(_ notification: Notification) { @@ -151,8 +156,13 @@ class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDele } func applicationDidBecomeActive(_ notification: Notification) { + self.shouldSuppressMainWindowLaunchReveal = false + if let mainWindow = self.mainWindowHiddenByAppHide { self.mainWindowHiddenByAppHide = nil + if mainWindow.alphaValue <= 0.01 { + mainWindow.alphaValue = 1 + } mainWindow.orderFrontRegardless() mainWindow.makeKeyAndOrderFront(nil) } @@ -223,7 +233,8 @@ class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDele guard let self else { return } guard self.didRevealMainWindowOnLaunch == false else { return } - if revealWindow { + let shouldRevealWindow = revealWindow && !self.shouldSuppressMainWindowLaunchReveal + if shouldRevealWindow { NSApp.unhide(nil) NSApp.activate(ignoringOtherApps: true) @@ -238,7 +249,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDele DebugLogger.shared.debug("Main window not ready during launch reveal retry", source: "AppDelegate") if delay >= 0.6 { - self.requestMainWindowReopenIfNeeded(activate: revealWindow) + self.requestMainWindowReopenIfNeeded(activate: shouldRevealWindow) } } } From e6f1c1871f248fd1edca50052b8ab665e5d93fcc Mon Sep 17 00:00:00 2001 From: altic-dev Date: Mon, 20 Jul 2026 18:04:36 -0700 Subject: [PATCH 3/4] fix: restore delayed hidden window --- Sources/Fluid/AppDelegate.swift | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/Sources/Fluid/AppDelegate.swift b/Sources/Fluid/AppDelegate.swift index ca0dbd46..bf6f6984 100644 --- a/Sources/Fluid/AppDelegate.swift +++ b/Sources/Fluid/AppDelegate.swift @@ -125,14 +125,14 @@ class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDele } func applicationShouldHandleReopen(_ sender: NSApplication, hasVisibleWindows flag: Bool) -> Bool { - self.mainWindowHiddenByAppHide = nil - self.shouldSuppressMainWindowLaunchReveal = false - if self.shouldSuppressNextReopenActivation { self.shouldSuppressNextReopenActivation = false return true } + self.mainWindowHiddenByAppHide = nil + self.shouldSuppressMainWindowLaunchReveal = false + // Ensure dock-icon reopen always foregrounds FluidVoice. sender.activate(ignoringOtherApps: true) @@ -243,6 +243,11 @@ class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDele return } } else if self.bootMainWindowHiddenIfPresent() { + if self.shouldSuppressMainWindowLaunchReveal, + self.mainWindowHiddenByAppHide == nil + { + self.mainWindowHiddenByAppHide = NSApp.windows.first(where: self.isMainWindow) + } self.didRevealMainWindowOnLaunch = true return } From b806f9a3f77ff875527fd936a795fc3b9c122ea6 Mon Sep 17 00:00:00 2001 From: altic-dev Date: Mon, 20 Jul 2026 18:06:58 -0700 Subject: [PATCH 4/4] fix: distinguish system-hidden login launch --- Sources/Fluid/AppDelegate.swift | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Sources/Fluid/AppDelegate.swift b/Sources/Fluid/AppDelegate.swift index bf6f6984..c890f0db 100644 --- a/Sources/Fluid/AppDelegate.swift +++ b/Sources/Fluid/AppDelegate.swift @@ -140,6 +140,14 @@ class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDele } func applicationWillHide(_ notification: Notification) { + // A system-hidden login launch is not a user request to suppress its configured reveal. + if self.wasLaunchedAsLoginItem, + !self.didRevealMainWindowOnLaunch, + !NSApp.isActive + { + return + } + // A nonactivating recording panel can make AppKit unhide the process. Remember // the visible main window so the panel does not restore it along with itself. self.shouldSuppressMainWindowLaunchReveal = true