| Apptag/ApptagApp.swift | ●●●●● patch | view | raw | blame | history | |
| Apptag/Info.plist | ●●●●● patch | view | raw | blame | history | |
| Apptag/OverlayWindowController.swift | ●●●●● patch | view | raw | blame | history | |
| Apptag/ProcessSingleton.swift | ●●●●● patch | view | raw | blame | history | |
| CHANGELOG.md | ●●●●● patch | view | raw | blame | history | |
| Release/AppStore-7.8.7-20260531.0252/APP_STORE_ASSET_INVENTORY.md | ●●●●● patch | view | raw | blame | history | |
| Release/AppStore-7.8.7-20260531.0252/Archive/TagLauncher-7.8.7-20260531.0252-local-QA.dmg | patch | view | raw | blame | history | |
| Release/AppStore-7.8.7-20260531.0252/QA_RELEASE_EVIDENCE.md | ●●●●● patch | view | raw | blame | history | |
| Release/AppStore-7.8.7-20260531.0252/README.md | ●●●●● patch | view | raw | blame | history | |
| Scripts/window_logic_qa.sh | ●●●●● patch | view | raw | blame | history |
Apptag/ApptagApp.swift
@@ -38,6 +38,7 @@ private static let downloadHelpMenuItemIdentifier = NSUserInterfaceItemIdentifier("TagLauncherDownloadHelpMenuItem") private static let externalActivationNotification = Notification.Name("TagLauncherExternalActivationRequested") private static let externalActivationObject = AppIdentity.bundleIdentifier private static let duplicateLaunchSuppressReopenKey = "duplicateLaunchSuppressReopenAt" private static let launcherOverlayLevel = NSWindow.Level(rawValue: NSWindow.Level.mainMenu.rawValue - 1) private static let overlayDefaultLevel = launcherOverlayLevel private static let overlayTextInputLevel = launcherOverlayLevel @@ -208,11 +209,39 @@ configureApplicationMenuWhenAvailable(retries: 12) } /// Reopening the already-running app must not implicitly show App Grid. /// App Grid is only opened by explicit launcher commands: main hotkey or status item/menu. /// Dock icon reopen is an explicit App Grid entry only when the user chooses to show the Dock icon. /// Duplicate-instance handoff suppresses this path so repeated launches do not show App Grid. func applicationShouldHandleReopen(_ sender: NSApplication, hasVisibleWindows flag: Bool) -> Bool { guard Date() >= suppressReopenUntil else { return false } let lastDuplicateLaunch = UserDefaults.standard.double(forKey: Self.duplicateLaunchSuppressReopenKey) if lastDuplicateLaunch > 0, Date().timeIntervalSince1970 - lastDuplicateLaunch < 2.0 { suppressReopenUntil = Date().addingTimeInterval(1.0) return false } guard UserDefaults.standard.bool(forKey: Self.showDockIconKey) else { return false } guard isPointerNearDockArea() else { return false } showOrFocusOverlay() return false // Suppress default "unhide all windows" behavior } private func isPointerNearDockArea() -> Bool { let mouse = NSEvent.mouseLocation return NSScreen.screens.contains { screen in let frame = screen.frame let visible = screen.visibleFrame guard NSMouseInRect(mouse, frame, false) else { return false } let bottomDock = visible.minY > frame.minY && mouse.y >= frame.minY && mouse.y <= visible.minY + 24 let leftDock = visible.minX > frame.minX && mouse.x >= frame.minX && mouse.x <= visible.minX + 24 let rightDock = visible.maxX < frame.maxX && mouse.x <= frame.maxX && mouse.x >= visible.maxX - 24 return bottomDock || leftDock || rightDock } } func applicationWillTerminate(_ notification: Notification) { @@ -272,11 +301,17 @@ } private func beginLauncherForegroundOwnership(activate: Bool = true, keyWindow: NSWindow? = nil) { if NSApp.activationPolicy() != .regular { NSApp.setActivationPolicy(.regular) let showDock = UserDefaults.standard.bool(forKey: Self.showDockIconKey) let desiredPolicy: NSApplication.ActivationPolicy = showDock ? .regular : .accessory if NSApp.activationPolicy() != desiredPolicy { NSApp.setActivationPolicy(desiredPolicy) } if activate { if activate, showDock { claimLauncherForeground(keyWindow: keyWindow) } else if activate { NSApp.activate(ignoringOtherApps: true) keyWindow?.makeKeyAndOrderFront(nil) keyWindow?.orderFrontRegardless() } } @@ -335,15 +370,18 @@ let shouldStayAccessoryForCurrentFullscreenSpace = isOverlayVisible && (avoidSpaceSwitch || overlayAvoidsSpaceSwitch) let shouldStayAccessoryForHiddenDockChrome = requiresForegroundOwnership && !showDock let shouldStayAccessoryForQuickOnlySearch = isOverlayVisible && quickSearchOnlyOverlaySession && !showDock let desiredPolicy: NSApplication.ActivationPolicy = shouldStayAccessoryForCurrentFullscreenSpace ? .accessory : (shouldStayAccessoryForHiddenDockChrome ? .accessory : (shouldStayAccessoryForQuickOnlySearch ? .accessory : (requiresForegroundOwnership ? .regular : (showDock ? .regular : .accessory))) : (showDock ? .regular : .accessory)))) if NSApp.activationPolicy() != desiredPolicy { NSApp.setActivationPolicy(desiredPolicy) } @@ -355,6 +393,7 @@ if activate && requiresForegroundOwnership && !shouldStayAccessoryForCurrentFullscreenSpace && !shouldStayAccessoryForHiddenDockChrome && !shouldStayAccessoryForQuickOnlySearch { let keyWindow = isSettingsVisible ? settingsWindow : (isOverlayVisible ? overlayWindow : nil) claimLauncherForeground( @@ -1478,7 +1517,10 @@ @objc private func handleExternalActivationRequest(_ notification: Notification) { let shouldShowOverlay = notification.userInfo?["showOverlay"] as? Bool ?? false guard shouldShowOverlay else { return } guard shouldShowOverlay else { suppressReopenUntil = Date().addingTimeInterval(1.0) return } showOrFocusOverlay() } Apptag/Info.plist
@@ -19,9 +19,9 @@ <key>CFBundlePackageType</key> <string>APPL</string> <key>CFBundleShortVersionString</key> <string>7.8.6</string> <string>7.8.7</string> <key>CFBundleVersion</key> <string>20260531.0146</string> <string>20260531.0252</string> <key>LSApplicationCategoryType</key> <string>public.app-category.utilities</string> <key>LSMinimumSystemVersion</key> Apptag/OverlayWindowController.swift
@@ -154,6 +154,14 @@ newWindow.setFrame(placementFrame, display: true) self.orderFront(newWindow) } for delay in [0.2, 0.5] { DispatchQueue.main.asyncAfter(deadline: .now() + delay) { [weak self, weak newWindow] in guard let self, let newWindow, self.window === newWindow else { return } guard newWindow.frame != placementFrame else { return } newWindow.setFrame(placementFrame, display: true) self.orderFront(newWindow) } } if let settingsWindow = self.dependencies.settingsWindow(), settingsWindow.isVisible { self.dependencies.prepareSettingsWindow(settingsWindow) } Apptag/ProcessSingleton.swift
@@ -6,6 +6,7 @@ private static let lockURL = AppIdentity.applicationSupportDirectory .appendingPathComponent("TagLauncher.lock") private static let activationNotification = Notification.Name("TagLauncherExternalActivationRequested") private static let duplicateLaunchSuppressReopenKey = "duplicateLaunchSuppressReopenAt" static func acquireOrHandOffAndExit() -> FileHandle { do { @@ -34,6 +35,8 @@ let arguments = CommandLine.arguments.dropFirst() let shouldShowOverlay = arguments.contains("--show-overlay") if !shouldShowOverlay { UserDefaults.standard.set(Date().timeIntervalSince1970, forKey: duplicateLaunchSuppressReopenKey) UserDefaults.standard.synchronize() NSApplication.shared.setActivationPolicy(.accessory) } let ownerInstance = NSRunningApplication CHANGELOG.md
@@ -1,5 +1,13 @@ # TagLauncher Changelog ## [7.8.7] — 2026-05-31 - 修复关闭“Show in Dock”后用主快捷键打开 App Grid 时 TagLauncher Dock 图标仍会闪现的问题;隐藏 Dock 图标设置现在严格生效 - 恢复“Show in Dock”开启时点击 Dock 图标打开 App Grid 的交互,同时继续阻止程序化重复启动误唤出 App Grid - 加固 overlay 显示后的窗口 frame 复核,避免隐藏 Dock / 多屏 / 全屏场景下系统坐标变化导致 overlay 偏移 - 窗口 QA 增加 Dock 点击、隐藏 Dock 主快捷键、重复启动不弹 App Grid 的组合回归 - 版本号更新为 `7.8.7`,Build 更新为 `20260531.0252` ## [7.8.6] — 2026-05-31 - 修复未按主快捷键时 App Grid 可能被重复启动或外部激活路径误唤出的问题;App Grid 现在只由主快捷键或状态栏显式命令打开 Release/AppStore-7.8.7-20260531.0252/APP_STORE_ASSET_INVENTORY.md
New file @@ -0,0 +1,17 @@ # App Store Asset Inventory This release pack freezes TagLauncher `7.8.7` build `20260531.0252`. ## Included - `Archive/TagLauncher-7.8.7-20260531.0252-local-QA.dmg` - `README.md` - `QA_RELEASE_EVIDENCE.md` - `APP_STORE_ASSET_INVENTORY.md` ## External Items Still Required For App Store Upload - Apple Developer Bundle ID selection/confirmation in App Store Connect. - Mac App Store signing certificate and provisioning profile. - Final App Store screenshots and metadata review before submission. Release/AppStore-7.8.7-20260531.0252/Archive/TagLauncher-7.8.7-20260531.0252-local-QA.dmgBinary files differ
Release/AppStore-7.8.7-20260531.0252/QA_RELEASE_EVIDENCE.md
New file @@ -0,0 +1,39 @@ # QA Release Evidence ## Build Under Test - Version: `7.8.7` - Build: `20260531.0252` - App: `/Users/ar/Projects/Taglauncher/build/TagLauncher.app` - DMG: `/Users/ar/Projects/Taglauncher/build/TagLauncher.dmg` - Archived DMG: `Archive/TagLauncher-7.8.7-20260531.0252-local-QA.dmg` - DMG SHA-256: `51cb2861eaf9194dc717cf00b96d3adca490ba89b16438c530b24939a25a94ae` ## Checks - Version metadata: - `CFBundleShortVersionString = 7.8.7` - `CFBundleVersion = 20260531.0252` - `LSUIElement = true` - Code signing: - `codesign --verify --deep --strict --verbose=2 build/TagLauncher.app` - Result: passed - Disk image: - `hdiutil verify build/TagLauncher.dmg` - Result: passed - Window logic: - `APP_BUILD=20260531.0252 Scripts/window_logic_qa.sh` - Result: `ALL WINDOW LOGIC QA PASSED` ## Targeted Fix Coverage - `Show in Dock = false`, main hotkey: - Expected: App Grid appears and no TagLauncher Dock tile appears. - Result: passed - `Show in Dock = true`, Dock icon click: - Expected: App Grid appears. - Result: passed - Duplicate launches: - Expected: one Dock tile and no unexpected App Grid. - Result: passed Release/AppStore-7.8.7-20260531.0252/README.md
New file @@ -0,0 +1,32 @@ # TagLauncher 7.8.7 Release Pack This folder freezes TagLauncher `7.8.7` build `20260531.0252` for local QA distribution and Mac App Store submission preparation. ## Release Identity - Product: `TagLauncher` - Version: `7.8.7` - Build: `20260531.0252` - Branch: `codex/fix-quick-search-focus-routing` - Local QA DMG: `Archive/TagLauncher-7.8.7-20260531.0252-local-QA.dmg` - DMG SHA-256: `51cb2861eaf9194dc717cf00b96d3adca490ba89b16438c530b24939a25a94ae` ## Changes Since 7.8.6 - Hidden-Dock mode no longer flashes the TagLauncher Dock icon when opening App Grid with the main hotkey. - Dock icon click opens App Grid when `Show in Dock` is enabled. - Programmatic duplicate launches remain blocked from opening App Grid. - Overlay frame is rechecked after show-time system coordinate changes to reduce fullscreen/multi-display drift. ## Verification - App version metadata verified: `7.8.7 (20260531.0252)` - `LSUIElement = true` - `codesign --verify --deep --strict --verbose=2 build/TagLauncher.app`: passed - `hdiutil verify build/TagLauncher.dmg`: passed - `Scripts/window_logic_qa.sh`: passed - Targeted checks: - `showDockIcon=false` + main hotkey: App Grid appears, no TagLauncher Dock tile. - `showDockIcon=true` + Dock click: App Grid appears. - repeated launches: one Dock tile, no unexpected App Grid. Scripts/window_logic_qa.sh
@@ -278,6 +278,61 @@ log "PASS Dock tile count: $names" } assert_no_dock_tile() { local output count names output="$(osascript <<'OSA' tell application "System Events" tell process "Dock" set tagCount to 0 set tagNames to {} repeat with itemRef in UI elements of list 1 try set itemName to name of itemRef as text if itemName is "TagLauncher" then set tagCount to tagCount + 1 set end of tagNames to itemName end if end try end repeat return (tagCount as text) & "|" & (tagNames as text) end tell end tell OSA )" count="${output%%|*}" names="${output#*|}" if [[ "$count" != "0" ]]; then echo "FAIL: expected no TagLauncher Dock tile, got $count ($names)" >&2 return 1 fi log "PASS no TagLauncher Dock tile" } click_taglauncher_dock_tile() { local coords x y coords="$(osascript <<'OSA' tell application "System Events" tell process "Dock" repeat with itemRef in UI elements of list 1 try if (name of itemRef as text) is "TagLauncher" then set itemPosition to position of itemRef set itemSize to size of itemRef set centerX to (item 1 of itemPosition) + ((item 1 of itemSize) / 2) set centerY to (item 2 of itemPosition) + ((item 2 of itemSize) / 2) return (centerX as integer as text) & " " & (centerY as integer as text) end if end try end repeat error "TagLauncher Dock tile not found" end tell end tell OSA )" read -r x y <<<"$coords" click_xy "$x" "$y" } assert_frontmost_taglauncher() { local frontmost frontmost="$(osascript -e 'tell application "System Events" to get name of first application process whose frontmost is true')" @@ -1071,6 +1126,24 @@ assert_single_qa_app_instance assert_single_dock_tile swift_assert no-overlay log "==> QA Dock reopen: showDockIcon=true opens App Grid from explicit app reopen" click_taglauncher_dock_tile sleep 1.0 wait_swift_assert overlay send_keycode 53 sleep 0.4 wait_swift_assert no-overlay log "==> QA hidden Dock: main hotkey opens App Grid without showing Dock tile" defaults write "$DEFAULTS_DOMAIN" showDockIcon -bool false prepare_isolated_app_instance assert_no_dock_tile send_main_hotkey sleep 0.8 wait_swift_assert overlay assert_no_dock_tile send_keycode 53 sleep 0.4 wait_swift_assert no-overlay kill_all_taglauncher_instances sleep 0.4 swift_assert no-overlay