From a4cc11b47009cf3223234c99b76bc713c9e533cf Mon Sep 17 00:00:00 2001 From: Louis Pontoise Date: Fri, 30 Aug 2019 02:03:26 +0900 Subject: [PATCH] fix: better heuristic for windows of same app (closes #12) --- alt-tab-macos/logic/WindowManager.swift | 24 +++--------------------- alt-tab-macos/ui/Application.swift | 15 ++++++++------- 2 files changed, 11 insertions(+), 28 deletions(-) diff --git a/alt-tab-macos/logic/WindowManager.swift b/alt-tab-macos/logic/WindowManager.swift index 95adc450c..db407280d 100644 --- a/alt-tab-macos/logic/WindowManager.swift +++ b/alt-tab-macos/logic/WindowManager.swift @@ -41,31 +41,13 @@ func computeDownscaledSize(_ image: NSImage) -> (Int, Int) { } } -func cgMakeshiftId(_ window: NSDictionary) -> (String, pid_t, CGWindowID, String) { - let cgId = window[kCGWindowNumber] as! CGWindowID - let cgOwnerPid = window[kCGWindowOwnerPID] as! pid_t - let cgBounds = window[kCGWindowBounds] as! [String: Int] - let cgTitle = String(window[kCGWindowName] as! NSString) - let cgMakeshiftId = String(cgBounds["X"]!) + String(cgBounds["Y"]!) - + String(cgBounds["Width"]!) + String(cgBounds["Height"]!) - + cgTitle - return (cgMakeshiftId, cgOwnerPid, cgId, cgTitle) -} - -func axMakeshiftId(_ element: AXUIElement) -> String { - let titleAttribute = AXUIElementCopyAttributeValue(element, kAXTitleAttribute, String.self)! - let pos = AXValueGetValue(element, kAXPositionAttribute, NSPoint(), AXValueType.cgPoint)! - let size = AXValueGetValue(element, kAXSizeAttribute, NSSize(), AXValueType.cgSize)! - return String(Int(pos.x)) + String(Int(pos.y)) - + String(Int(size.width)) + String(Int(size.height)) - + titleAttribute -} - func axWindows(_ cgOwnerPid: pid_t) -> [AXUIElement] { if let windows = AXUIElementCopyAttributeValue(AXUIElementCreateApplication(cgOwnerPid), kAXWindowsAttribute, [AXUIElement].self) { return windows.filter { let hasTitle = !(AXUIElementCopyAttributeValue($0, kAXTitleAttribute, String.self) ?? "").isEmpty - return hasTitle + // workaround: some apps like chrome use a window to implement the search popover + let isReasonablyTall = AXValueGetValue($0, kAXSizeAttribute, NSSize(), AXValueType.cgSize)!.height > 200 + return hasTitle && isReasonablyTall } } return [] diff --git a/alt-tab-macos/ui/Application.swift b/alt-tab-macos/ui/Application.swift index 585c25d9d..c35931db7 100644 --- a/alt-tab-macos/ui/Application.swift +++ b/alt-tab-macos/ui/Application.swift @@ -121,14 +121,15 @@ class Application: NSApplication, NSApplicationDelegate, NSWindowDelegate, NSCol func computeOpenWindows() { openWindows.removeAll() + var pidAndCurrentIndex: [pid_t: Int] = [:] for cgWindow in cgWindows() { - let (cgMakeshiftId_, cgOwnerPid, cgId, cgTitle) = cgMakeshiftId(cgWindow) - for axWindow in axWindows(cgOwnerPid) { - if axMakeshiftId(axWindow).starts(with: cgMakeshiftId_) { - openWindows.append(OpenWindow(target: axWindow, ownerPid: cgOwnerPid, cgId: cgId, cgTitle: cgTitle)) - break - } - } + let cgId = cgWindow[kCGWindowNumber] as! CGWindowID + let cgTitle = String(cgWindow[kCGWindowName] as! NSString) + let cgOwnerPid = cgWindow[kCGWindowOwnerPID] as! pid_t + let i = pidAndCurrentIndex.index(forKey: cgOwnerPid) + pidAndCurrentIndex[cgOwnerPid] = i == nil ? 0 : pidAndCurrentIndex[i!].value + 1 + let axWindow = axWindows(cgOwnerPid)[pidAndCurrentIndex[cgOwnerPid]!] + openWindows.append(OpenWindow(target: axWindow, ownerPid: cgOwnerPid, cgId: cgId, cgTitle: cgTitle)) } }