From b6e11990cc9bd3c838ad6cdd9e53caafff0fd7cb Mon Sep 17 00:00:00 2001
From: Ariver <shanghai3168@gmail.com>
Date: Thu, 18 Jun 2026 23:24:21 +0800
Subject: [PATCH] Add vertical App Shelf keyboard focus
---
C1.source/Sources/Aligner/Infrastructure/Windows/CGWindowAXWindowService.swift | 131 +++++++++++++++++++------------------------
1 files changed, 59 insertions(+), 72 deletions(-)
diff --git a/C1.source/Sources/Aligner/Infrastructure/Windows/CGWindowAXWindowService.swift b/C1.source/Sources/Aligner/Infrastructure/Windows/CGWindowAXWindowService.swift
index e03dddb..21abec8 100644
--- a/C1.source/Sources/Aligner/Infrastructure/Windows/CGWindowAXWindowService.swift
+++ b/C1.source/Sources/Aligner/Infrastructure/Windows/CGWindowAXWindowService.swift
@@ -129,8 +129,7 @@
: .activationFailed
}
- func activate(window requestedWindow: AlignerWindow) throws -> WindowActivationResult {
- let window = refreshedFinderWindowForPreciseAction(requestedWindow, operation: "windowActivation")
+ func activate(window: AlignerWindow) throws -> WindowActivationResult {
DevelopmentDiagnostics.log("windowActivation.activate.start", [
"windowID": window.id,
"identifierSource": String(describing: window.identifierSource),
@@ -280,8 +279,7 @@
: .appActivatedOnly
}
- func close(window requestedWindow: AlignerWindow) throws -> WindowCloseResult {
- let window = refreshedFinderWindowForPreciseAction(requestedWindow, operation: "windowClose")
+ func close(window: AlignerWindow) throws -> WindowCloseResult {
DevelopmentDiagnostics.log("windowClose.window.start", [
"windowID": window.id,
"identifierSource": String(describing: window.identifierSource),
@@ -358,59 +356,6 @@
processIdentifier: matchedAXWindow.processIdentifier,
attempt: "initial"
)
- }
-
- private func refreshedFinderWindowForPreciseAction(
- _ window: AlignerWindow,
- operation: String
- ) -> AlignerWindow {
- guard isFinderCGOnlyPageCandidate(window) else { return window }
-
- guard let refreshedWindow = try? allWindows().first(where: { refreshed in
- refreshed.id == window.id
- && refreshed.identifierSource == window.identifierSource
- && refreshed.app.bundleIdentifier == window.app.bundleIdentifier
- }) else {
- DevelopmentDiagnostics.log("\(operation).finderRefresh.missing", [
- "windowID": window.id,
- "spaceIDCount": window.spaceIDs.count,
- "hasFrame": window.frame != nil
- ])
- return window
- }
-
- let mergedWindow = AlignerWindow(
- id: window.id,
- app: window.app.processIdentifier == nil ? refreshedWindow.app : window.app,
- title: window.title.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty
- ? refreshedWindow.title
- : window.title,
- identifierSource: window.identifierSource,
- isMinimized: window.isMinimized || refreshedWindow.isMinimized,
- isFullscreen: window.isFullscreen || refreshedWindow.isFullscreen,
- isGhost: window.isGhost,
- frame: window.frame ?? refreshedWindow.frame,
- spaceIDs: window.spaceIDs.isEmpty ? refreshedWindow.spaceIDs : window.spaceIDs
- )
-
- if mergedWindow.spaceIDs != window.spaceIDs
- || mergedWindow.isFullscreen != window.isFullscreen
- || (window.frame == nil && refreshedWindow.frame != nil) {
- DevelopmentDiagnostics.log("\(operation).finderRefresh.merged", [
- "windowID": window.id,
- "originalSpaceIDCount": window.spaceIDs.count,
- "refreshedSpaceIDCount": refreshedWindow.spaceIDs.count,
- "mergedSpaceIDCount": mergedWindow.spaceIDs.count,
- "originalIsFullscreen": window.isFullscreen,
- "refreshedIsFullscreen": refreshedWindow.isFullscreen,
- "mergedIsFullscreen": mergedWindow.isFullscreen,
- "originalHasFrame": window.frame != nil,
- "refreshedHasFrame": refreshedWindow.frame != nil,
- "mergedHasFrame": mergedWindow.frame != nil
- ])
- }
-
- return mergedWindow
}
private func closeButton(for axWindow: AXWindowMetadata) -> AXUIElement? {
@@ -676,6 +621,28 @@
}
guard let host = finderTabHostAXWindow(for: window, in: axMetadata) else {
+ let normalizedTargetTitle = normalizedWindowTitle(window.title)
+ let applicationActivated = activateApplication(processIdentifier: processIdentifier)
+ let selectedViaWindowMenu = !normalizedTargetTitle.isEmpty
+ && selectFinderWindowMenuItem(
+ processIdentifier: processIdentifier,
+ window: window,
+ normalizedTargetTitle: normalizedTargetTitle
+ )
+ DevelopmentDiagnostics.log("\(operation).finderTab.hostlessWindowMenuResult", [
+ "windowID": window.id,
+ "pid": processIdentifier,
+ "reason": reason,
+ "applicationActivated": applicationActivated,
+ "selectedViaWindowMenu": selectedViaWindowMenu,
+ "spaceIDs": window.spaceIDs,
+ "targetTitleHash": DevelopmentDiagnostics.stableFingerprint(window.title),
+ "targetTitleLength": window.title.count
+ ])
+ if selectedViaWindowMenu {
+ return true
+ }
+
DevelopmentDiagnostics.log("\(operation).finderTab.hostMissing", [
"windowID": window.id,
"pid": processIdentifier,
@@ -772,21 +739,9 @@
finderHostCanRepresentTarget(window, in: metadata)
}
- let hostCandidates: [AXWindowMetadata]
- if targetSpaceIDs.isEmpty {
- guard !selectableHostCandidates.isEmpty else {
- DevelopmentDiagnostics.log("windowActivation.finderTab.noSelectableHost", [
- "windowID": window.id,
- "candidateCount": candidates.count,
- "targetTitleHash": DevelopmentDiagnostics.stableFingerprint(window.title),
- "targetTitleLength": window.title.count
- ])
- return nil
- }
- hostCandidates = selectableHostCandidates
- } else {
- hostCandidates = selectableHostCandidates.isEmpty ? spaceScopedCandidates : selectableHostCandidates
- }
+ let hostCandidates = selectableHostCandidates.isEmpty
+ ? spaceScopedCandidates
+ : selectableHostCandidates
let targetFrame = matchingFrame(for: window)
let scoredHosts = hostCandidates.compactMap { metadata -> (metadata: AXWindowMetadata, score: CGFloat)? in
@@ -807,16 +762,48 @@
if let best = scoredHosts.first {
if scoredHosts.count == 1 {
+ if selectableHostCandidates.isEmpty {
+ DevelopmentDiagnostics.log("windowActivation.finderTab.frameInferredHost", [
+ "windowID": window.id,
+ "hostWindowID": best.metadata.windowID,
+ "score": Double(best.score),
+ "spaceIDCount": targetSpaceIDs.count,
+ "candidateCount": hostCandidates.count,
+ "targetTitleHash": DevelopmentDiagnostics.stableFingerprint(window.title),
+ "targetTitleLength": window.title.count
+ ])
+ }
return best.metadata
}
let secondBest = scoredHosts[1]
if best.score - secondBest.score >= 0.05 {
+ if selectableHostCandidates.isEmpty {
+ DevelopmentDiagnostics.log("windowActivation.finderTab.frameInferredHost", [
+ "windowID": window.id,
+ "hostWindowID": best.metadata.windowID,
+ "score": Double(best.score),
+ "secondBestScore": Double(secondBest.score),
+ "spaceIDCount": targetSpaceIDs.count,
+ "candidateCount": hostCandidates.count,
+ "targetTitleHash": DevelopmentDiagnostics.stableFingerprint(window.title),
+ "targetTitleLength": window.title.count
+ ])
+ }
return best.metadata
}
}
if hostCandidates.count == 1 {
+ if selectableHostCandidates.isEmpty {
+ DevelopmentDiagnostics.log("windowActivation.finderTab.singleFrameHostFallback", [
+ "windowID": window.id,
+ "hostWindowID": hostCandidates[0].windowID,
+ "spaceIDCount": targetSpaceIDs.count,
+ "targetTitleHash": DevelopmentDiagnostics.stableFingerprint(window.title),
+ "targetTitleLength": window.title.count
+ ])
+ }
return hostCandidates[0]
}
--
Gitblit v1.9.3