import Cocoa import ApplicationServices func testLiveAX() { let sysWide = AXUIElementCreateSystemWide() // Enable Chromium/Electron accessibility AXUIElementSetAttributeValue(sysWide, "AXEnhancedUserInterface" as CFString, kCFBooleanTrue) AXUIElementSetAttributeValue(sysWide, "AXManualAccessibility" as CFString, kCFBooleanTrue) guard let frontApp = NSWorkspace.shared.frontmostApplication else { print("No front app") return } print("Front App:", frontApp.localizedName ?? "", "PID:", frontApp.processIdentifier) let appElem = AXUIElementCreateApplication(frontApp.processIdentifier) AXUIElementSetAttributeValue(appElem, "AXEnhancedUserInterface" as CFString, kCFBooleanTrue) AXUIElementSetAttributeValue(appElem, "AXManualAccessibility" as CFString, kCFBooleanTrue) // Try system wide focused element var focusedUIElement: CFTypeRef? var err = AXUIElementCopyAttributeValue(sysWide, kAXFocusedUIElementAttribute as CFString, &focusedUIElement) if err != .success || focusedUIElement == nil { err = AXUIElementCopyAttributeValue(appElem, kAXFocusedUIElementAttribute as CFString, &focusedUIElement) } guard err == .success, let elem = focusedUIElement else { print("No focused element. Error:", err.rawValue) return } let axElem = elem as! AXUIElement var roleRef: CFTypeRef? AXUIElementCopyAttributeValue(axElem, kAXRoleAttribute as CFString, &roleRef) let role = (roleRef as? String) ?? "AXUnknown" print("Role:", role) // Extract text var currentText = "" var valueRef: CFTypeRef? if AXUIElementCopyAttributeValue(axElem, kAXValueAttribute as CFString, &valueRef) == .success, let val = valueRef { if let str = val as? String { currentText = str } else if let attrStr = val as? NSAttributedString { currentText = attrStr.string } } if currentText.isEmpty { var countRef: CFTypeRef? if AXUIElementCopyAttributeValue(axElem, kAXNumberOfCharactersAttribute as CFString, &countRef) == .success, let count = countRef as? Int { var range = CFRange(location: 0, length: count) if let axRange = AXValueCreate(.cfRange, &range) { var stringRef: CFTypeRef? if AXUIElementCopyParameterizedAttributeValue(axElem, kAXStringForRangeParameterizedAttribute as CFString, axRange, &stringRef) == .success, let str = stringRef as? String { currentText = str } } } } print("Extracted Text: '\(currentText)'") // Selection / Cursor var rangeRef: CFTypeRef? if AXUIElementCopyAttributeValue(axElem, kAXSelectedTextRangeAttribute as CFString, &rangeRef) == .success, let val = rangeRef { var cfRange = CFRange() if AXValueGetValue(val as! AXValue, .cfRange, &cfRange) { print("Cursor Location: \(cfRange.location), Selection Length: \(cfRange.length)") } } } testLiveAX()