fix: better heuristic for windows of same app (closes #12)

This commit is contained in:
Louis Pontoise committed 2019-08-30 02:03:41 +09:00
1 parent d41bff7a36
commit a4cc11b470
2 files changed
+11 -28

No files matched your search

+3 -21
View File
@@ -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 []
+8 -7
View File
@@ -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))
}
}