Skip to content

Commit

Permalink
Merge pull request #1268 from decodism/master-2
Browse files Browse the repository at this point in the history
Filter level when getting window by location
  • Loading branch information
rxhanson authored Sep 21, 2023
2 parents 56caf63 + 21d38da commit 7e90241
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 25 deletions.
2 changes: 1 addition & 1 deletion Rectangle/AccessibilityElement.swift
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ extension AccessibilityElement {
}

private static func getWindowInfo(_ location: CGPoint) -> WindowInfo? {
let infos = WindowUtil.getWindowList().filter { !["Dock", "WindowManager"].contains($0.processName) }
let infos = WindowUtil.getWindowList().filter { $0.level < 1000 && !["Dock", "WindowManager"].contains($0.processName) }
if let info = (infos.first { $0.frame.contains(location) }) {
return info
}
Expand Down
4 changes: 0 additions & 4 deletions Rectangle/Utilities/CFExtension.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,4 @@ extension CFDictionary {
func getValue<T>(_ key: CFString) -> T {
return unsafeBitCast(CFDictionaryGetValue(self, unsafeBitCast(key, to: UnsafeRawPointer.self)), to: T.self)
}

func toRect() -> CGRect? {
return CGRect(dictionaryRepresentation: self)
}
}
52 changes: 32 additions & 20 deletions Rectangle/Utilities/WindowUtil.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,31 +11,42 @@ class WindowUtil {
private static var windowListCache = TimeoutCache<[CGWindowID]?, [WindowInfo]>(timeout: 100)

static func getWindowList(ids: [CGWindowID]? = nil, all: Bool = false) -> [WindowInfo] {
if let infos = windowListCache[ids] { return infos }
if let infos = windowListCache[ids] {
return infos
}
var infos = [WindowInfo]()
var array: CFArray?
if let ids = ids {
let ptr = UnsafeMutablePointer<UnsafeRawPointer?>.allocate(capacity: ids.count)
for i in 0..<ids.count {
ptr[i] = UnsafeRawPointer(bitPattern: UInt(ids[i]))
var rawInfos: CFArray?
if let ids {
let values = UnsafeMutablePointer<UnsafeRawPointer?>.allocate(capacity: ids.count)
for (i, id) in ids.enumerated() {
values[i] = UnsafeRawPointer(bitPattern: UInt(id))
}
let ids = CFArrayCreate(kCFAllocatorDefault, ptr, ids.count, nil)
array = CGWindowListCreateDescriptionFromArray(ids)
let rawIds = CFArrayCreate(kCFAllocatorDefault, values, ids.count, nil)
rawInfos = CGWindowListCreateDescriptionFromArray(rawIds)
} else {
array = CGWindowListCopyWindowInfo([all ? .optionAll : .optionOnScreenOnly, .excludeDesktopElements], kCGNullWindowID)
rawInfos = CGWindowListCopyWindowInfo([all ? .optionAll : .optionOnScreenOnly, .excludeDesktopElements], kCGNullWindowID)
}
if let array = array {
let count = array.getCount()
if let rawInfos {
let count = rawInfos.getCount()
for i in 0..<count {
let dictionary = array.getValue(i) as CFDictionary
let id = dictionary.getValue(kCGWindowNumber) as CFNumber
let frame = (dictionary.getValue(kCGWindowBounds) as CFDictionary).toRect()
let pid = dictionary.getValue(kCGWindowOwnerPID) as CFNumber
let processName = dictionary.getValue(kCGWindowOwnerName) as CFString
if let frame = frame {
let info = WindowInfo(id: CGWindowID(truncating: id), frame: frame, pid: pid_t(truncating: pid), processName: String(processName))
infos.append(info)
let rawInfo = rawInfos.getValue(i) as CFDictionary
let rawId = rawInfo.getValue(kCGWindowNumber) as CFNumber
let rawLevel = rawInfo.getValue(kCGWindowLayer) as CFNumber
let rawFrame = rawInfo.getValue(kCGWindowBounds) as CFDictionary
let rawPid = rawInfo.getValue(kCGWindowOwnerPID) as CFNumber
let rawProcessName = rawInfo.getValue(kCGWindowOwnerName) as CFString?
let id = CGWindowID(truncating: rawId)
let level = CGWindowLevel(truncating: rawLevel)
guard let frame = CGRect(dictionaryRepresentation: rawFrame) else {
continue
}
let pid = pid_t(truncating: rawPid)
var processName: String?
if let rawProcessName {
processName = String(rawProcessName)
}
let info = WindowInfo(id: id, level: level, frame: frame, pid: pid, processName: processName)
infos.append(info)
}
}
windowListCache[ids] = infos
Expand All @@ -45,7 +56,8 @@ class WindowUtil {

struct WindowInfo {
let id: CGWindowID
let level: CGWindowLevel
let frame: CGRect
let pid: pid_t
let processName: String
let processName: String?
}

0 comments on commit 7e90241

Please sign in to comment.