import Cocoa let app = AXUIElementCreateApplication(1668) func info(_ x: Float, _ y: Float) -> String { var el: AXUIElement? guard AXUIElementCopyElementAtPosition(app, x, y, &el) == .success, let el = el else { return "none" } func s(_ a: String) -> String { var v: CFTypeRef? if AXUIElementCopyAttributeValue(el, a as CFString, &v) == .success, let st = v as? String { return String(st.prefix(40)).replacingOccurrences(of: "\n", with: "⏎") } return "" } var nkids = "?" if var kids: CFTypeRef? = nil, AXUIElementCopyAttributeValue(el, kAXChildrenAttribute as CFString, &kids) == .success, let arr = kids as? [AnyObject] { nkids = "\(arr.count)" } return "role=\(s(kAXRoleAttribute)) val='\(s(kAXValueAttribute))' desc='\(s(kAXDescriptionAttribute))' kids=\(nkids)" } print("P(849,707) [button center]: " + info(849, 707)) print("P(1450,1211) [send btn ctrl]: " + info(1450, 1211)) print("P(600,900) [chat text ctrl]: " + info(600, 900)) print("P(400,400) [sidebar ctrl]: " + info(400, 400)) // descend into element at (849,707) to find buttons var el: AXUIElement? if AXUIElementCopyElementAtPosition(app, 849, 707, &el) == .success, let root = el { var stack: [(AXUIElement, Int)] = [(root, 0)] var seen = 0 while let (e, d) = stack.popLast(), seen < 80 { var v: CFTypeRef? var role = "" if AXUIElementCopyAttributeValue(e, kAXRoleAttribute as CFString, &v) == .success { role = (v as? String) ?? "?" } v = nil var val = "" if AXUIElementCopyAttributeValue(e, kAXValueAttribute as CFString, &v) == .success, let st = v as? String { val = String(st.prefix(30)).replacingOccurrences(of: "\n", with: "⏎") } v = nil var desc = "" if AXUIElementCopyAttributeValue(e, kAXDescriptionAttribute as CFString, &v) == .success, let st = v as? String { desc = String(st.prefix(30)).replacingOccurrences(of: "\n", with: "⏎") } print("d\(d) \(role) val='\(val)' desc='\(desc)'") seen += 1 v = nil if AXUIElementCopyAttributeValue(e, kAXChildrenAttribute as CFString, &v) == .success, let arr = v as? [AnyObject] { for k in arr.reversed() { stack.append((k as! AXUIElement, d+1)) } } } }