Soniox Mobile to Mac - Real-time Voice Dictation & Remote Input Control
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

81 lines
3.1 KiB

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()