From ba3471291a3e343f335261d83aa9ab23fe5f699f Mon Sep 17 00:00:00 2001
From: Ariver <shanghai3168@gmail.com>
Date: Sun, 24 May 2026 18:52:37 +0800
Subject: [PATCH] Keep secondary windows in fullscreen Space
---
Apptag/ApptagApp.swift | 39 ++++++++++++++++++++++++++++++++-------
1 files changed, 32 insertions(+), 7 deletions(-)
diff --git a/Apptag/ApptagApp.swift b/Apptag/ApptagApp.swift
index ea0f0e3..214816c 100644
--- a/Apptag/ApptagApp.swift
+++ b/Apptag/ApptagApp.swift
@@ -67,6 +67,7 @@
private var lastShowDockIcon: Bool?
private var statusMenuScreenForNextOverlay: NSScreen?
private var overlayGeneration = 0
+ private var overlayAvoidsSpaceSwitch = false
private var suppressReopenUntil = Date.distantPast
private struct OverlayPlacementContext {
@@ -269,9 +270,8 @@
let showDock = UserDefaults.standard.bool(forKey: Self.showDockIconKey)
lastShowDockIcon = showDock
- let shouldStayAccessoryForCurrentFullscreenSpace = avoidSpaceSwitch
- && isOverlayVisible
- && !isSettingsVisible
+ let shouldStayAccessoryForCurrentFullscreenSpace = isOverlayVisible
+ && (avoidSpaceSwitch || overlayAvoidsSpaceSwitch)
let desiredPolicy: NSApplication.ActivationPolicy = shouldStayAccessoryForCurrentFullscreenSpace
? .accessory
: (requiresForegroundOwnership
@@ -784,6 +784,7 @@
let placement = overlayPlacementContextForNextOverlay(preferredScreen: preferredScreen)
let shouldAvoidSpaceSwitch = placement.map { hasFullscreenWindowOnScreen($0.screen) } ?? false
if let overlayWindow, overlayWindow.isVisible {
+ overlayAvoidsSpaceSwitch = shouldAvoidSpaceSwitch
moveOverlayToCurrentPlacement(preferredScreen: preferredScreen)
overlayWindow.level = currentOverlayLevel
refreshLauncherChromeState(activate: !shouldAvoidSpaceSwitch, avoidSpaceSwitch: shouldAvoidSpaceSwitch)
@@ -839,6 +840,7 @@
existingWindow.orderOut(nil)
overlayWindow = nil
}
+ overlayAvoidsSpaceSwitch = shouldAvoidSpaceSwitch
let window = makeOverlayWindow(
on: placement.screen,
@@ -1098,6 +1100,7 @@
overlayWindow?.orderOut(nil)
removeOverlayKeyMonitor()
removeQuickSearchExternalMouseMonitor()
+ overlayAvoidsSpaceSwitch = false
refreshLauncherChromeState()
NotificationCenter.default.post(name: .tagLauncherOverlayDidHide, object: nil)
if discardWindow {
@@ -1203,7 +1206,10 @@
private func showQuickSearchFromGlobalHotkey() {
if overlayWindow?.isVisible == true {
- refreshLauncherChromeState(activate: true)
+ refreshLauncherChromeState(
+ activate: !overlayAvoidsSpaceSwitch,
+ avoidSpaceSwitch: overlayAvoidsSpaceSwitch
+ )
requestQuickSearch(source: QuickSearchOpenSource.globalVisible)
return
}
@@ -1299,12 +1305,20 @@
var behavior = window.collectionBehavior
behavior.remove(.canJoinAllSpaces)
- behavior.formUnion([.fullScreenAuxiliary, .moveToActiveSpace])
+ if overlayAvoidsSpaceSwitch {
+ behavior.remove(.moveToActiveSpace)
+ behavior.formUnion([.fullScreenAuxiliary, .stationary, .transient, .ignoresCycle])
+ } else {
+ behavior.formUnion([.fullScreenAuxiliary, .moveToActiveSpace])
+ }
window.collectionBehavior = behavior
window.makeKeyAndOrderFront(nil)
window.orderFrontRegardless()
settingsWindow = window
- refreshLauncherChromeState(activate: true)
+ refreshLauncherChromeState(
+ activate: !overlayAvoidsSpaceSwitch,
+ avoidSpaceSwitch: overlayAvoidsSpaceSwitch
+ )
}
private func attachSettingsWindow(_ window: NSWindow, to overlayWindow: NSWindow) {
@@ -1454,6 +1468,13 @@
}
private func promoteOverlayToForegroundInput() {
+ if overlayAvoidsSpaceSwitch {
+ refreshLauncherChromeState(activate: false, avoidSpaceSwitch: true)
+ guard let overlayWindow else { return }
+ overlayWindow.makeKeyAndOrderFront(nil)
+ overlayWindow.orderFrontRegardless()
+ return
+ }
beginLauncherForegroundOwnership()
guard let overlayWindow else { return }
overlayWindow.makeKeyAndOrderFront(nil)
@@ -1551,7 +1572,11 @@
@objc private func openPreferences(_ sender: Any? = nil) {
TagDatabase.flushPendingCategorySchemeBackupBatch()
- beginLauncherForegroundOwnership()
+ if overlayAvoidsSpaceSwitch {
+ refreshLauncherChromeState(activate: false, avoidSpaceSwitch: true)
+ } else {
+ beginLauncherForegroundOwnership()
+ }
// Don't hide overlay — keep it visible for real-time setting preview.
if let overlayWindow, overlayWindow.isVisible {
overlayWindow.makeKeyAndOrderFront(nil)
--
Gitblit v1.9.3