fix: better heuristic for windows of same app (closes #12)
This commit is contained in:
1 parent
d41bff7a36
commit
a4cc11b470
2 files changed
+11
-28
No files matched your search
@@ -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 []
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user