fix: better decide which windows to show the user (closes #15 #30)

This commit is contained in:
Louis Pontoise committed 2019-10-17 21:40:56 +09:00
1 parent 80a883c7d4
commit f150b7e3dc
2 files changed
+16 -9

No files matched your search

+10 -5
View File
@@ -1,6 +1,8 @@
import Cocoa
import Foundation
let minimumWindowSize: CGFloat = 200
class OpenWindow {
var target: AXUIElement?
var ownerPid: pid_t?
@@ -46,10 +48,10 @@ func computeDownscaledSize(_ image: NSImage) -> (Int, Int) {
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
// 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
let windowBounds = AXValueGetValue($0, kAXSizeAttribute, NSSize(), AXValueType.cgSize)!
let isReasonablyBig = windowBounds.width > minimumWindowSize && windowBounds.height > minimumWindowSize
return isReasonablyBig
}
}
return []
@@ -58,9 +60,12 @@ func axWindows(_ cgOwnerPid: pid_t) -> [AXUIElement] {
func cgWindows() -> [NSDictionary] {
let windows = CGWindowListCopyWindowInfo([.excludeDesktopElements, .optionOnScreenOnly], kCGNullWindowID) as! [NSDictionary]
return windows.filter {
// workaround: filtering this criteria seems to remove non-windows UI elements
let isWindowNotMenubarOrOthers = $0[kCGWindowLayer] as? Int == 0
let hasTitle = !(($0[kCGWindowName] as? String ?? "").isEmpty)
return isWindowNotMenubarOrOthers && hasTitle
let windowBounds = CGRect(dictionaryRepresentation: $0[kCGWindowBounds] as! NSDictionary)!
// workaround: some apps like chrome use a window to implement the search popover
let isReasonablyBig = windowBounds.width > minimumWindowSize && windowBounds.height > minimumWindowSize
return isWindowNotMenubarOrOthers && isReasonablyBig
}
}
+6 -4
View File
@@ -117,14 +117,16 @@ class Application: NSApplication, NSApplicationDelegate, NSWindowDelegate, NSCol
var pidAndCurrentIndex: [pid_t: Int] = [:]
for cgWindow in cgWindows() {
let cgId = cgWindow[kCGWindowNumber] as! CGWindowID
let cgTitle = String(cgWindow[kCGWindowName] as! NSString)
let cgTitle = cgWindow[kCGWindowName] as? String ?? ""
let cgOwnerName = cgWindow[kCGWindowOwnerName] as? String ?? ""
let cellTitle = cgTitle.isEmpty ? cgOwnerName : cgTitle
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)
let axWindows_ = axWindows(cgOwnerPid)
// windows may have changed between the CG and the AX calls
if axWindow.count > pidAndCurrentIndex[cgOwnerPid]! {
openWindows.append(OpenWindow(target: axWindow[pidAndCurrentIndex[cgOwnerPid]!], ownerPid: cgOwnerPid, cgId: cgId, cgTitle: cgTitle))
if axWindows_.count > pidAndCurrentIndex[cgOwnerPid]! {
openWindows.append(OpenWindow(target: axWindows_[pidAndCurrentIndex[cgOwnerPid]!], ownerPid: cgOwnerPid, cgId: cgId, cgTitle: cellTitle))
}
}
}