From e7d61e9adc4b6887cec26ab34c03101df24c27c2 Mon Sep 17 00:00:00 2001 From: Michael Redig Date: Thu, 12 Jun 2025 21:47:24 -0500 Subject: [PATCH 01/39] (bump) swift version --- Package.swift | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Package.swift b/Package.swift index 112f472..a1800b3 100644 --- a/Package.swift +++ b/Package.swift @@ -1,9 +1,12 @@ -// swift-tools-version:4.0 +// swift-tools-version:5.10 import PackageDescription let package = Package( name: "AXSwift", + platforms: [ + .macOS(.v10_15) + ], products: [ .library( name: "AXSwift", From 24525c37944292b9b339b7dd02ab00ae1b30fdd1 Mon Sep 17 00:00:00 2001 From: Michael Redig Date: Thu, 12 Jun 2025 21:47:48 -0500 Subject: [PATCH 02/39] (refactor) typed throws --- Sources/Application.swift | 2 +- Sources/SystemWideElement.swift | 2 +- Sources/UIElement.swift | 80 +++++++++++++++++---------------- 3 files changed, 43 insertions(+), 41 deletions(-) diff --git a/Sources/Application.swift b/Sources/Application.swift index 65a68e0..7368ef9 100644 --- a/Sources/Application.swift +++ b/Sources/Application.swift @@ -81,7 +81,7 @@ public final class Application: UIElement { } /// Returns the element at the specified top-down coordinates, or nil if there is none. - public override func elementAtPosition(_ x: Float, _ y: Float) throws -> UIElement? { + public override func elementAtPosition(_ x: Float, _ y: Float) throws(AXError) -> UIElement? { return try super.elementAtPosition(x, y) } } diff --git a/Sources/SystemWideElement.swift b/Sources/SystemWideElement.swift index cc0e80c..85512f8 100644 --- a/Sources/SystemWideElement.swift +++ b/Sources/SystemWideElement.swift @@ -12,7 +12,7 @@ open class SystemWideElement: UIElement { } /// Returns the element at the specified top-down coordinates, or nil if there is none. - open override func elementAtPosition(_ x: Float, _ y: Float) throws -> UIElement? { + open override func elementAtPosition(_ x: Float, _ y: Float) throws(AXError) -> UIElement? { return try super.elementAtPosition(x, y) } } diff --git a/Sources/UIElement.swift b/Sources/UIElement.swift index 6a34ddc..c3a548b 100644 --- a/Sources/UIElement.swift +++ b/Sources/UIElement.swift @@ -76,7 +76,7 @@ open class UIElement { /// Returns the list of all attributes. /// /// Does not include parameterized attributes. - open func attributes() throws -> [Attribute] { + open func attributes() throws(AXError) -> [Attribute] { let attrs = try attributesAsStrings() for attr in attrs where Attribute(rawValue: attr) == nil { print("Unrecognized attribute: \(attr)") @@ -86,7 +86,7 @@ open class UIElement { // This version is named differently so the caller doesn't have to specify the return type when // using the enum version. - open func attributesAsStrings() throws -> [String] { + open func attributesAsStrings() throws(AXError) -> [String] { var names: CFArray? let error = AXUIElementCopyAttributeNames(element, &names) @@ -109,11 +109,11 @@ open class UIElement { /// which is more convenient than dealing with exceptions (which are used for more serious /// errors). However, if you'd like to specifically test an attribute is actually supported, you /// can use this method. - open func attributeIsSupported(_ attribute: Attribute) throws -> Bool { + open func attributeIsSupported(_ attribute: Attribute) throws(AXError) -> Bool { return try attributeIsSupported(attribute.rawValue) } - open func attributeIsSupported(_ attribute: String) throws -> Bool { + open func attributeIsSupported(_ attribute: String) throws(AXError) -> Bool { // Ask to copy 0 values, since we are only interested in the return code. var value: CFArray? let error = AXUIElementCopyAttributeValues(element, attribute as CFString, 0, 0, &value) @@ -134,11 +134,11 @@ open class UIElement { } /// Returns whether `attribute` is writeable. - open func attributeIsSettable(_ attribute: Attribute) throws -> Bool { + open func attributeIsSettable(_ attribute: Attribute) throws(AXError) -> Bool { return try attributeIsSettable(attribute.rawValue) } - open func attributeIsSettable(_ attribute: String) throws -> Bool { + open func attributeIsSettable(_ attribute: String) throws(AXError) -> Bool { var settable: DarwinBoolean = false let error = AXUIElementIsAttributeSettable(element, attribute as CFString, &settable) @@ -162,11 +162,11 @@ open class UIElement { /// /// - warning: This method force-casts the attribute to the desired type, which will abort if /// the cast fails. If you want to check the return type, ask for Any. - open func attribute(_ attribute: Attribute) throws -> T? { + open func attribute(_ attribute: Attribute) throws(AXError) -> T? { return try self.attribute(attribute.rawValue) } - open func attribute(_ attribute: String) throws -> T? { + open func attribute(_ attribute: String) throws(AXError) -> T? { var value: AnyObject? let error = AXUIElementCopyAttributeValue(element, attribute as CFString, &value) @@ -187,17 +187,17 @@ open class UIElement { /// Sets the value of `attribute` to `value`. /// - /// - warning: Unlike read-only methods, this method throws if the attribute doesn't exist. + /// - warning: Unlike read-only methods, this method throws(AXError) if the attribute doesn't exist. /// /// - throws: /// - `Error.AttributeUnsupported`: `attribute` isn't supported. /// - `Error.IllegalArgument`: `value` is an illegal value. /// - `Error.Failure`: A temporary failure occurred. - open func setAttribute(_ attribute: Attribute, value: Any) throws { + open func setAttribute(_ attribute: Attribute, value: Any) throws(AXError) { try setAttribute(attribute.rawValue, value: value) } - open func setAttribute(_ attribute: String, value: Any) throws { + open func setAttribute(_ attribute: String, value: Any) throws(AXError) { let error = AXUIElementSetAttributeValue(element, attribute as CFString, packAXValue(value)) guard error == .success else { @@ -217,22 +217,22 @@ open class UIElement { /// /// - note: Presumably you would use this API for performance, though it's not explicitly /// documented by Apple that there is actually a difference. - open func getMultipleAttributes(_ names: Attribute...) throws -> [Attribute: Any] { + open func getMultipleAttributes(_ names: Attribute...) throws(AXError) -> [Attribute: Any] { return try getMultipleAttributes(names) } - open func getMultipleAttributes(_ attributes: [Attribute]) throws -> [Attribute: Any] { + open func getMultipleAttributes(_ attributes: [Attribute]) throws(AXError) -> [Attribute: Any] { let values = try fetchMultiAttrValues(attributes.map({ $0.rawValue })) return try packMultiAttrValues(attributes, values: values) } - open func getMultipleAttributes(_ attributes: [String]) throws -> [String: Any] { + open func getMultipleAttributes(_ attributes: [String]) throws(AXError) -> [String: Any] { let values = try fetchMultiAttrValues(attributes) return try packMultiAttrValues(attributes, values: values) } // Helper: Gets list of values - fileprivate func fetchMultiAttrValues(_ attributes: [String]) throws -> [AnyObject] { + fileprivate func fetchMultiAttrValues(_ attributes: [String]) throws(AXError) -> [AnyObject] { var valuesCF: CFArray? let error = AXUIElementCopyMultipleAttributeValues( element, @@ -249,8 +249,10 @@ open class UIElement { } // Helper: Packs names, values into dictionary - fileprivate func packMultiAttrValues(_ attributes: [Attr], - values: [AnyObject]) throws -> [Attr: Any] { + fileprivate func packMultiAttrValues( + _ attributes: [Attr], + values: [AnyObject] + ) throws(AXError) -> [Attr: Any] { var result = [Attr: Any]() for (index, attribute) in attributes.enumerated() { if try checkMultiAttrValue(values[index]) { @@ -261,7 +263,7 @@ open class UIElement { } // Helper: Checks if value is present and not an error (throws on nontrivial errors). - fileprivate func checkMultiAttrValue(_ value: AnyObject) throws -> Bool { + fileprivate func checkMultiAttrValue(_ value: AnyObject) throws(AXError) -> Bool { // Check for null if value is NSNull { return false @@ -291,11 +293,11 @@ open class UIElement { /// - parameter attribute: The name of the array attribute. /// /// - throws: `Error.IllegalArgument` if the attribute isn't an array. - open func arrayAttribute(_ attribute: Attribute) throws -> [T]? { + open func arrayAttribute(_ attribute: Attribute) throws(AXError) -> [T]? { return try arrayAttribute(attribute.rawValue) } - open func arrayAttribute(_ attribute: String) throws -> [T]? { + open func arrayAttribute(_ attribute: String) throws(AXError) -> [T]? { guard let value: Any = try self.attribute(attribute) else { return nil } @@ -318,12 +320,12 @@ open class UIElement { /// /// - throws: `Error.IllegalArgument` if the attribute isn't an array. open func valuesForAttribute - (_ attribute: Attribute, startAtIndex index: Int, maxValues: Int) throws -> [T]? { + (_ attribute: Attribute, startAtIndex index: Int, maxValues: Int) throws(AXError) -> [T]? { return try valuesForAttribute(attribute.rawValue, startAtIndex: index, maxValues: maxValues) } open func valuesForAttribute - (_ attribute: String, startAtIndex index: Int, maxValues: Int) throws -> [T]? { + (_ attribute: String, startAtIndex index: Int, maxValues: Int) throws(AXError) -> [T]? { var values: CFArray? let error = AXUIElementCopyAttributeValues( element, attribute as CFString, index, maxValues, &values @@ -343,11 +345,11 @@ open class UIElement { /// Returns the number of values an array attribute has. /// - returns: The number of values, or `nil` if `attribute` isn't an array (or doesn't exist). - open func valueCountForAttribute(_ attribute: Attribute) throws -> Int? { + open func valueCountForAttribute(_ attribute: Attribute) throws(AXError) -> Int? { return try valueCountForAttribute(attribute.rawValue) } - open func valueCountForAttribute(_ attribute: String) throws -> Int? { + open func valueCountForAttribute(_ attribute: String) throws(AXError) -> Int? { var count: Int = 0 let error = AXUIElementGetAttributeValueCount(element, attribute as CFString, &count) @@ -368,11 +370,11 @@ open class UIElement { /// /// Parameterized attributes are attributes that require parameters to retrieve. For example, /// the cell contents of a spreadsheet might require the row and column of the cell you want. - open func parameterizedAttributes() throws -> [Attribute] { + open func parameterizedAttributes() throws(AXError) -> [Attribute] { return try parameterizedAttributesAsStrings().compactMap({ Attribute(rawValue: $0) }) } - open func parameterizedAttributesAsStrings() throws -> [String] { + open func parameterizedAttributesAsStrings() throws(AXError) -> [String] { var names: CFArray? let error = AXUIElementCopyParameterizedAttributeNames(element, &names) @@ -394,11 +396,11 @@ open class UIElement { /// The expected type of `param` depends on the attribute. See the /// [NSAccessibility Informal Protocol Reference](https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Protocols/NSAccessibility_Protocol/) /// for more info. - open func parameterizedAttribute(_ attribute: Attribute, param: U) throws -> T? { + open func parameterizedAttribute(_ attribute: Attribute, param: U) throws(AXError) -> T? { return try parameterizedAttribute(attribute.rawValue, param: param) } - open func parameterizedAttribute(_ attribute: String, param: U) throws -> T? { + open func parameterizedAttribute(_ attribute: String, param: U) throws(AXError) -> T? { var value: AnyObject? let error = AXUIElementCopyParameterizedAttributeValue( element, attribute as CFString, param as AnyObject, &value @@ -483,11 +485,11 @@ open class UIElement { // MARK: - Actions /// Returns a list of actions that can be performed on the element. - open func actions() throws -> [Action] { + open func actions() throws(AXError) -> [Action] { return try actionsAsStrings().compactMap({ Action(rawValue: $0) }) } - open func actionsAsStrings() throws -> [String] { + open func actionsAsStrings() throws(AXError) -> [String] { var names: CFArray? let error = AXUIElementCopyActionNames(element, &names) @@ -504,11 +506,11 @@ open class UIElement { } /// Returns the human-readable description of `action`. - open func actionDescription(_ action: Action) throws -> String? { + open func actionDescription(_ action: Action) throws(AXError) -> String? { return try actionDescription(action.rawValue) } - open func actionDescription(_ action: String) throws -> String? { + open func actionDescription(_ action: String) throws(AXError) -> String? { var description: CFString? let error = AXUIElementCopyActionDescription(element, action as CFString, &description) @@ -529,11 +531,11 @@ open class UIElement { /// actually perform the action. It doesn't necessarily mean that the action wasn't /// performed. /// - throws: `Error.ActionUnsupported` if the action is not supported. - open func performAction(_ action: Action) throws { + open func performAction(_ action: Action) throws(AXError) { try performAction(action.rawValue) } - open func performAction(_ action: String) throws { + open func performAction(_ action: String) throws(AXError) { let error = AXUIElementPerformAction(element, action as CFString) guard error == .success else { @@ -545,8 +547,8 @@ open class UIElement { /// Returns the process ID of the application that the element is a part of. /// - /// Throws only if the element is invalid (`Errors.InvalidUIElement`). - open func pid() throws -> pid_t { + /// throws(AXError) only if the element is invalid (`Errors.InvalidUIElement`). + open func pid() throws(AXError) -> pid_t { var pid: pid_t = -1 let error = AXUIElementGetPid(element, &pid) @@ -578,7 +580,7 @@ open class UIElement { // Gets the element at the specified coordinates. // This can only be called on applications and the system-wide element, so it is internal here. - func elementAtPosition(_ x: Float, _ y: Float) throws -> UIElement? { + func elementAtPosition(_ x: Float, _ y: Float) throws(AXError) -> UIElement? { var result: AXUIElement? let error = AXUIElementCopyElementAtPosition(element, x, y, &result) @@ -658,7 +660,7 @@ extension UIElement { /// finished initializing. /// /// - seeAlso: [Roles](https://developer.apple.com/library/mac/documentation/AppKit/Reference/NSAccessibility_Protocol_Reference/index.html#//apple_ref/doc/constant_group/Roles) - public func role() throws -> Role? { + public func role() throws(AXError) -> Role? { // should this be non-optional? if let str: String = try self.attribute(.role) { return Role(rawValue: str) @@ -668,7 +670,7 @@ extension UIElement { } /// - seeAlso: [Subroles](https://developer.apple.com/library/mac/documentation/AppKit/Reference/NSAccessibility_Protocol_Reference/index.html#//apple_ref/doc/constant_group/Subroles) - public func subrole() throws -> Subrole? { + public func subrole() throws(AXError) -> Subrole? { if let str: String = try self.attribute(.subrole) { return Subrole(rawValue: str) } else { From a3b109616e0e60832633e83cdc446383d282fd7c Mon Sep 17 00:00:00 2001 From: Michael Redig Date: Thu, 12 Jun 2025 21:48:02 -0500 Subject: [PATCH 03/39] (feat) UIElement hashable --- Sources/UIElement.swift | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Sources/UIElement.swift b/Sources/UIElement.swift index c3a548b..fdd065f 100644 --- a/Sources/UIElement.swift +++ b/Sources/UIElement.swift @@ -651,6 +651,13 @@ public func ==(lhs: UIElement, rhs: UIElement) -> Bool { return CFEqual(lhs.element, rhs.element) } +extension UIElement: Hashable { + public func hash(into hasher: inout Hasher) { + let hashCode = CFHash(self) + hasher.combine(hashCode) + } +} + // MARK: - Convenience getters extension UIElement { From cbb4772dcc0a7954f7de63651e8ab1a5bc70a4e1 Mon Sep 17 00:00:00 2001 From: Michael Redig Date: Thu, 12 Jun 2025 21:50:00 -0500 Subject: [PATCH 04/39] (nit) mark retroactive --- Sources/Error.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/Error.swift b/Sources/Error.swift index 1be2d31..26f0010 100644 --- a/Sources/Error.swift +++ b/Sources/Error.swift @@ -4,7 +4,7 @@ import Cocoa extension AXError: Swift.Error {} // For some reason values don't get described in this enum, so we have to do it manually. -extension AXError: CustomStringConvertible { +extension AXError: @retroactive CustomStringConvertible { fileprivate var valueAsString: String { switch self { case .success: From 0b6f36b156827c7cd99193d3239ae02f0b99a48e Mon Sep 17 00:00:00 2001 From: Michael Redig Date: Sat, 14 Jun 2025 15:20:30 -0500 Subject: [PATCH 05/39] (refactor) change most enums to RawRep structs locate in UIElement namespace and make deprecated typealiases available --- Sources/Constants.swift | 408 ------------------------- Sources/Constants/AXNotification.swift | 79 +++++ Sources/Constants/Action.swift | 28 ++ Sources/Constants/Attribute.swift | 236 ++++++++++++++ Sources/Constants/Orientation.swift | 13 + Sources/Constants/Role.swift | 72 +++++ Sources/Constants/Subrole.swift | 46 +++ Sources/Observer.swift | 26 +- Sources/UIElement.swift | 4 +- 9 files changed, 490 insertions(+), 422 deletions(-) delete mode 100644 Sources/Constants.swift create mode 100644 Sources/Constants/AXNotification.swift create mode 100644 Sources/Constants/Action.swift create mode 100644 Sources/Constants/Attribute.swift create mode 100644 Sources/Constants/Orientation.swift create mode 100644 Sources/Constants/Role.swift create mode 100644 Sources/Constants/Subrole.swift diff --git a/Sources/Constants.swift b/Sources/Constants.swift deleted file mode 100644 index 1fd8d7e..0000000 --- a/Sources/Constants.swift +++ /dev/null @@ -1,408 +0,0 @@ -/// All possible notifications you can subscribe to with `Observer`. -/// - seeAlso: [Notificatons](https://developer.apple.com/library/mac/documentation/AppKit/Reference/NSAccessibility_Protocol_Reference/index.html#//apple_ref/c/data/NSAccessibilityAnnouncementRequestedNotification) -public enum AXNotification: String { - // Focus notifications - case mainWindowChanged = "AXMainWindowChanged" - case focusedWindowChanged = "AXFocusedWindowChanged" - case focusedUIElementChanged = "AXFocusedUIElementChanged" - case focusedTabChanged = "AXFocusedTabChanged" - - // Application notifications - case applicationActivated = "AXApplicationActivated" - case applicationDeactivated = "AXApplicationDeactivated" - case applicationHidden = "AXApplicationHidden" - case applicationShown = "AXApplicationShown" - - // Window notifications - case windowCreated = "AXWindowCreated" - case windowMoved = "AXWindowMoved" - case windowResized = "AXWindowResized" - case windowMiniaturized = "AXWindowMiniaturized" - case windowDeminiaturized = "AXWindowDeminiaturized" - - // Drawer & sheet notifications - case drawerCreated = "AXDrawerCreated" - case sheetCreated = "AXSheetCreated" - - // Element notifications - case uiElementDestroyed = "AXUIElementDestroyed" - case valueChanged = "AXValueChanged" - case titleChanged = "AXTitleChanged" - case resized = "AXResized" - case moved = "AXMoved" - case created = "AXCreated" - - // Used when UI changes require the attention of assistive application. Pass along a user info - // dictionary with the key NSAccessibilityUIElementsKey and an array of elements that have been - // added or changed as a result of this layout change. - case layoutChanged = "AXLayoutChanged" - - // Misc notifications - case helpTagCreated = "AXHelpTagCreated" - case selectedTextChanged = "AXSelectedTextChanged" - case rowCountChanged = "AXRowCountChanged" - case selectedChildrenChanged = "AXSelectedChildrenChanged" - case selectedRowsChanged = "AXSelectedRowsChanged" - case selectedColumnsChanged = "AXSelectedColumnsChanged" - case loadComplete = "AXLoadComplete" - - case rowExpanded = "AXRowExpanded" - case rowCollapsed = "AXRowCollapsed" - - // Cell-table notifications - case selectedCellsChanged = "AXSelectedCellsChanged" - - // Layout area notifications - case unitsChanged = "AXUnitsChanged" - case selectedChildrenMoved = "AXSelectedChildrenMoved" - - // This notification allows an application to request that an announcement be made to the user - // by an assistive application such as VoiceOver. The notification requires a user info - // dictionary with the key NSAccessibilityAnnouncementKey and the announcement as a localized - // string. In addition, the key NSAccessibilityAnnouncementPriorityKey should also be used to - // help an assistive application determine the importance of this announcement. This - // notification should be posted for the application element. - case announcementRequested = "AXAnnouncementRequested" -} - -/// All UIElement roles. -/// - seeAlso: [Roles](https://developer.apple.com/library/mac/documentation/AppKit/Reference/NSAccessibility_Protocol_Reference/index.html#//apple_ref/doc/constant_group/Roles) -public enum Role: String { - case unknown = "AXUnknown" - case button = "AXButton" - case radioButton = "AXRadioButton" - case checkBox = "AXCheckBox" - case slider = "AXSlider" - case tabGroup = "AXTabGroup" - case textField = "AXTextField" - case staticText = "AXStaticText" - case textArea = "AXTextArea" - case scrollArea = "AXScrollArea" - case popUpButton = "AXPopUpButton" - case menuButton = "AXMenuButton" - case table = "AXTable" - case application = "AXApplication" - case group = "AXGroup" - case radioGroup = "AXRadioGroup" - case list = "AXList" - case scrollBar = "AXScrollBar" - case valueIndicator = "AXValueIndicator" - case image = "AXImage" - case menuBar = "AXMenuBar" - case menu = "AXMenu" - case menuItem = "AXMenuItem" - case menuBarItem = "AXMenuBarItem" - case column = "AXColumn" - case row = "AXRow" - case toolbar = "AXToolbar" - case busyIndicator = "AXBusyIndicator" - case progressIndicator = "AXProgressIndicator" - case window = "AXWindow" - case drawer = "AXDrawer" - case systemWide = "AXSystemWide" - case outline = "AXOutline" - case incrementor = "AXIncrementor" - case browser = "AXBrowser" - case comboBox = "AXComboBox" - case splitGroup = "AXSplitGroup" - case splitter = "AXSplitter" - case colorWell = "AXColorWell" - case growArea = "AXGrowArea" - case sheet = "AXSheet" - case helpTag = "AXHelpTag" - case matte = "AXMatte" - case ruler = "AXRuler" - case rulerMarker = "AXRulerMarker" - case link = "AXLink" - case disclosureTriangle = "AXDisclosureTriangle" - case grid = "AXGrid" - case relevanceIndicator = "AXRelevanceIndicator" - case levelIndicator = "AXLevelIndicator" - case cell = "AXCell" - case popover = "AXPopover" - case layoutArea = "AXLayoutArea" - case layoutItem = "AXLayoutItem" - case handle = "AXHandle" -} - -/// All UIElement subroles. -/// - seeAlso: [Subroles](https://developer.apple.com/library/mac/documentation/AppKit/Reference/NSAccessibility_Protocol_Reference/index.html#//apple_ref/doc/constant_group/Subroles) -public enum Subrole: String { - case unknown = "AXUnknown" - case closeButton = "AXCloseButton" - case zoomButton = "AXZoomButton" - case minimizeButton = "AXMinimizeButton" - case toolbarButton = "AXToolbarButton" - case tableRow = "AXTableRow" - case outlineRow = "AXOutlineRow" - case secureTextField = "AXSecureTextField" - case standardWindow = "AXStandardWindow" - case dialog = "AXDialog" - case systemDialog = "AXSystemDialog" - case floatingWindow = "AXFloatingWindow" - case systemFloatingWindow = "AXSystemFloatingWindow" - case incrementArrow = "AXIncrementArrow" - case decrementArrow = "AXDecrementArrow" - case incrementPage = "AXIncrementPage" - case decrementPage = "AXDecrementPage" - case searchField = "AXSearchField" - case textAttachment = "AXTextAttachment" - case textLink = "AXTextLink" - case timeline = "AXTimeline" - case sortButton = "AXSortButton" - case ratingIndicator = "AXRatingIndicator" - case contentList = "AXContentList" - case definitionList = "AXDefinitionList" - case fullScreenButton = "AXFullScreenButton" - case toggle = "AXToggle" - case switchSubrole = "AXSwitch" - case descriptionList = "AXDescriptionList" -} - -/// Orientations returned by the orientation property. -/// - seeAlso: [NSAccessibilityOrientation](https://developer.apple.com/library/mac/documentation/AppKit/Reference/NSAccessibility_Protocol_Reference/index.html#//apple_ref/c/tdef/NSAccessibilityOrientation) -public enum Orientation: Int { - case unknown = 0 - case vertical = 1 - case horizontal = 2 -} - -public enum Attribute: String { - // Standard attributes - case role = "AXRole" //(NSString *) - type, non-localized (e.g. radioButton) - case roleDescription = "AXRoleDescription" //(NSString *) - user readable role (e.g. "radio button") - case subrole = "AXSubrole" //(NSString *) - type, non-localized (e.g. closeButton) - case help = "AXHelp" //(NSString *) - instance description (e.g. a tool tip) - case value = "AXValue" //(id) - element's value - case minValue = "AXMinValue" //(id) - element's min value - case maxValue = "AXMaxValue" //(id) - element's max value - case enabled = "AXEnabled" //(NSNumber *) - (boolValue) responds to user? - case focused = "AXFocused" //(NSNumber *) - (boolValue) has keyboard focus? - case parent = "AXParent" //(id) - element containing you - case children = "AXChildren" //(NSArray *) - elements you contain - case window = "AXWindow" //(id) - UIElement for the containing window - case topLevelUIElement = "AXTopLevelUIElement" //(id) - UIElement for the containing top level element - case selectedChildren = "AXSelectedChildren" //(NSArray *) - child elements which are selected - case visibleChildren = "AXVisibleChildren" //(NSArray *) - child elements which are visible - case position = "AXPosition" //(NSValue *) - (pointValue) position in screen coords - case size = "AXSize" //(NSValue *) - (sizeValue) size - case frame = "AXFrame" //(NSValue *) - (rectValue) frame - case contents = "AXContents" //(NSArray *) - main elements - case title = "AXTitle" //(NSString *) - visible text (e.g. of a push button) - case description = "AXDescription" //(NSString *) - instance description - case shownMenu = "AXShownMenu" //(id) - menu being displayed - case valueDescription = "AXValueDescription" //(NSString *) - text description of value - - case sharedFocusElements = "AXSharedFocusElements" //(NSArray *) - elements that share focus - - // Misc attributes - case previousContents = "AXPreviousContents" //(NSArray *) - main elements - case nextContents = "AXNextContents" //(NSArray *) - main elements - case header = "AXHeader" //(id) - UIElement for header. - case edited = "AXEdited" //(NSNumber *) - (boolValue) is it dirty? - case tabs = "AXTabs" //(NSArray *) - UIElements for tabs - case horizontalScrollBar = "AXHorizontalScrollBar" //(id) - UIElement for the horizontal scroller - case verticalScrollBar = "AXVerticalScrollBar" //(id) - UIElement for the vertical scroller - case overflowButton = "AXOverflowButton" //(id) - UIElement for overflow - case incrementButton = "AXIncrementButton" //(id) - UIElement for increment - case decrementButton = "AXDecrementButton" //(id) - UIElement for decrement - case filename = "AXFilename" //(NSString *) - filename - case expanded = "AXExpanded" //(NSNumber *) - (boolValue) is expanded? - case selected = "AXSelected" //(NSNumber *) - (boolValue) is selected? - case splitters = "AXSplitters" //(NSArray *) - UIElements for splitters - case document = "AXDocument" //(NSString *) - url as string - for open document - case activationPoint = "AXActivationPoint" //(NSValue *) - (pointValue) - - case url = "AXURL" //(NSURL *) - url - case index = "AXIndex" //(NSNumber *) - (intValue) - - case rowCount = "AXRowCount" //(NSNumber *) - (intValue) number of rows - - case columnCount = "AXColumnCount" //(NSNumber *) - (intValue) number of columns - - case orderedByRow = "AXOrderedByRow" //(NSNumber *) - (boolValue) is ordered by row? - - case warningValue = "AXWarningValue" //(id) - warning value of a level indicator, typically a number - - case criticalValue = "AXCriticalValue" //(id) - critical value of a level indicator, typically a number - - case placeholderValue = "AXPlaceholderValue" //(NSString *) - placeholder value of a control such as a text field - - case containsProtectedContent = "AXContainsProtectedContent" // (NSNumber *) - (boolValue) contains protected content? - case alternateUIVisible = "AXAlternateUIVisible" //(NSNumber *) - (boolValue) - - // Linkage attributes - case titleUIElement = "AXTitleUIElement" //(id) - UIElement for the title - case servesAsTitleForUIElements = "AXServesAsTitleForUIElements" //(NSArray *) - UIElements this titles - case linkedUIElements = "AXLinkedUIElements" //(NSArray *) - corresponding UIElements - - // Text-specific attributes - case selectedText = "AXSelectedText" //(NSString *) - selected text - case selectedTextRange = "AXSelectedTextRange" //(NSValue *) - (rangeValue) range of selected text - case numberOfCharacters = "AXNumberOfCharacters" //(NSNumber *) - number of characters - case visibleCharacterRange = "AXVisibleCharacterRange" //(NSValue *) - (rangeValue) range of visible text - case sharedTextUIElements = "AXSharedTextUIElements" //(NSArray *) - text views sharing text - case sharedCharacterRange = "AXSharedCharacterRange" //(NSValue *) - (rangeValue) part of shared text in this view - case insertionPointLineNumber = "AXInsertionPointLineNumber" //(NSNumber *) - line# containing caret - case selectedTextRanges = "AXSelectedTextRanges" //(NSArray *) - array of NSValue (rangeValue) ranges of selected text - /// - note: private/undocumented attribute - case textInputMarkedRange = "AXTextInputMarkedRange" - - // Parameterized text-specific attributes - case lineForIndexParameterized = "AXLineForIndexParameterized" //(NSNumber *) - line# for char index; param:(NSNumber *) - case rangeForLineParameterized = "AXRangeForLineParameterized" //(NSValue *) - (rangeValue) range of line; param:(NSNumber *) - case stringForRangeParameterized = "AXStringForRangeParameterized" //(NSString *) - substring; param:(NSValue * - rangeValue) - case rangeForPositionParameterized = "AXRangeForPositionParameterized" //(NSValue *) - (rangeValue) composed char range; param:(NSValue * - pointValue) - case rangeForIndexParameterized = "AXRangeForIndexParameterized" //(NSValue *) - (rangeValue) composed char range; param:(NSNumber *) - case boundsForRangeParameterized = "AXBoundsForRangeParameterized" //(NSValue *) - (rectValue) bounds of text; param:(NSValue * - rangeValue) - case rtfForRangeParameterized = "AXRTFForRangeParameterized" //(NSData *) - rtf for text; param:(NSValue * - rangeValue) - case styleRangeForIndexParameterized = "AXStyleRangeForIndexParameterized" //(NSValue *) - (rangeValue) extent of style run; param:(NSNumber *) - case attributedStringForRangeParameterized = "AXAttributedStringForRangeParameterized" //(NSAttributedString *) - does _not_ use attributes from Appkit/AttributedString.h - - // Text attributed string attributes and constants - case fontText = "AXFontText" //(NSDictionary *) - NSAccessibilityFontXXXKey's - case foregroundColorText = "AXForegroundColorText" //CGColorRef - case backgroundColorText = "AXBackgroundColorText" //CGColorRef - case underlineColorText = "AXUnderlineColorText" //CGColorRef - case strikethroughColorText = "AXStrikethroughColorText" //CGColorRef - case underlineText = "AXUnderlineText" //(NSNumber *) - underline style - case superscriptText = "AXSuperscriptText" //(NSNumber *) - superscript>0, subscript<0 - case strikethroughText = "AXStrikethroughText" //(NSNumber *) - (boolValue) - case shadowText = "AXShadowText" //(NSNumber *) - (boolValue) - case attachmentText = "AXAttachmentText" //id - corresponding element - case linkText = "AXLinkText" //id - corresponding element - case autocorrectedText = "AXAutocorrectedText" //(NSNumber *) - (boolValue) - - // Textual list attributes and constants. Examples: unordered or ordered lists in a document. - case listItemPrefixText = "AXListItemPrefixText" // NSAttributedString, the prepended string of the list item. If the string is a common unicode character (e.g. a bullet •), return that unicode character. For lists with images before the text, return a reasonable label of the image. - case listItemIndexText = "AXListItemIndexText" // NSNumber, integerValue of the line index. Each list item increments the index, even for unordered lists. The first item should have index 0. - case listItemLevelText = "AXListItemLevelText" // NSNumber, integerValue of the indent level. Each sublist increments the level. The first item should have level 0. - - // MisspelledText attributes - case misspelledText = "AXMisspelledText" //(NSNumber *) - (boolValue) - case markedMisspelledText = "AXMarkedMisspelledText" //(NSNumber *) - (boolValue) - - // Window-specific attributes - case main = "AXMain" //(NSNumber *) - (boolValue) is it the main window? - case minimized = "AXMinimized" //(NSNumber *) - (boolValue) is window minimized? - case closeButton = "AXCloseButton" //(id) - UIElement for close box (or nil) - case zoomButton = "AXZoomButton" //(id) - UIElement for zoom box (or nil) - case minimizeButton = "AXMinimizeButton" //(id) - UIElement for miniaturize box (or nil) - case toolbarButton = "AXToolbarButton" //(id) - UIElement for toolbar box (or nil) - case proxy = "AXProxy" //(id) - UIElement for title's icon (or nil) - case growArea = "AXGrowArea" //(id) - UIElement for grow box (or nil) - case modal = "AXModal" //(NSNumber *) - (boolValue) is the window modal - case defaultButton = "AXDefaultButton" //(id) - UIElement for default button - case cancelButton = "AXCancelButton" //(id) - UIElement for cancel button - case fullScreenButton = "AXFullScreenButton" //(id) - UIElement for full screen button (or nil) - /// - note: private/undocumented attribute - case fullScreen = "AXFullScreen" //(NSNumber *) - (boolValue) is the window fullscreen - - // Application-specific attributes - case menuBar = "AXMenuBar" //(id) - UIElement for the menu bar - case windows = "AXWindows" //(NSArray *) - UIElements for the windows - case frontmost = "AXFrontmost" //(NSNumber *) - (boolValue) is the app active? - case hidden = "AXHidden" //(NSNumber *) - (boolValue) is the app hidden? - case mainWindow = "AXMainWindow" //(id) - UIElement for the main window. - case focusedWindow = "AXFocusedWindow" //(id) - UIElement for the key window. - case focusedUIElement = "AXFocusedUIElement" //(id) - Currently focused UIElement. - case extrasMenuBar = "AXExtrasMenuBar" //(id) - UIElement for the application extras menu bar. - /// - note: private/undocumented attribute - case enhancedUserInterface = "AXEnhancedUserInterface" //(NSNumber *) - (boolValue) is the enhanced user interface active? - - case orientation = "AXOrientation" //(NSString *) - NSAccessibilityXXXOrientationValue - - case columnTitles = "AXColumnTitles" //(NSArray *) - UIElements for titles - - case searchButton = "AXSearchButton" //(id) - UIElement for search field search btn - case searchMenu = "AXSearchMenu" //(id) - UIElement for search field menu - case clearButton = "AXClearButton" //(id) - UIElement for search field clear btn - - // Table/outline view attributes - case rows = "AXRows" //(NSArray *) - UIElements for rows - case visibleRows = "AXVisibleRows" //(NSArray *) - UIElements for visible rows - case selectedRows = "AXSelectedRows" //(NSArray *) - UIElements for selected rows - case columns = "AXColumns" //(NSArray *) - UIElements for columns - case visibleColumns = "AXVisibleColumns" //(NSArray *) - UIElements for visible columns - case selectedColumns = "AXSelectedColumns" //(NSArray *) - UIElements for selected columns - case sortDirection = "AXSortDirection" //(NSString *) - see sort direction values below - - // Cell-based table attributes - case selectedCells = "AXSelectedCells" //(NSArray *) - UIElements for selected cells - case visibleCells = "AXVisibleCells" //(NSArray *) - UIElements for visible cells - case rowHeaderUIElements = "AXRowHeaderUIElements" //(NSArray *) - UIElements for row headers - case columnHeaderUIElements = "AXColumnHeaderUIElements" //(NSArray *) - UIElements for column headers - - // Cell-based table parameterized attributes. The parameter for this attribute is an NSArray containing two NSNumbers, the first NSNumber specifies the column index, the second NSNumber specifies the row index. - case cellForColumnAndRowParameterized = "AXCellForColumnAndRowParameterized" // (id) - UIElement for cell at specified row and column - - // Cell attributes. The index range contains both the starting index, and the index span in a table. - case rowIndexRange = "AXRowIndexRange" //(NSValue *) - (rangeValue) location and row span - case columnIndexRange = "AXColumnIndexRange" //(NSValue *) - (rangeValue) location and column span - - // Layout area attributes - case horizontalUnits = "AXHorizontalUnits" //(NSString *) - see ruler unit values below - case verticalUnits = "AXVerticalUnits" //(NSString *) - see ruler unit values below - case horizontalUnitDescription = "AXHorizontalUnitDescription" //(NSString *) - case verticalUnitDescription = "AXVerticalUnitDescription" //(NSString *) - - // Layout area parameterized attributes - case layoutPointForScreenPointParameterized = "AXLayoutPointForScreenPointParameterized" //(NSValue *) - (pointValue); param:(NSValue * - pointValue) - case layoutSizeForScreenSizeParameterized = "AXLayoutSizeForScreenSizeParameterized" //(NSValue *) - (sizeValue); param:(NSValue * - sizeValue) - case screenPointForLayoutPointParameterized = "AXScreenPointForLayoutPointParameterized" //(NSValue *) - (pointValue); param:(NSValue * - pointValue) - case screenSizeForLayoutSizeParameterized = "AXScreenSizeForLayoutSizeParameterized" //(NSValue *) - (sizeValue); param:(NSValue * - sizeValue) - - // Layout item attributes - case handles = "AXHandles" //(NSArray *) - UIElements for handles - - // Outline attributes - case disclosing = "AXDisclosing" //(NSNumber *) - (boolValue) is disclosing rows? - case disclosedRows = "AXDisclosedRows" //(NSArray *) - UIElements for disclosed rows - case disclosedByRow = "AXDisclosedByRow" //(id) - UIElement for disclosing row - case disclosureLevel = "AXDisclosureLevel" //(NSNumber *) - indentation level - - // Slider attributes - case allowedValues = "AXAllowedValues" //(NSArray *) - array of allowed values - case labelUIElements = "AXLabelUIElements" //(NSArray *) - array of label UIElements - case labelValue = "AXLabelValue" //(NSNumber *) - value of a label UIElement - - // Matte attributes - // Attributes no longer supported - case matteHole = "AXMatteHole" //(NSValue *) - (rect value) bounds of matte hole in screen coords - case matteContentUIElement = "AXMatteContentUIElement" //(id) - UIElement clipped by the matte - - // Ruler view attributes - case markerUIElements = "AXMarkerUIElements" //(NSArray *) - case markerValues = "AXMarkerValues" // - case markerGroupUIElement = "AXMarkerGroupUIElement" //(id) - case units = "AXUnits" //(NSString *) - see ruler unit values below - case unitDescription = "AXUnitDescription" //(NSString *) - case markerType = "AXMarkerType" //(NSString *) - see ruler marker type values below - case markerTypeDescription = "AXMarkerTypeDescription" //(NSString *) - - // UI element identification attributes - case identifier = "AXIdentifier" //(NSString *) - - // System-wide attributes - case focusedApplication = "AXFocusedApplication" - - // Unknown attributes - case functionRowTopLevelElements = "AXFunctionRowTopLevelElements" - case childrenInNavigationOrder = "AXChildrenInNavigationOrder" -} - -/// All actions a `UIElement` can support. -/// - seeAlso: [Actions](https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Protocols/NSAccessibility_Protocol/#//apple_ref/doc/constant_group/Actions) -public enum Action: String { - case press = "AXPress" - case increment = "AXIncrement" - case decrement = "AXDecrement" - case confirm = "AXConfirm" - case pick = "AXPick" - case cancel = "AXCancel" - case raise = "AXRaise" - case showMenu = "AXShowMenu" - case delete = "AXDelete" - case showAlternateUI = "AXShowAlternateUI" - case showDefaultUI = "AXShowDefaultUI" -} diff --git a/Sources/Constants/AXNotification.swift b/Sources/Constants/AXNotification.swift new file mode 100644 index 0000000..362dd49 --- /dev/null +++ b/Sources/Constants/AXNotification.swift @@ -0,0 +1,79 @@ +import Foundation + +@available(*, deprecated, renamed: "UIElement.AXNotification", message: "Provided for drop in replacement, but now the type is located under the `UIElement` namespace.") +public typealias AXNotification = UIElement.AXNotification +extension UIElement { + /// Provides all known possible notifications you can subscribe to with `Observer`. + /// - seeAlso: [Notificatons](https://developer.apple.com/library/mac/documentation/AppKit/Reference/NSAccessibility_Protocol_Reference/index.html#//apple_ref/c/data/NSAccessibilityAnnouncementRequestedNotification) + public struct AXNotification: RawRepresentable, Hashable, Sendable { + public let rawValue: String + public var rawCFStringValue: CFString { rawValue as CFString } + + public init(rawValue: String) { + self.rawValue = rawValue + } + + // Focus notifications + public static let mainWindowChanged = AXNotification(rawValue: "AXMainWindowChanged") + public static let focusedWindowChanged = AXNotification(rawValue: "AXFocusedWindowChanged") + public static let focusedUIElementChanged = AXNotification(rawValue: "AXFocusedUIElementChanged") + public static let focusedTabChanged = AXNotification(rawValue: "AXFocusedTabChanged") + + // Application notifications + public static let applicationActivated = AXNotification(rawValue: "AXApplicationActivated") + public static let applicationDeactivated = AXNotification(rawValue: "AXApplicationDeactivated") + public static let applicationHidden = AXNotification(rawValue: "AXApplicationHidden") + public static let applicationShown = AXNotification(rawValue: "AXApplicationShown") + + // Window notifications + public static let windowCreated = AXNotification(rawValue: "AXWindowCreated") + public static let windowMoved = AXNotification(rawValue: "AXWindowMoved") + public static let windowResized = AXNotification(rawValue: "AXWindowResized") + public static let windowMiniaturized = AXNotification(rawValue: "AXWindowMiniaturized") + public static let windowDeminiaturized = AXNotification(rawValue: "AXWindowDeminiaturized") + + // Drawer & sheet notifications + public static let drawerCreated = AXNotification(rawValue: "AXDrawerCreated") + public static let sheetCreated = AXNotification(rawValue: "AXSheetCreated") + + // Element notifications + public static let uiElementDestroyed = AXNotification(rawValue: "AXUIElementDestroyed") + public static let valueChanged = AXNotification(rawValue: "AXValueChanged") + public static let titleChanged = AXNotification(rawValue: "AXTitleChanged") + public static let resized = AXNotification(rawValue: "AXResized") + public static let moved = AXNotification(rawValue: "AXMoved") + public static let created = AXNotification(rawValue: "AXCreated") + + // Used when UI changes require the attention of assistive application. Pass along a user info + // dictionary with the key NSAccessibilityUIElementsKey and an array of elements that have been + // added or changed as a result of this layout change. + public static let layoutChanged = AXNotification(rawValue: "AXLayoutChanged") + + // Misc notifications + public static let helpTagCreated = AXNotification(rawValue: "AXHelpTagCreated") + public static let selectedTextChanged = AXNotification(rawValue: "AXSelectedTextChanged") + public static let rowCountChanged = AXNotification(rawValue: "AXRowCountChanged") + public static let selectedChildrenChanged = AXNotification(rawValue: "AXSelectedChildrenChanged") + public static let selectedRowsChanged = AXNotification(rawValue: "AXSelectedRowsChanged") + public static let selectedColumnsChanged = AXNotification(rawValue: "AXSelectedColumnsChanged") + public static let loadComplete = AXNotification(rawValue: "AXLoadComplete") + + public static let rowExpanded = AXNotification(rawValue: "AXRowExpanded") + public static let rowCollapsed = AXNotification(rawValue: "AXRowCollapsed") + + // Cell-table notifications + public static let selectedCellsChanged = AXNotification(rawValue: "AXSelectedCellsChanged") + + // Layout area notifications + public static let unitsChanged = AXNotification(rawValue: "AXUnitsChanged") + public static let selectedChildrenMoved = AXNotification(rawValue: "AXSelectedChildrenMoved") + + // This notification allows an application to request that an announcement be made to the user + // by an assistive application such as VoiceOver. The notification requires a user info + // dictionary with the key NSAccessibilityAnnouncementKey and the announcement as a localized + // string. In addition, the key NSAccessibilityAnnouncementPriorityKey should also be used to + // help an assistive application determine the importance of this announcement. This + // notification should be posted for the application element. + public static let announcementRequested = AXNotification(rawValue: "AXAnnouncementRequested") + } +} diff --git a/Sources/Constants/Action.swift b/Sources/Constants/Action.swift new file mode 100644 index 0000000..1da9345 --- /dev/null +++ b/Sources/Constants/Action.swift @@ -0,0 +1,28 @@ +import Foundation + +@available(*, deprecated, renamed: "UIElement.Action", message: "Provided for drop in replacement, but now the type is located under the `UIElement` namespace.") +public typealias Action = UIElement.Action +extension UIElement { + /// Provides all known actions a `UIElement` can support. + /// - seeAlso: [Actions](https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Protocols/NSAccessibility_Protocol/#//apple_ref/doc/constant_group/Actions) + public struct Action: RawRepresentable, Hashable, Sendable { + public let rawValue: String + public var rawCFStringValue: CFString { rawValue as CFString } + + public init(rawValue: String) { + self.rawValue = rawValue + } + + public static let press = Action(rawValue: "AXPress") + public static let increment = Action(rawValue: "AXIncrement") + public static let decrement = Action(rawValue: "AXDecrement") + public static let confirm = Action(rawValue: "AXConfirm") + public static let pick = Action(rawValue: "AXPick") + public static let cancel = Action(rawValue: "AXCancel") + public static let raise = Action(rawValue: "AXRaise") + public static let showMenu = Action(rawValue: "AXShowMenu") + public static let delete = Action(rawValue: "AXDelete") + public static let showAlternateUI = Action(rawValue: "AXShowAlternateUI") + public static let showDefaultUI = Action(rawValue: "AXShowDefaultUI") + } +} diff --git a/Sources/Constants/Attribute.swift b/Sources/Constants/Attribute.swift new file mode 100644 index 0000000..96862dc --- /dev/null +++ b/Sources/Constants/Attribute.swift @@ -0,0 +1,236 @@ +import Foundation + +@available(*, deprecated, renamed: "UIElement.Attribute", message: "Provided for drop in replacement, but now the type is located under the `UIElement` namespace.") +public typealias Attribute = UIElement.Attribute +extension UIElement { + public struct Attribute: RawRepresentable, Hashable, Sendable { + public let rawValue: String + public var rawCFStringValue: CFString { rawValue as CFString } + + public init(rawValue: String) { + self.rawValue = rawValue + } + + // Standard attributes + public static let role = Attribute(rawValue: "AXRole") //(NSString *) - type, non-localized (e.g. radioButton) + public static let roleDescription = Attribute(rawValue: "AXRoleDescription") //(NSString *) - user readable role (e.g. "radio button") + public static let subrole = Attribute(rawValue: "AXSubrole") //(NSString *) - type, non-localized (e.g. closeButton) + public static let help = Attribute(rawValue: "AXHelp") //(NSString *) - instance description (e.g. a tool tip) + public static let value = Attribute(rawValue: "AXValue") //(id) - element's value + public static let minValue = Attribute(rawValue: "AXMinValue") //(id) - element's min value + public static let maxValue = Attribute(rawValue: "AXMaxValue") //(id) - element's max value + public static let enabled = Attribute(rawValue: "AXEnabled") //(NSNumber *) - (boolValue) responds to user? + public static let focused = Attribute(rawValue: "AXFocused") //(NSNumber *) - (boolValue) has keyboard focus? + public static let parent = Attribute(rawValue: "AXParent") //(id) - element containing you + public static let children = Attribute(rawValue: "AXChildren") //(NSArray *) - elements you contain + public static let window = Attribute(rawValue: "AXWindow") //(id) - UIElement for the containing window + public static let topLevelUIElement = Attribute(rawValue: "AXTopLevelUIElement") //(id) - UIElement for the containing top level element + public static let selectedChildren = Attribute(rawValue: "AXSelectedChildren") //(NSArray *) - child elements which are selected + public static let visibleChildren = Attribute(rawValue: "AXVisibleChildren") //(NSArray *) - child elements which are visible + public static let position = Attribute(rawValue: "AXPosition") //(NSValue *) - (pointValue) position in screen coords + public static let size = Attribute(rawValue: "AXSize") //(NSValue *) - (sizeValue) size + public static let frame = Attribute(rawValue: "AXFrame") //(NSValue *) - (rectValue) frame + public static let contents = Attribute(rawValue: "AXContents") //(NSArray *) - main elements + public static let title = Attribute(rawValue: "AXTitle") //(NSString *) - visible text (e.g. of a push button) + public static let description = Attribute(rawValue: "AXDescription") //(NSString *) - instance description + public static let shownMenu = Attribute(rawValue: "AXShownMenu") //(id) - menu being displayed + public static let valueDescription = Attribute(rawValue: "AXValueDescription") //(NSString *) - text description of value + + public static let sharedFocusElements = Attribute(rawValue: "AXSharedFocusElements") //(NSArray *) - elements that share focus + + // Misc attributes + public static let previousContents = Attribute(rawValue: "AXPreviousContents") //(NSArray *) - main elements + public static let nextContents = Attribute(rawValue: "AXNextContents") //(NSArray *) - main elements + public static let header = Attribute(rawValue: "AXHeader") //(id) - UIElement for header. + public static let edited = Attribute(rawValue: "AXEdited") //(NSNumber *) - (boolValue) is it dirty? + public static let tabs = Attribute(rawValue: "AXTabs") //(NSArray *) - UIElements for tabs + public static let horizontalScrollBar = Attribute(rawValue: "AXHorizontalScrollBar") //(id) - UIElement for the horizontal scroller + public static let verticalScrollBar = Attribute(rawValue: "AXVerticalScrollBar") //(id) - UIElement for the vertical scroller + public static let overflowButton = Attribute(rawValue: "AXOverflowButton") //(id) - UIElement for overflow + public static let incrementButton = Attribute(rawValue: "AXIncrementButton") //(id) - UIElement for increment + public static let decrementButton = Attribute(rawValue: "AXDecrementButton") //(id) - UIElement for decrement + public static let filename = Attribute(rawValue: "AXFilename") //(NSString *) - filename + public static let expanded = Attribute(rawValue: "AXExpanded") //(NSNumber *) - (boolValue) is expanded? + public static let selected = Attribute(rawValue: "AXSelected") //(NSNumber *) - (boolValue) is selected? + public static let splitters = Attribute(rawValue: "AXSplitters") //(NSArray *) - UIElements for splitters + public static let document = Attribute(rawValue: "AXDocument") //(NSString *) - url as string - for open document + public static let activationPoint = Attribute(rawValue: "AXActivationPoint") //(NSValue *) - (pointValue) + + public static let url = Attribute(rawValue: "AXURL") //(NSURL *) - url + public static let index = Attribute(rawValue: "AXIndex") //(NSNumber *) - (intValue) + + public static let rowCount = Attribute(rawValue: "AXRowCount") //(NSNumber *) - (intValue) number of rows + + public static let columnCount = Attribute(rawValue: "AXColumnCount") //(NSNumber *) - (intValue) number of columns + + public static let orderedByRow = Attribute(rawValue: "AXOrderedByRow") //(NSNumber *) - (boolValue) is ordered by row? + + public static let warningValue = Attribute(rawValue: "AXWarningValue") //(id) - warning value of a level indicator, typically a number + + public static let criticalValue = Attribute(rawValue: "AXCriticalValue") //(id) - critical value of a level indicator, typically a number + + public static let placeholderValue = Attribute(rawValue: "AXPlaceholderValue") //(NSString *) - placeholder value of a control such as a text field + + public static let containsProtectedContent = Attribute(rawValue: "AXContainsProtectedContent") // (NSNumber *) - (boolValue) contains protected content? + public static let alternateUIVisible = Attribute(rawValue: "AXAlternateUIVisible") //(NSNumber *) - (boolValue) + + // Linkage attributes + public static let titleUIElement = Attribute(rawValue: "AXTitleUIElement") //(id) - UIElement for the title + public static let servesAsTitleForUIElements = Attribute(rawValue: "AXServesAsTitleForUIElements") //(NSArray *) - UIElements this titles + public static let linkedUIElements = Attribute(rawValue: "AXLinkedUIElements") //(NSArray *) - corresponding UIElements + + // Text-specific attributes + public static let selectedText = Attribute(rawValue: "AXSelectedText") //(NSString *) - selected text + public static let selectedTextRange = Attribute(rawValue: "AXSelectedTextRange") //(NSValue *) - (rangeValue) range of selected text + public static let numberOfCharacters = Attribute(rawValue: "AXNumberOfCharacters") //(NSNumber *) - number of characters + public static let visibleCharacterRange = Attribute(rawValue: "AXVisibleCharacterRange") //(NSValue *) - (rangeValue) range of visible text + public static let sharedTextUIElements = Attribute(rawValue: "AXSharedTextUIElements") //(NSArray *) - text views sharing text + public static let sharedCharacterRange = Attribute(rawValue: "AXSharedCharacterRange") //(NSValue *) - (rangeValue) part of shared text in this view + public static let insertionPointLineNumber = Attribute(rawValue: "AXInsertionPointLineNumber") //(NSNumber *) - line# containing caret + public static let selectedTextRanges = Attribute(rawValue: "AXSelectedTextRanges") //(NSArray *) - array of NSValue (rangeValue) ranges of selected text + /// - note: private/undocumented attribute + public static let textInputMarkedRange = Attribute(rawValue: "AXTextInputMarkedRange") + + // Parameterized text-specific attributes + public static let lineForIndexParameterized = Attribute(rawValue: "AXLineForIndexParameterized") //(NSNumber *) - line# for char index; param:(NSNumber *) + public static let rangeForLineParameterized = Attribute(rawValue: "AXRangeForLineParameterized") //(NSValue *) - (rangeValue) range of line; param:(NSNumber *) + public static let stringForRangeParameterized = Attribute(rawValue: "AXStringForRangeParameterized") //(NSString *) - substring; param:(NSValue * - rangeValue) + public static let rangeForPositionParameterized = Attribute(rawValue: "AXRangeForPositionParameterized") //(NSValue *) - (rangeValue) composed char range; param:(NSValue * - pointValue) + public static let rangeForIndexParameterized = Attribute(rawValue: "AXRangeForIndexParameterized") //(NSValue *) - (rangeValue) composed char range; param:(NSNumber *) + public static let boundsForRangeParameterized = Attribute(rawValue: "AXBoundsForRangeParameterized") //(NSValue *) - (rectValue) bounds of text; param:(NSValue * - rangeValue) + public static let rtfForRangeParameterized = Attribute(rawValue: "AXRTFForRangeParameterized") //(NSData *) - rtf for text; param:(NSValue * - rangeValue) + public static let styleRangeForIndexParameterized = Attribute(rawValue: "AXStyleRangeForIndexParameterized") //(NSValue *) - (rangeValue) extent of style run; param:(NSNumber *) + public static let attributedStringForRangeParameterized = Attribute(rawValue: "AXAttributedStringForRangeParameterized") //(NSAttributedString *) - does _not_ use attributes from Appkit/AttributedString.h + + // Text attributed string attributes and constants + public static let fontText = Attribute(rawValue: "AXFontText") //(NSDictionary *) - NSAccessibilityFontXXXKey's + public static let foregroundColorText = Attribute(rawValue: "AXForegroundColorText") //CGColorRef + public static let backgroundColorText = Attribute(rawValue: "AXBackgroundColorText") //CGColorRef + public static let underlineColorText = Attribute(rawValue: "AXUnderlineColorText") //CGColorRef + public static let strikethroughColorText = Attribute(rawValue: "AXStrikethroughColorText") //CGColorRef + public static let underlineText = Attribute(rawValue: "AXUnderlineText") //(NSNumber *) - underline style + public static let superscriptText = Attribute(rawValue: "AXSuperscriptText") //(NSNumber *) - superscript>0, subscript<0 + public static let strikethroughText = Attribute(rawValue: "AXStrikethroughText") //(NSNumber *) - (boolValue) + public static let shadowText = Attribute(rawValue: "AXShadowText") //(NSNumber *) - (boolValue) + public static let attachmentText = Attribute(rawValue: "AXAttachmentText") //id - corresponding element + public static let linkText = Attribute(rawValue: "AXLinkText") //id - corresponding element + public static let autocorrectedText = Attribute(rawValue: "AXAutocorrectedText") //(NSNumber *) - (boolValue) + + // Textual list attributes and constants. Examples: unordered or ordered lists in a document. + public static let listItemPrefixText = Attribute(rawValue: "AXListItemPrefixText") // NSAttributedString, the prepended string of the list item. If the string is a common unicode character (e.g. a bullet •), return that unicode character. For lists with images before the text, return a reasonable label of the image. + public static let listItemIndexText = Attribute(rawValue: "AXListItemIndexText") // NSNumber, integerValue of the line index. Each list item increments the index, even for unordered lists. The first item should have index 0. + public static let listItemLevelText = Attribute(rawValue: "AXListItemLevelText") // NSNumber, integerValue of the indent level. Each sublist increments the level. The first item should have level 0. + + // MisspelledText attributes + public static let misspelledText = Attribute(rawValue: "AXMisspelledText") //(NSNumber *) - (boolValue) + public static let markedMisspelledText = Attribute(rawValue: "AXMarkedMisspelledText") //(NSNumber *) - (boolValue) + + // Window-specific attributes + public static let main = Attribute(rawValue: "AXMain") //(NSNumber *) - (boolValue) is it the main window? + public static let minimized = Attribute(rawValue: "AXMinimized") //(NSNumber *) - (boolValue) is window minimized? + public static let closeButton = Attribute(rawValue: "AXCloseButton") //(id) - UIElement for close box (or nil) + public static let zoomButton = Attribute(rawValue: "AXZoomButton") //(id) - UIElement for zoom box (or nil) + public static let minimizeButton = Attribute(rawValue: "AXMinimizeButton") //(id) - UIElement for miniaturize box (or nil) + public static let toolbarButton = Attribute(rawValue: "AXToolbarButton") //(id) - UIElement for toolbar box (or nil) + public static let proxy = Attribute(rawValue: "AXProxy") //(id) - UIElement for title's icon (or nil) + public static let growArea = Attribute(rawValue: "AXGrowArea") //(id) - UIElement for grow box (or nil) + public static let modal = Attribute(rawValue: "AXModal") //(NSNumber *) - (boolValue) is the window modal + public static let defaultButton = Attribute(rawValue: "AXDefaultButton") //(id) - UIElement for default button + public static let cancelButton = Attribute(rawValue: "AXCancelButton") //(id) - UIElement for cancel button + public static let fullScreenButton = Attribute(rawValue: "AXFullScreenButton") //(id) - UIElement for full screen button (or nil) + /// - note: private/undocumented attribute + public static let fullScreen = Attribute(rawValue: "AXFullScreen") //(NSNumber *) - (boolValue) is the window fullscreen + + // Application-specific attributes + public static let menuBar = Attribute(rawValue: "AXMenuBar") //(id) - UIElement for the menu bar + public static let windows = Attribute(rawValue: "AXWindows") //(NSArray *) - UIElements for the windows + public static let frontmost = Attribute(rawValue: "AXFrontmost") //(NSNumber *) - (boolValue) is the app active? + public static let hidden = Attribute(rawValue: "AXHidden") //(NSNumber *) - (boolValue) is the app hidden? + public static let mainWindow = Attribute(rawValue: "AXMainWindow") //(id) - UIElement for the main window. + public static let focusedWindow = Attribute(rawValue: "AXFocusedWindow") //(id) - UIElement for the key window. + public static let focusedUIElement = Attribute(rawValue: "AXFocusedUIElement") //(id) - Currently focused UIElement. + public static let extrasMenuBar = Attribute(rawValue: "AXExtrasMenuBar") //(id) - UIElement for the application extras menu bar. + /// - note: private/undocumented attribute + public static let enhancedUserInterface = Attribute(rawValue: "AXEnhancedUserInterface") //(NSNumber *) - (boolValue) is the enhanced user interface active? + + public static let orientation = Attribute(rawValue: "AXOrientation") //(NSString *) - NSAccessibilityXXXOrientationValue + + public static let columnTitles = Attribute(rawValue: "AXColumnTitles") //(NSArray *) - UIElements for titles + + public static let searchButton = Attribute(rawValue: "AXSearchButton") //(id) - UIElement for search field search btn + public static let searchMenu = Attribute(rawValue: "AXSearchMenu") //(id) - UIElement for search field menu + public static let clearButton = Attribute(rawValue: "AXClearButton") //(id) - UIElement for search field clear btn + + // Table/outline view attributes + public static let rows = Attribute(rawValue: "AXRows") //(NSArray *) - UIElements for rows + public static let visibleRows = Attribute(rawValue: "AXVisibleRows") //(NSArray *) - UIElements for visible rows + public static let selectedRows = Attribute(rawValue: "AXSelectedRows") //(NSArray *) - UIElements for selected rows + public static let columns = Attribute(rawValue: "AXColumns") //(NSArray *) - UIElements for columns + public static let visibleColumns = Attribute(rawValue: "AXVisibleColumns") //(NSArray *) - UIElements for visible columns + public static let selectedColumns = Attribute(rawValue: "AXSelectedColumns") //(NSArray *) - UIElements for selected columns + public static let sortDirection = Attribute(rawValue: "AXSortDirection") //(NSString *) - see sort direction values below + + // Cell-based table attributes + public static let selectedCells = Attribute(rawValue: "AXSelectedCells") //(NSArray *) - UIElements for selected cells + public static let visibleCells = Attribute(rawValue: "AXVisibleCells") //(NSArray *) - UIElements for visible cells + public static let rowHeaderUIElements = Attribute(rawValue: "AXRowHeaderUIElements") //(NSArray *) - UIElements for row headers + public static let columnHeaderUIElements = Attribute(rawValue: "AXColumnHeaderUIElements") //(NSArray *) - UIElements for column headers + + // Cell-based table parameterized attributes. The parameter for this attribute is an NSArray containing two NSNumbers, the first NSNumber specifies the column index, the second NSNumber specifies the row index. + public static let cellForColumnAndRowParameterized = Attribute(rawValue: "AXCellForColumnAndRowParameterized") // (id) - UIElement for cell at specified row and column + + // Cell attributes. The index range contains both the starting index, and the index span in a table. + public static let rowIndexRange = Attribute(rawValue: "AXRowIndexRange") //(NSValue *) - (rangeValue) location and row span + public static let columnIndexRange = Attribute(rawValue: "AXColumnIndexRange") //(NSValue *) - (rangeValue) location and column span + + // Layout area attributes + public static let horizontalUnits = Attribute(rawValue: "AXHorizontalUnits") //(NSString *) - see ruler unit values below + public static let verticalUnits = Attribute(rawValue: "AXVerticalUnits") //(NSString *) - see ruler unit values below + public static let horizontalUnitDescription = Attribute(rawValue: "AXHorizontalUnitDescription") //(NSString *) + public static let verticalUnitDescription = Attribute(rawValue: "AXVerticalUnitDescription") //(NSString *) + + // Layout area parameterized attributes + public static let layoutPointForScreenPointParameterized = "Attribute(rawValue: AXLayoutPointForScreenPointParameterized" //)(NSValue *) - (pointValue); param:(NSValue * - pointValue) + public static let layoutSizeForScreenSizeParameterized = Attribute(rawValue: "AXLayoutSizeForScreenSizeParameterized") //(NSValue *) - (sizeValue); param:(NSValue * - sizeValue) + public static let screenPointForLayoutPointParameterized = "Attribute(rawValue: AXScreenPointForLayoutPointParameterized" //)(NSValue *) - (pointValue); param:(NSValue * - pointValue) + public static let screenSizeForLayoutSizeParameterized = Attribute(rawValue: "AXScreenSizeForLayoutSizeParameterized") //(NSValue *) - (sizeValue); param:(NSValue * - sizeValue) + + // Layout item attributes + public static let handles = Attribute(rawValue: "AXHandles") //(NSArray *) - UIElements for handles + + // Outline attributes + public static let disclosing = Attribute(rawValue: "AXDisclosing") //(NSNumber *) - (boolValue) is disclosing rows? + public static let disclosedRows = Attribute(rawValue: "AXDisclosedRows") //(NSArray *) - UIElements for disclosed rows + public static let disclosedByRow = Attribute(rawValue: "AXDisclosedByRow") //(id) - UIElement for disclosing row + public static let disclosureLevel = Attribute(rawValue: "AXDisclosureLevel") //(NSNumber *) - indentation level + + // Slider attributes + public static let allowedValues = Attribute(rawValue: "AXAllowedValues") //(NSArray *) - array of allowed values + public static let labelUIElements = Attribute(rawValue: "AXLabelUIElements") //(NSArray *) - array of label UIElements + public static let labelValue = Attribute(rawValue: "AXLabelValue") //(NSNumber *) - value of a label UIElement + + // Matte attributes + // Attributes no longer supported + public static let matteHole = Attribute(rawValue: "AXMatteHole") //(NSValue *) - (rect value) bounds of matte hole in screen coords + public static let matteContentUIElement = Attribute(rawValue: "AXMatteContentUIElement") //(id) - UIElement clipped by the matte + + // Ruler view attributes + public static let markerUIElements = Attribute(rawValue: "AXMarkerUIElements") //(NSArray *) + public static let markerValues = Attribute(rawValue: "AXMarkerValues") // + public static let markerGroupUIElement = Attribute(rawValue: "AXMarkerGroupUIElement") //(id) + public static let units = Attribute(rawValue: "AXUnits") //(NSString *) - see ruler unit values below + public static let unitDescription = Attribute(rawValue: "AXUnitDescription") //(NSString *) + public static let markerType = Attribute(rawValue: "AXMarkerType") //(NSString *) - see ruler marker type values below + public static let markerTypeDescription = Attribute(rawValue: "AXMarkerTypeDescription") //(NSString *) + + // UI element identification attributes + public static let identifier = Attribute(rawValue: "AXIdentifier") //(NSString *) + + // System-wide attributes + public static let focusedApplication = Attribute(rawValue: "AXFocusedApplication") + + // Unknown attributes + public static let functionRowTopLevelElements = Attribute(rawValue: "AXFunctionRowTopLevelElements") + public static let childrenInNavigationOrder = Attribute(rawValue: "AXChildrenInNavigationOrder") + } +} diff --git a/Sources/Constants/Orientation.swift b/Sources/Constants/Orientation.swift new file mode 100644 index 0000000..2f27264 --- /dev/null +++ b/Sources/Constants/Orientation.swift @@ -0,0 +1,13 @@ +import Foundation + +@available(*, deprecated, renamed: "UIElement.Orientation", message: "Provided for drop in replacement, but now the type is located under the `UIElement` namespace.") +public typealias Orientation = UIElement.Orientation +extension UIElement { + /// Orientations returned by the orientation property. + /// - seeAlso: [NSAccessibilityOrientation](https://developer.apple.com/library/mac/documentation/AppKit/Reference/NSAccessibility_Protocol_Reference/index.html#//apple_ref/c/tdef/NSAccessibilityOrientation) + public enum Orientation: Int { + case unknown = 0 + case vertical = 1 + case horizontal = 2 + } +} diff --git a/Sources/Constants/Role.swift b/Sources/Constants/Role.swift new file mode 100644 index 0000000..74d7653 --- /dev/null +++ b/Sources/Constants/Role.swift @@ -0,0 +1,72 @@ +import Foundation + +@available(*, deprecated, renamed: "UIElement.Role", message: "Provided for drop in replacement, but now the type is located under the `UIElement` namespace.") +public typealias Role = UIElement.Role +extension UIElement { + /// Provides all known UIElement roles. + /// - seeAlso: [Roles](https://developer.apple.com/library/mac/documentation/AppKit/Reference/NSAccessibility_Protocol_Reference/index.html#//apple_ref/doc/constant_group/Roles) + public struct Role: RawRepresentable, Hashable, Sendable { + public let rawValue: String + public var rawCFStringValue: CFString { rawValue as CFString } + + public init(rawValue: String) { + self.rawValue = rawValue + } + + public static let unknown = Role(rawValue: "AXUnknown") + public static let button = Role(rawValue: "AXButton") + public static let radioButton = Role(rawValue: "AXRadioButton") + public static let checkBox = Role(rawValue: "AXCheckBox") + public static let slider = Role(rawValue: "AXSlider") + public static let tabGroup = Role(rawValue: "AXTabGroup") + public static let textField = Role(rawValue: "AXTextField") + public static let staticText = Role(rawValue: "AXStaticText") + public static let textArea = Role(rawValue: "AXTextArea") + public static let scrollArea = Role(rawValue: "AXScrollArea") + public static let popUpButton = Role(rawValue: "AXPopUpButton") + public static let menuButton = Role(rawValue: "AXMenuButton") + public static let table = Role(rawValue: "AXTable") + public static let application = Role(rawValue: "AXApplication") + public static let group = Role(rawValue: "AXGroup") + public static let radioGroup = Role(rawValue: "AXRadioGroup") + public static let list = Role(rawValue: "AXList") + public static let scrollBar = Role(rawValue: "AXScrollBar") + public static let valueIndicator = Role(rawValue: "AXValueIndicator") + public static let image = Role(rawValue: "AXImage") + public static let menuBar = Role(rawValue: "AXMenuBar") + public static let menu = Role(rawValue: "AXMenu") + public static let menuItem = Role(rawValue: "AXMenuItem") + public static let menuBarItem = Role(rawValue: "AXMenuBarItem") + public static let column = Role(rawValue: "AXColumn") + public static let row = Role(rawValue: "AXRow") + public static let toolbar = Role(rawValue: "AXToolbar") + public static let busyIndicator = Role(rawValue: "AXBusyIndicator") + public static let progressIndicator = Role(rawValue: "AXProgressIndicator") + public static let window = Role(rawValue: "AXWindow") + public static let drawer = Role(rawValue: "AXDrawer") + public static let systemWide = Role(rawValue: "AXSystemWide") + public static let outline = Role(rawValue: "AXOutline") + public static let incrementor = Role(rawValue: "AXIncrementor") + public static let browser = Role(rawValue: "AXBrowser") + public static let comboBox = Role(rawValue: "AXComboBox") + public static let splitGroup = Role(rawValue: "AXSplitGroup") + public static let splitter = Role(rawValue: "AXSplitter") + public static let colorWell = Role(rawValue: "AXColorWell") + public static let growArea = Role(rawValue: "AXGrowArea") + public static let sheet = Role(rawValue: "AXSheet") + public static let helpTag = Role(rawValue: "AXHelpTag") + public static let matte = Role(rawValue: "AXMatte") + public static let ruler = Role(rawValue: "AXRuler") + public static let rulerMarker = Role(rawValue: "AXRulerMarker") + public static let link = Role(rawValue: "AXLink") + public static let disclosureTriangle = Role(rawValue: "AXDisclosureTriangle") + public static let grid = Role(rawValue: "AXGrid") + public static let relevanceIndicator = Role(rawValue: "AXRelevanceIndicator") + public static let levelIndicator = Role(rawValue: "AXLevelIndicator") + public static let cell = Role(rawValue: "AXCell") + public static let popover = Role(rawValue: "AXPopover") + public static let layoutArea = Role(rawValue: "AXLayoutArea") + public static let layoutItem = Role(rawValue: "AXLayoutItem") + public static let handle = Role(rawValue: "AXHandle") + } +} diff --git a/Sources/Constants/Subrole.swift b/Sources/Constants/Subrole.swift new file mode 100644 index 0000000..ac28b76 --- /dev/null +++ b/Sources/Constants/Subrole.swift @@ -0,0 +1,46 @@ +import Foundation + +@available(*, deprecated, renamed: "UIElement.Role.Subrole", message: "Provided for drop in replacement, but now the type is located under the `UIElement.Role` namespace.") +public typealias Subrole = UIElement.Role.Subrole +extension UIElement.Role { + /// Provides all known UIElement subroles. + /// - seeAlso: [Subroles](https://developer.apple.com/library/mac/documentation/AppKit/Reference/NSAccessibility_Protocol_Reference/index.html#//apple_ref/doc/constant_group/Subroles) + public struct Subrole: RawRepresentable, Hashable, Sendable { + public let rawValue: String + public var rawCFStringValue: CFString { rawValue as CFString } + + public init(rawValue: String) { + self.rawValue = rawValue + } + + public static let unknown = Subrole(rawValue: "AXUnknown") + public static let closeButton = Subrole(rawValue: "AXCloseButton") + public static let zoomButton = Subrole(rawValue: "AXZoomButton") + public static let minimizeButton = Subrole(rawValue: "AXMinimizeButton") + public static let toolbarButton = Subrole(rawValue: "AXToolbarButton") + public static let tableRow = Subrole(rawValue: "AXTableRow") + public static let outlineRow = Subrole(rawValue: "AXOutlineRow") + public static let secureTextField = Subrole(rawValue: "AXSecureTextField") + public static let standardWindow = Subrole(rawValue: "AXStandardWindow") + public static let dialog = Subrole(rawValue: "AXDialog") + public static let systemDialog = Subrole(rawValue: "AXSystemDialog") + public static let floatingWindow = Subrole(rawValue: "AXFloatingWindow") + public static let systemFloatingWindow = Subrole(rawValue: "AXSystemFloatingWindow") + public static let incrementArrow = Subrole(rawValue: "AXIncrementArrow") + public static let decrementArrow = Subrole(rawValue: "AXDecrementArrow") + public static let incrementPage = Subrole(rawValue: "AXIncrementPage") + public static let decrementPage = Subrole(rawValue: "AXDecrementPage") + public static let searchField = Subrole(rawValue: "AXSearchField") + public static let textAttachment = Subrole(rawValue: "AXTextAttachment") + public static let textLink = Subrole(rawValue: "AXTextLink") + public static let timeline = Subrole(rawValue: "AXTimeline") + public static let sortButton = Subrole(rawValue: "AXSortButton") + public static let ratingIndicator = Subrole(rawValue: "AXRatingIndicator") + public static let contentList = Subrole(rawValue: "AXContentList") + public static let definitionList = Subrole(rawValue: "AXDefinitionList") + public static let fullScreenButton = Subrole(rawValue: "AXFullScreenButton") + public static let toggle = Subrole(rawValue: "AXToggle") + public static let switchSubrole = Subrole(rawValue: "AXSwitch") + public static let descriptionList = Subrole(rawValue: "AXDescriptionList") + } +} diff --git a/Sources/Observer.swift b/Sources/Observer.swift index 75954d5..eaf919d 100644 --- a/Sources/Observer.swift +++ b/Sources/Observer.swift @@ -10,10 +10,10 @@ import Darwin public final class Observer { public typealias Callback = (_ observer: Observer, _ element: UIElement, - _ notification: AXNotification) -> Void + _ notification: UIElement.AXNotification) -> Void public typealias CallbackWithInfo = (_ observer: Observer, _ element: UIElement, - _ notification: AXNotification, + _ notification: UIElement.AXNotification, _ info: [String: AnyObject]?) -> Void let pid: pid_t @@ -100,7 +100,7 @@ public final class Observer { /// error is not passed on for consistency with `start()` and `stop()`. /// - throws: `Error.NotificationUnsupported`: The element does not support notifications (note /// that the system-wide element does not support notifications). - public func addNotification(_ notification: AXNotification, + public func addNotification(_ notification: UIElement.AXNotification, forElement element: UIElement) throws { let selfPtr = UnsafeMutableRawPointer(Unmanaged.passUnretained(self).toOpaque()) let error = AXObserverAddNotification( @@ -119,7 +119,7 @@ public final class Observer { /// error is not passed on for consistency with `start()` and `stop()`. /// - throws: `Error.NotificationUnsupported`: The element does not support notifications (note /// that the system-wide element does not support notifications). - public func removeNotification(_ notification: AXNotification, + public func removeNotification(_ notification: UIElement.AXNotification, forElement element: UIElement) throws { let error = AXObserverRemoveNotification( axObserver, element.element, notification.rawValue as CFString @@ -138,10 +138,11 @@ private func internalCallback(_ axObserver: AXObserver, let observer = Unmanaged.fromOpaque(userData).takeUnretainedValue() let element = UIElement(axElement) - guard let notif = AXNotification(rawValue: notification as String) else { - NSLog("Unknown AX notification %s received", notification as String) - return - } + let notif = UIElement.AXNotification(rawValue: notification as String) +// guard let notif = UIElement.AXNotification(rawValue: notification as String) else { +// NSLog("Unknown AX notification %s received", notification as String) +// return +// } observer.callback!(observer, element, notif) } @@ -155,9 +156,10 @@ private func internalInfoCallback(_ axObserver: AXObserver, let observer = Unmanaged.fromOpaque(userData).takeUnretainedValue() let element = UIElement(axElement) let info = cfInfo as NSDictionary? as! [String: AnyObject]? - guard let notif = AXNotification(rawValue: notification as String) else { - NSLog("Unknown AX notification %s received", notification as String) - return - } + let notif = UIElement.AXNotification(rawValue: notification as String) +// guard let notif = UIElement.AXNotification(rawValue: notification as String) else { +// NSLog("Unknown AX notification %s received", notification as String) +// return +// } observer.callbackWithInfo!(observer, element, notif, info) } diff --git a/Sources/UIElement.swift b/Sources/UIElement.swift index fdd065f..c447da4 100644 --- a/Sources/UIElement.swift +++ b/Sources/UIElement.swift @@ -677,9 +677,9 @@ extension UIElement { } /// - seeAlso: [Subroles](https://developer.apple.com/library/mac/documentation/AppKit/Reference/NSAccessibility_Protocol_Reference/index.html#//apple_ref/doc/constant_group/Subroles) - public func subrole() throws(AXError) -> Subrole? { + public func subrole() throws(AXError) -> Role.Subrole? { if let str: String = try self.attribute(.subrole) { - return Subrole(rawValue: str) + return Role.Subrole(rawValue: str) } else { return nil } From 134ea9e0cf48d85976807acd2b5bc5cf783e5a5d Mon Sep 17 00:00:00 2001 From: Michael Redig Date: Sat, 14 Jun 2025 15:33:37 -0500 Subject: [PATCH 06/39] (fix) update Package.swift conventions --- Package.swift | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/Package.swift b/Package.swift index a1800b3..1af45eb 100644 --- a/Package.swift +++ b/Package.swift @@ -4,9 +4,9 @@ import PackageDescription let package = Package( name: "AXSwift", - platforms: [ - .macOS(.v10_15) - ], + platforms: [ + .macOS(.v10_15) + ], products: [ .library( name: "AXSwift", @@ -16,10 +16,12 @@ let package = Package( .target( name: "AXSwift", path: "Sources"), - .target(name: "AXSwiftExample", + .executableTarget( + name: "AXSwiftExample", dependencies: ["AXSwift"], path: "AXSwiftExample"), - .target(name: "AXSwiftObserverExample", + .executableTarget( + name: "AXSwiftObserverExample", dependencies: ["AXSwift"], path: "AXSwiftObserverExample"), ] From b3d7e21a84ba76808ceaffd53b49fffd14926e44 Mon Sep 17 00:00:00 2001 From: Michael Redig Date: Sat, 14 Jun 2025 15:36:50 -0500 Subject: [PATCH 07/39] (refactor) attributes --- Sources/UIElement.swift | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/Sources/UIElement.swift b/Sources/UIElement.swift index c447da4..a286804 100644 --- a/Sources/UIElement.swift +++ b/Sources/UIElement.swift @@ -77,20 +77,10 @@ open class UIElement { /// /// Does not include parameterized attributes. open func attributes() throws(AXError) -> [Attribute] { - let attrs = try attributesAsStrings() - for attr in attrs where Attribute(rawValue: attr) == nil { - print("Unrecognized attribute: \(attr)") - } - return attrs.compactMap({ Attribute(rawValue: $0) }) - } - - // This version is named differently so the caller doesn't have to specify the return type when - // using the enum version. - open func attributesAsStrings() throws(AXError) -> [String] { - var names: CFArray? + var names: CFArray! let error = AXUIElementCopyAttributeNames(element, &names) - if error == .noValue || error == .attributeUnsupported { + guard error != .noValue, error != .attributeUnsupported, let names else { return [] } @@ -100,7 +90,16 @@ open class UIElement { // We must first convert the CFArray to a native array, then downcast to an array of // strings. - return names! as [AnyObject] as! [String] + let strings = names as! [String] + + return strings.map(Attribute.init(rawValue:)) + } + + // This version is named differently so the caller doesn't have to specify the return type when + // using the enum version. + @available(*, deprecated, renamed: "attributes", message: "If you need strings, just call `attributes().map(\\.rawValue)`") + open func attributesAsStrings() throws(AXError) -> [String] { + try attributes().map(\.rawValue) } /// Returns whether `attribute` is supported by this element. From a73bcbfd36adc31c547b933d8b2a9152432ddba6 Mon Sep 17 00:00:00 2001 From: Michael Redig Date: Sat, 14 Jun 2025 15:40:55 -0500 Subject: [PATCH 08/39] (refactor) attributeIsSupported --- Sources/UIElement.swift | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Sources/UIElement.swift b/Sources/UIElement.swift index a286804..bdd99c0 100644 --- a/Sources/UIElement.swift +++ b/Sources/UIElement.swift @@ -109,13 +109,9 @@ open class UIElement { /// errors). However, if you'd like to specifically test an attribute is actually supported, you /// can use this method. open func attributeIsSupported(_ attribute: Attribute) throws(AXError) -> Bool { - return try attributeIsSupported(attribute.rawValue) - } - - open func attributeIsSupported(_ attribute: String) throws(AXError) -> Bool { // Ask to copy 0 values, since we are only interested in the return code. var value: CFArray? - let error = AXUIElementCopyAttributeValues(element, attribute as CFString, 0, 0, &value) + let error = AXUIElementCopyAttributeValues(element, attribute.rawCFStringValue, 0, 0, &value) if error == .attributeUnsupported { return false @@ -132,6 +128,11 @@ open class UIElement { return true } + @available(*, deprecated, renamed: "attributeIsSupported") + open func attributeIsSupported(_ attribute: String) throws(AXError) -> Bool { + try attributeIsSupported(Attribute(rawValue: attribute)) + } + /// Returns whether `attribute` is writeable. open func attributeIsSettable(_ attribute: Attribute) throws(AXError) -> Bool { return try attributeIsSettable(attribute.rawValue) From e2345a6cb431a5db8245f905df3fc3e4f1d365b0 Mon Sep 17 00:00:00 2001 From: Michael Redig Date: Sat, 14 Jun 2025 15:42:20 -0500 Subject: [PATCH 09/39] (refactor) attributeIsSettable --- Sources/UIElement.swift | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Sources/UIElement.swift b/Sources/UIElement.swift index bdd99c0..d57b49a 100644 --- a/Sources/UIElement.swift +++ b/Sources/UIElement.swift @@ -135,12 +135,8 @@ open class UIElement { /// Returns whether `attribute` is writeable. open func attributeIsSettable(_ attribute: Attribute) throws(AXError) -> Bool { - return try attributeIsSettable(attribute.rawValue) - } - - open func attributeIsSettable(_ attribute: String) throws(AXError) -> Bool { var settable: DarwinBoolean = false - let error = AXUIElementIsAttributeSettable(element, attribute as CFString, &settable) + let error = AXUIElementIsAttributeSettable(element, attribute.rawCFStringValue, &settable) if error == .noValue || error == .attributeUnsupported { return false @@ -153,6 +149,11 @@ open class UIElement { return settable.boolValue } + @available(*, deprecated, renamed: "attributeIsSettable") + open func attributeIsSettable(_ attribute: String) throws(AXError) -> Bool { + try attributeIsSettable(Attribute(rawValue: attribute)) + } + /// Returns the value of `attribute`, if it exists. /// /// - parameter attribute: The name of a (non-parameterized) attribute. From 8bbd46b15191d025757a1d3e012f8921ead11431 Mon Sep 17 00:00:00 2001 From: Michael Redig Date: Sat, 14 Jun 2025 15:45:08 -0500 Subject: [PATCH 10/39] (refactor) attribute --- Sources/UIElement.swift | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/Sources/UIElement.swift b/Sources/UIElement.swift index d57b49a..b6cfd25 100644 --- a/Sources/UIElement.swift +++ b/Sources/UIElement.swift @@ -164,28 +164,31 @@ open class UIElement { /// - warning: This method force-casts the attribute to the desired type, which will abort if /// the cast fails. If you want to check the return type, ask for Any. open func attribute(_ attribute: Attribute) throws(AXError) -> T? { - return try self.attribute(attribute.rawValue) - } - - open func attribute(_ attribute: String) throws(AXError) -> T? { var value: AnyObject? - let error = AXUIElementCopyAttributeValue(element, attribute as CFString, &value) + let error = AXUIElementCopyAttributeValue(element, attribute.rawCFStringValue, &value) - if error == .noValue || error == .attributeUnsupported { - return nil - } + guard + error != .noValue, + error != .attributeUnsupported, + let value + else { return nil } guard error == .success else { throw error } - guard let unpackedValue = (unpackAXValue(value!) as? T) else { + guard let unpackedValue = (unpackAXValue(value) as? T) else { throw AXError.illegalArgument } - + return unpackedValue } + @available(*, deprecated, renamed: "attribute") + open func attribute(_ attribute: String) throws(AXError) -> T? { + try self.attribute(Attribute(rawValue: attribute)) + } + /// Sets the value of `attribute` to `value`. /// /// - warning: Unlike read-only methods, this method throws(AXError) if the attribute doesn't exist. From 7076fb602096a82ed5d0eae77c6815b4acdb6ab8 Mon Sep 17 00:00:00 2001 From: Michael Redig Date: Sat, 14 Jun 2025 16:13:46 -0500 Subject: [PATCH 11/39] (feat) add AXValueCompatibility --- Sources/AXValueCompatibility.swift | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 Sources/AXValueCompatibility.swift diff --git a/Sources/AXValueCompatibility.swift b/Sources/AXValueCompatibility.swift new file mode 100644 index 0000000..8961b33 --- /dev/null +++ b/Sources/AXValueCompatibility.swift @@ -0,0 +1,28 @@ +import Cocoa + +public protocol AXValueCompatibility {} + +extension AXValueCompatibility { + func pack() -> AnyObject { + switch self { + case let val as UIElement: + return val.element + case var val as CFRange: + return AXValueCreate(AXValueType(rawValue: kAXValueCFRangeType)!, &val)! + case var val as CGPoint: + return AXValueCreate(AXValueType(rawValue: kAXValueCGPointType)!, &val)! + case var val as CGRect: + return AXValueCreate(AXValueType(rawValue: kAXValueCGRectType)!, &val)! + case var val as CGSize: + return AXValueCreate(AXValueType(rawValue: kAXValueCGSizeType)!, &val)! + default: + return self as AnyObject // must be an object to pass to AX + } + } +} + +extension UIElement: AXValueCompatibility {} +extension CFRange: AXValueCompatibility {} +extension CGPoint: AXValueCompatibility {} +extension CGRect: AXValueCompatibility {} +extension CGSize: AXValueCompatibility {} From 9f71e090ec5a9f22625b94f88295660480cc0c9c Mon Sep 17 00:00:00 2001 From: Michael Redig Date: Sat, 14 Jun 2025 16:13:57 -0500 Subject: [PATCH 12/39] (refactor) setAttribute --- Sources/UIElement.swift | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/Sources/UIElement.swift b/Sources/UIElement.swift index b6cfd25..b5fc76f 100644 --- a/Sources/UIElement.swift +++ b/Sources/UIElement.swift @@ -197,18 +197,19 @@ open class UIElement { /// - `Error.AttributeUnsupported`: `attribute` isn't supported. /// - `Error.IllegalArgument`: `value` is an illegal value. /// - `Error.Failure`: A temporary failure occurred. - open func setAttribute(_ attribute: Attribute, value: Any) throws(AXError) { - try setAttribute(attribute.rawValue, value: value) - } - - open func setAttribute(_ attribute: String, value: Any) throws(AXError) { - let error = AXUIElementSetAttributeValue(element, attribute as CFString, packAXValue(value)) + open func setAttribute(_ attribute: Attribute, value: T) throws(AXError) { + let error = AXUIElementSetAttributeValue(element, attribute.rawCFStringValue, packAXValue(value)) guard error == .success else { throw error } } + @available(*, deprecated, renamed: "setAttribute") + open func setAttribute(_ attribute: String, value: T) throws(AXError) { + try setAttribute(Attribute(rawValue: attribute), value: value) + } + /// Gets multiple attributes of the element at once. /// /// - parameter attributes: An array of attribute names. Nonexistent attributes are ignored. From c108bfc4ed7730220433f24e61c8bd81054a3e88 Mon Sep 17 00:00:00 2001 From: Michael Redig Date: Sat, 14 Jun 2025 16:30:30 -0500 Subject: [PATCH 13/39] (refactor) multiattr stuff --- Sources/UIElement.swift | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Sources/UIElement.swift b/Sources/UIElement.swift index b5fc76f..e4c95e1 100644 --- a/Sources/UIElement.swift +++ b/Sources/UIElement.swift @@ -227,21 +227,21 @@ open class UIElement { } open func getMultipleAttributes(_ attributes: [Attribute]) throws(AXError) -> [Attribute: Any] { - let values = try fetchMultiAttrValues(attributes.map({ $0.rawValue })) + let values = try fetchMultiAttrValues(attributes) return try packMultiAttrValues(attributes, values: values) } open func getMultipleAttributes(_ attributes: [String]) throws(AXError) -> [String: Any] { - let values = try fetchMultiAttrValues(attributes) + let values = try fetchMultiAttrValues(attributes.map(Attribute.init(rawValue:))) return try packMultiAttrValues(attributes, values: values) } // Helper: Gets list of values - fileprivate func fetchMultiAttrValues(_ attributes: [String]) throws(AXError) -> [AnyObject] { + fileprivate func fetchMultiAttrValues(_ attributes: [Attribute]) throws(AXError) -> [AnyObject] { var valuesCF: CFArray? let error = AXUIElementCopyMultipleAttributeValues( element, - attributes as CFArray, + attributes.map(\.rawCFStringValue) as CFArray, // keep going on errors (particularly NoValue) AXCopyMultipleAttributeOptions(rawValue: 0), &valuesCF) From bacb30256efee50b95d078528bc7c7f519925f94 Mon Sep 17 00:00:00 2001 From: Michael Redig Date: Sat, 14 Jun 2025 16:30:57 -0500 Subject: [PATCH 14/39] (refactor) arrayAttribute --- Sources/UIElement.swift | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Sources/UIElement.swift b/Sources/UIElement.swift index e4c95e1..b9fb272 100644 --- a/Sources/UIElement.swift +++ b/Sources/UIElement.swift @@ -299,10 +299,6 @@ open class UIElement { /// /// - throws: `Error.IllegalArgument` if the attribute isn't an array. open func arrayAttribute(_ attribute: Attribute) throws(AXError) -> [T]? { - return try arrayAttribute(attribute.rawValue) - } - - open func arrayAttribute(_ attribute: String) throws(AXError) -> [T]? { guard let value: Any = try self.attribute(attribute) else { return nil } @@ -313,6 +309,11 @@ open class UIElement { return array.map({ unpackAXValue($0) as! T }) } + @available(*, deprecated, renamed: "arrayAttribute") + open func arrayAttribute(_ attribute: String) throws(AXError) -> [T]? { + try arrayAttribute(Attribute(rawValue: attribute)) + } + /// Returns a subset of values from an array attribute. /// /// - parameter attribute: The name of the array attribute. From c69dc903388b1fc89fb611efab3af7717572f4e0 Mon Sep 17 00:00:00 2001 From: Michael Redig Date: Sat, 14 Jun 2025 16:31:19 -0500 Subject: [PATCH 15/39] (refactor) valuesForAttribute --- Sources/UIElement.swift | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/Sources/UIElement.swift b/Sources/UIElement.swift index b9fb272..e7b06da 100644 --- a/Sources/UIElement.swift +++ b/Sources/UIElement.swift @@ -327,28 +327,31 @@ open class UIElement { /// - throws: `Error.IllegalArgument` if the attribute isn't an array. open func valuesForAttribute (_ attribute: Attribute, startAtIndex index: Int, maxValues: Int) throws(AXError) -> [T]? { - return try valuesForAttribute(attribute.rawValue, startAtIndex: index, maxValues: maxValues) - } - - open func valuesForAttribute - (_ attribute: String, startAtIndex index: Int, maxValues: Int) throws(AXError) -> [T]? { var values: CFArray? let error = AXUIElementCopyAttributeValues( - element, attribute as CFString, index, maxValues, &values + element, attribute.rawCFStringValue, index, maxValues, &values ) - if error == .noValue || error == .attributeUnsupported { - return nil - } + guard + error != .noValue, + error != .attributeUnsupported, + let values + else { return nil } guard error == .success else { throw error } - let array = values! as [AnyObject] + let array = values as [AnyObject] return array.map({ unpackAXValue($0) as! T }) } + @available(*, deprecated, renamed: "valuesForAttribute") + open func valuesForAttribute + (_ attribute: String, startAtIndex index: Int, maxValues: Int) throws(AXError) -> [T]? { + try valuesForAttribute(Attribute(rawValue: attribute), startAtIndex: index, maxValues: maxValues) + } + /// Returns the number of values an array attribute has. /// - returns: The number of values, or `nil` if `attribute` isn't an array (or doesn't exist). open func valueCountForAttribute(_ attribute: Attribute) throws(AXError) -> Int? { From 1b160556f08ebd2fe0013bd49f3daa50a8f2e6bf Mon Sep 17 00:00:00 2001 From: Michael Redig Date: Sat, 14 Jun 2025 16:31:34 -0500 Subject: [PATCH 16/39] (refactor) valueCountForAttribute --- Sources/UIElement.swift | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Sources/UIElement.swift b/Sources/UIElement.swift index e7b06da..76b48c3 100644 --- a/Sources/UIElement.swift +++ b/Sources/UIElement.swift @@ -355,12 +355,8 @@ open class UIElement { /// Returns the number of values an array attribute has. /// - returns: The number of values, or `nil` if `attribute` isn't an array (or doesn't exist). open func valueCountForAttribute(_ attribute: Attribute) throws(AXError) -> Int? { - return try valueCountForAttribute(attribute.rawValue) - } - - open func valueCountForAttribute(_ attribute: String) throws(AXError) -> Int? { var count: Int = 0 - let error = AXUIElementGetAttributeValueCount(element, attribute as CFString, &count) + let error = AXUIElementGetAttributeValueCount(element, attribute.rawCFStringValue, &count) if error == .attributeUnsupported || error == .illegalArgument { return nil @@ -373,6 +369,11 @@ open class UIElement { return count } + @available(*, deprecated, renamed: "valueCountForAttribute") + open func valueCountForAttribute(_ attribute: String) throws(AXError) -> Int? { + try valueCountForAttribute(Attribute(rawValue: attribute)) + } + // MARK: Parameterized attributes /// Returns a list of all parameterized attributes of the element. From 78608744d0f50a2edaaac1985a5cad4468a100f6 Mon Sep 17 00:00:00 2001 From: Michael Redig Date: Sat, 14 Jun 2025 16:31:49 -0500 Subject: [PATCH 17/39] (refactor) parameterizedAttributes --- Sources/UIElement.swift | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/Sources/UIElement.swift b/Sources/UIElement.swift index 76b48c3..e125a9d 100644 --- a/Sources/UIElement.swift +++ b/Sources/UIElement.swift @@ -381,16 +381,15 @@ open class UIElement { /// Parameterized attributes are attributes that require parameters to retrieve. For example, /// the cell contents of a spreadsheet might require the row and column of the cell you want. open func parameterizedAttributes() throws(AXError) -> [Attribute] { - return try parameterizedAttributesAsStrings().compactMap({ Attribute(rawValue: $0) }) - } - - open func parameterizedAttributesAsStrings() throws(AXError) -> [String] { var names: CFArray? let error = AXUIElementCopyParameterizedAttributeNames(element, &names) - if error == .noValue || error == .attributeUnsupported { - return [] - } + guard + error != .noValue, + error != .attributeUnsupported, + let names = names as? [AnyObject], + let strings = names as? [String] + else { return [] } guard error == .success else { throw error @@ -398,7 +397,12 @@ open class UIElement { // We must first convert the CFArray to a native array, then downcast to an array of // strings. - return names! as [AnyObject] as! [String] + return strings.map(Attribute.init(rawValue:)) + } + + @available(*, deprecated, renamed: "parameterizedAttributes") + open func parameterizedAttributesAsStrings() throws(AXError) -> [String] { + try parameterizedAttributes().map(\.rawValue) } /// Returns the value of the parameterized attribute `attribute` with parameter `param`. From 5d6ef0377ce0ee14009116ed8fbf1a8cabcf8c1e Mon Sep 17 00:00:00 2001 From: Michael Redig Date: Sat, 14 Jun 2025 16:33:41 -0500 Subject: [PATCH 18/39] (refactor) parameterizedAttribute --- Sources/UIElement.swift | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/Sources/UIElement.swift b/Sources/UIElement.swift index e125a9d..5a5630f 100644 --- a/Sources/UIElement.swift +++ b/Sources/UIElement.swift @@ -411,24 +411,26 @@ open class UIElement { /// [NSAccessibility Informal Protocol Reference](https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Protocols/NSAccessibility_Protocol/) /// for more info. open func parameterizedAttribute(_ attribute: Attribute, param: U) throws(AXError) -> T? { - return try parameterizedAttribute(attribute.rawValue, param: param) - } - - open func parameterizedAttribute(_ attribute: String, param: U) throws(AXError) -> T? { var value: AnyObject? let error = AXUIElementCopyParameterizedAttributeValue( - element, attribute as CFString, param as AnyObject, &value + element, attribute.rawCFStringValue, param as AnyObject, &value ) - if error == .noValue || error == .attributeUnsupported { - return nil - } + guard + error != .noValue, + error != .attributeUnsupported, + let value + else { return nil } guard error == .success else { throw error } - return (unpackAXValue(value!) as! T) + return (unpackAXValue(value) as! T) + } + + open func parameterizedAttribute(_ attribute: String, param: U) throws(AXError) -> T? { + try parameterizedAttribute(Attribute(rawValue: attribute), param: param) } // MARK: Attribute helpers From 2842e3743d2b54b431f262f37b1e078606844635 Mon Sep 17 00:00:00 2001 From: Michael Redig Date: Sat, 14 Jun 2025 16:39:33 -0500 Subject: [PATCH 19/39] (refactor) actions --- Sources/UIElement.swift | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/Sources/UIElement.swift b/Sources/UIElement.swift index 5a5630f..a9e3316 100644 --- a/Sources/UIElement.swift +++ b/Sources/UIElement.swift @@ -502,23 +502,29 @@ open class UIElement { /// Returns a list of actions that can be performed on the element. open func actions() throws(AXError) -> [Action] { - return try actionsAsStrings().compactMap({ Action(rawValue: $0) }) - } - - open func actionsAsStrings() throws(AXError) -> [String] { var names: CFArray? let error = AXUIElementCopyActionNames(element, &names) if error == .noValue || error == .attributeUnsupported { return [] } + guard + error != .noValue, + error != .attributeUnsupported, + let names = names as? [AnyObject], + let strings = names as? [String] + else { return [] } guard error == .success else { throw error } // We must first convert the CFArray to a native array, then downcast to an array of strings. - return names! as [AnyObject] as! [String] + return strings.map(Action.init(rawValue:)) + } + + open func actionsAsStrings() throws(AXError) -> [String] { + try actions().map(\.rawValue) } /// Returns the human-readable description of `action`. From e9e5bdf1bdaa5805d53e3759237d6b58eb5d6096 Mon Sep 17 00:00:00 2001 From: Michael Redig Date: Sat, 14 Jun 2025 16:40:51 -0500 Subject: [PATCH 20/39] (refactor) restore original order of operations --- Sources/UIElement.swift | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/Sources/UIElement.swift b/Sources/UIElement.swift index a9e3316..37d2e39 100644 --- a/Sources/UIElement.swift +++ b/Sources/UIElement.swift @@ -387,8 +387,7 @@ open class UIElement { guard error != .noValue, error != .attributeUnsupported, - let names = names as? [AnyObject], - let strings = names as? [String] + let names = names as? [AnyObject] else { return [] } guard error == .success else { @@ -397,6 +396,10 @@ open class UIElement { // We must first convert the CFArray to a native array, then downcast to an array of // strings. + guard + let strings = names as? [String] + else { return [] } + return strings.map(Attribute.init(rawValue:)) } @@ -511,8 +514,7 @@ open class UIElement { guard error != .noValue, error != .attributeUnsupported, - let names = names as? [AnyObject], - let strings = names as? [String] + let names = names as? [AnyObject] else { return [] } guard error == .success else { @@ -520,6 +522,10 @@ open class UIElement { } // We must first convert the CFArray to a native array, then downcast to an array of strings. + guard + let strings = names as? [String] + else { return [] } + return strings.map(Action.init(rawValue:)) } From 4d5bde6cbbe126183b7cbe10f5fb385526cc89e9 Mon Sep 17 00:00:00 2001 From: Michael Redig Date: Sat, 14 Jun 2025 16:41:48 -0500 Subject: [PATCH 21/39] (nit) mark deprecations --- Sources/UIElement.swift | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Sources/UIElement.swift b/Sources/UIElement.swift index 37d2e39..9495c85 100644 --- a/Sources/UIElement.swift +++ b/Sources/UIElement.swift @@ -432,6 +432,7 @@ open class UIElement { return (unpackAXValue(value) as! T) } + @available(*, deprecated, renamed: "parameterizedAttribute") open func parameterizedAttribute(_ attribute: String, param: U) throws(AXError) -> T? { try parameterizedAttribute(Attribute(rawValue: attribute), param: param) } @@ -529,6 +530,7 @@ open class UIElement { return strings.map(Action.init(rawValue:)) } + @available(*, deprecated, renamed: "actions") open func actionsAsStrings() throws(AXError) -> [String] { try actions().map(\.rawValue) } From 67e82eabefd148f7f4fe949678e06d31209c10e5 Mon Sep 17 00:00:00 2001 From: Michael Redig Date: Sat, 14 Jun 2025 16:43:54 -0500 Subject: [PATCH 22/39] (refactor) actionDescription --- Sources/UIElement.swift | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/Sources/UIElement.swift b/Sources/UIElement.swift index 9495c85..a6eb206 100644 --- a/Sources/UIElement.swift +++ b/Sources/UIElement.swift @@ -537,22 +537,24 @@ open class UIElement { /// Returns the human-readable description of `action`. open func actionDescription(_ action: Action) throws(AXError) -> String? { - return try actionDescription(action.rawValue) - } - - open func actionDescription(_ action: String) throws(AXError) -> String? { var description: CFString? - let error = AXUIElementCopyActionDescription(element, action as CFString, &description) + let error = AXUIElementCopyActionDescription(element, action.rawCFStringValue, &description) - if error == .noValue || error == .actionUnsupported { - return nil - } + guard + error != .noValue, + error != .attributeUnsupported + else { return nil } guard error == .success else { throw error } - return description! as String + return description as? String + } + + @available(*, deprecated, renamed: "actionDescription") + open func actionDescription(_ action: String) throws(AXError) -> String? { + try actionDescription(Action(rawValue: action)) } /// Performs the action `action` on the element, returning on success. From f0fd34c12b44d221e28bd7f7b7584cb01166b7dc Mon Sep 17 00:00:00 2001 From: Michael Redig Date: Sat, 14 Jun 2025 16:44:45 -0500 Subject: [PATCH 23/39] (refactor) performAction --- Sources/UIElement.swift | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Sources/UIElement.swift b/Sources/UIElement.swift index a6eb206..c00aa2d 100644 --- a/Sources/UIElement.swift +++ b/Sources/UIElement.swift @@ -564,17 +564,18 @@ open class UIElement { /// performed. /// - throws: `Error.ActionUnsupported` if the action is not supported. open func performAction(_ action: Action) throws(AXError) { - try performAction(action.rawValue) - } - - open func performAction(_ action: String) throws(AXError) { - let error = AXUIElementPerformAction(element, action as CFString) + let error = AXUIElementPerformAction(element, action.rawCFStringValue) guard error == .success else { throw error } } + @available(*, deprecated, renamed: "performAction") + open func performAction(_ action: String) throws(AXError) { + try performAction(Action(rawValue: action)) + } + // MARK: - /// Returns the process ID of the application that the element is a part of. From d747e6cd0b590fd72a13cf57f830c5d5581f6006 Mon Sep 17 00:00:00 2001 From: Michael Redig Date: Sat, 14 Jun 2025 16:47:04 -0500 Subject: [PATCH 24/39] (feat) elementAtPosition(_ position: CGPoint) --- Sources/UIElement.swift | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Sources/UIElement.swift b/Sources/UIElement.swift index c00aa2d..5859cbc 100644 --- a/Sources/UIElement.swift +++ b/Sources/UIElement.swift @@ -625,7 +625,11 @@ open class UIElement { throw error } - return UIElement(result!) + return result.map(UIElement.init) + } + + func elementAtPosition(_ position: CGPoint) throws(AXError) -> UIElement? { + try elementAtPosition(Float(position.x), Float(position.y)) } // TODO: convenience functions for attributes From 49a913285c0b0ed67d1cb852b61fdddbf875ae47 Mon Sep 17 00:00:00 2001 From: Michael Redig Date: Sat, 14 Jun 2025 16:54:16 -0500 Subject: [PATCH 25/39] (refactor) revery protocol constraint --- Sources/AXValueCompatibility.swift | 28 ---------------------------- Sources/UIElement.swift | 4 ++-- 2 files changed, 2 insertions(+), 30 deletions(-) delete mode 100644 Sources/AXValueCompatibility.swift diff --git a/Sources/AXValueCompatibility.swift b/Sources/AXValueCompatibility.swift deleted file mode 100644 index 8961b33..0000000 --- a/Sources/AXValueCompatibility.swift +++ /dev/null @@ -1,28 +0,0 @@ -import Cocoa - -public protocol AXValueCompatibility {} - -extension AXValueCompatibility { - func pack() -> AnyObject { - switch self { - case let val as UIElement: - return val.element - case var val as CFRange: - return AXValueCreate(AXValueType(rawValue: kAXValueCFRangeType)!, &val)! - case var val as CGPoint: - return AXValueCreate(AXValueType(rawValue: kAXValueCGPointType)!, &val)! - case var val as CGRect: - return AXValueCreate(AXValueType(rawValue: kAXValueCGRectType)!, &val)! - case var val as CGSize: - return AXValueCreate(AXValueType(rawValue: kAXValueCGSizeType)!, &val)! - default: - return self as AnyObject // must be an object to pass to AX - } - } -} - -extension UIElement: AXValueCompatibility {} -extension CFRange: AXValueCompatibility {} -extension CGPoint: AXValueCompatibility {} -extension CGRect: AXValueCompatibility {} -extension CGSize: AXValueCompatibility {} diff --git a/Sources/UIElement.swift b/Sources/UIElement.swift index 5859cbc..9eab8ec 100644 --- a/Sources/UIElement.swift +++ b/Sources/UIElement.swift @@ -197,7 +197,7 @@ open class UIElement { /// - `Error.AttributeUnsupported`: `attribute` isn't supported. /// - `Error.IllegalArgument`: `value` is an illegal value. /// - `Error.Failure`: A temporary failure occurred. - open func setAttribute(_ attribute: Attribute, value: T) throws(AXError) { + open func setAttribute(_ attribute: Attribute, value: Any) throws(AXError) { let error = AXUIElementSetAttributeValue(element, attribute.rawCFStringValue, packAXValue(value)) guard error == .success else { @@ -206,7 +206,7 @@ open class UIElement { } @available(*, deprecated, renamed: "setAttribute") - open func setAttribute(_ attribute: String, value: T) throws(AXError) { + open func setAttribute(_ attribute: String, value: Any) throws(AXError) { try setAttribute(Attribute(rawValue: attribute), value: value) } From bf8ee466d0a78574d7c1232980994443acc6ad67 Mon Sep 17 00:00:00 2001 From: Michael Redig Date: Sat, 14 Jun 2025 17:00:47 -0500 Subject: [PATCH 26/39] (fix) resolve some deprecations in sample code --- AXSwiftObserverExample/AppDelegate.swift | 8 ++++++-- Sources/Application.swift | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/AXSwiftObserverExample/AppDelegate.swift b/AXSwiftObserverExample/AppDelegate.swift index 1f56849..b032abc 100644 --- a/AXSwiftObserverExample/AppDelegate.swift +++ b/AXSwiftObserverExample/AppDelegate.swift @@ -7,6 +7,11 @@ class AppDelegate: NSObject, NSApplicationDelegate { func applicationDidFinishLaunching(_ aNotification: Notification) { let app = Application.allForBundleID("com.apple.finder").first! + guard UIElement.isProcessTrusted(withPrompt: true) else { + NSLog("No accessibility API permission, exiting") + NSRunningApplication.current.terminate() + return + } do { try startWatcher(app) @@ -18,7 +23,7 @@ class AppDelegate: NSObject, NSApplicationDelegate { func startWatcher(_ app: Application) throws { var updated = false - observer = app.createObserver { (observer: Observer, element: UIElement, event: AXNotification, info: [String: AnyObject]?) in + observer = app.createObserver { (observer: Observer, element: UIElement, event: UIElement.AXNotification, info: [String: AnyObject]?) in var elementDesc: String! if let role = try? element.role()!, role == .window { elementDesc = "\(element) \"\(try! (element.attribute(.title) as String?)!)\"" @@ -55,5 +60,4 @@ class AppDelegate: NSObject, NSApplicationDelegate { func applicationWillTerminate(_ aNotification: Notification) { // Insert code here to tear down your application } - } diff --git a/Sources/Application.swift b/Sources/Application.swift index 7368ef9..6bd556a 100644 --- a/Sources/Application.swift +++ b/Sources/Application.swift @@ -76,7 +76,7 @@ public final class Application: UIElement { /// - returns: An array of `UIElement`s, one for every visible window. Or `nil` if the list /// cannot be retrieved. public func windows() throws -> [UIElement]? { - let axWindows: [AXUIElement]? = try attribute("AXWindows") + let axWindows: [AXUIElement]? = try attribute(.windows) return axWindows?.map({ UIElement($0) }) } From a42fd863bd2bd905e85c9d0ac11564a0c8b147c5 Mon Sep 17 00:00:00 2001 From: Michael Redig Date: Sat, 14 Jun 2025 17:12:26 -0500 Subject: [PATCH 27/39] (fix) indentation as original project intended --- Sources/Application.swift | 20 +- Sources/Constants/AXNotification.swift | 146 ++++---- Sources/Constants/Action.swift | 44 +-- Sources/Constants/Attribute.swift | 460 ++++++++++++------------- Sources/Constants/Orientation.swift | 14 +- Sources/Constants/Role.swift | 132 +++---- Sources/Constants/Subrole.swift | 80 ++--- Sources/Observer.swift | 30 +- Sources/UIElement.swift | 222 ++++++------ 9 files changed, 574 insertions(+), 574 deletions(-) diff --git a/Sources/Application.swift b/Sources/Application.swift index 6bd556a..deb6e40 100644 --- a/Sources/Application.swift +++ b/Sources/Application.swift @@ -7,12 +7,12 @@ public final class Application: UIElement { convenience init?(forKnownProcessID processID: pid_t) { let appElement = AXUIElementCreateApplication(processID) self.init(appElement) - + if processID < 0 { return nil } } - + /// Creates an `Application` from a `NSRunningApplication` instance. /// - returns: The `Application`, or `nil` if the given application is not running. public convenience init?(_ app: NSRunningApplication) { @@ -21,7 +21,7 @@ public final class Application: UIElement { } self.init(forKnownProcessID: app.processIdentifier) } - + /// Create an `Application` from the process ID of a running application. /// - returns: The `Application`, or `nil` if the PID is invalid or the given application /// is not running. @@ -31,7 +31,7 @@ public final class Application: UIElement { } self.init(app) } - + /// Creates an `Application` for every running application with a UI. /// - returns: An array of `Application`s. public class func all() -> [Application] { @@ -40,7 +40,7 @@ public final class Application: UIElement { .filter({ $0.activationPolicy != .prohibited }) .compactMap({ Application($0) }) } - + /// Creates an `Application` for every running instance of the given `bundleID`. /// - returns: A (potentially empty) array of `Application`s. public class func allForBundleID(_ bundleID: String) -> [Application] { @@ -49,7 +49,7 @@ public final class Application: UIElement { .filter({ $0.bundleIdentifier == bundleID }) .compactMap({ Application($0) }) } - + /// Creates an `Observer` on this application, if it is still alive. public func createObserver(_ callback: @escaping Observer.Callback) -> Observer? { do { @@ -60,7 +60,7 @@ public final class Application: UIElement { fatalError("Caught unexpected error creating observer: \(error)") } } - + /// Creates an `Observer` on this application, if it is still alive. public func createObserver(_ callback: @escaping Observer.CallbackWithInfo) -> Observer? { do { @@ -71,15 +71,15 @@ public final class Application: UIElement { fatalError("Caught unexpected error creating observer: \(error)") } } - + /// Returns a list of the application's visible windows. /// - returns: An array of `UIElement`s, one for every visible window. Or `nil` if the list /// cannot be retrieved. public func windows() throws -> [UIElement]? { - let axWindows: [AXUIElement]? = try attribute(.windows) + let axWindows: [AXUIElement]? = try attribute(.windows) return axWindows?.map({ UIElement($0) }) } - + /// Returns the element at the specified top-down coordinates, or nil if there is none. public override func elementAtPosition(_ x: Float, _ y: Float) throws(AXError) -> UIElement? { return try super.elementAtPosition(x, y) diff --git a/Sources/Constants/AXNotification.swift b/Sources/Constants/AXNotification.swift index 362dd49..e5174e9 100644 --- a/Sources/Constants/AXNotification.swift +++ b/Sources/Constants/AXNotification.swift @@ -3,77 +3,77 @@ import Foundation @available(*, deprecated, renamed: "UIElement.AXNotification", message: "Provided for drop in replacement, but now the type is located under the `UIElement` namespace.") public typealias AXNotification = UIElement.AXNotification extension UIElement { - /// Provides all known possible notifications you can subscribe to with `Observer`. - /// - seeAlso: [Notificatons](https://developer.apple.com/library/mac/documentation/AppKit/Reference/NSAccessibility_Protocol_Reference/index.html#//apple_ref/c/data/NSAccessibilityAnnouncementRequestedNotification) - public struct AXNotification: RawRepresentable, Hashable, Sendable { - public let rawValue: String - public var rawCFStringValue: CFString { rawValue as CFString } - - public init(rawValue: String) { - self.rawValue = rawValue - } - - // Focus notifications - public static let mainWindowChanged = AXNotification(rawValue: "AXMainWindowChanged") - public static let focusedWindowChanged = AXNotification(rawValue: "AXFocusedWindowChanged") - public static let focusedUIElementChanged = AXNotification(rawValue: "AXFocusedUIElementChanged") - public static let focusedTabChanged = AXNotification(rawValue: "AXFocusedTabChanged") - - // Application notifications - public static let applicationActivated = AXNotification(rawValue: "AXApplicationActivated") - public static let applicationDeactivated = AXNotification(rawValue: "AXApplicationDeactivated") - public static let applicationHidden = AXNotification(rawValue: "AXApplicationHidden") - public static let applicationShown = AXNotification(rawValue: "AXApplicationShown") - - // Window notifications - public static let windowCreated = AXNotification(rawValue: "AXWindowCreated") - public static let windowMoved = AXNotification(rawValue: "AXWindowMoved") - public static let windowResized = AXNotification(rawValue: "AXWindowResized") - public static let windowMiniaturized = AXNotification(rawValue: "AXWindowMiniaturized") - public static let windowDeminiaturized = AXNotification(rawValue: "AXWindowDeminiaturized") - - // Drawer & sheet notifications - public static let drawerCreated = AXNotification(rawValue: "AXDrawerCreated") - public static let sheetCreated = AXNotification(rawValue: "AXSheetCreated") - - // Element notifications - public static let uiElementDestroyed = AXNotification(rawValue: "AXUIElementDestroyed") - public static let valueChanged = AXNotification(rawValue: "AXValueChanged") - public static let titleChanged = AXNotification(rawValue: "AXTitleChanged") - public static let resized = AXNotification(rawValue: "AXResized") - public static let moved = AXNotification(rawValue: "AXMoved") - public static let created = AXNotification(rawValue: "AXCreated") - - // Used when UI changes require the attention of assistive application. Pass along a user info - // dictionary with the key NSAccessibilityUIElementsKey and an array of elements that have been - // added or changed as a result of this layout change. - public static let layoutChanged = AXNotification(rawValue: "AXLayoutChanged") - - // Misc notifications - public static let helpTagCreated = AXNotification(rawValue: "AXHelpTagCreated") - public static let selectedTextChanged = AXNotification(rawValue: "AXSelectedTextChanged") - public static let rowCountChanged = AXNotification(rawValue: "AXRowCountChanged") - public static let selectedChildrenChanged = AXNotification(rawValue: "AXSelectedChildrenChanged") - public static let selectedRowsChanged = AXNotification(rawValue: "AXSelectedRowsChanged") - public static let selectedColumnsChanged = AXNotification(rawValue: "AXSelectedColumnsChanged") - public static let loadComplete = AXNotification(rawValue: "AXLoadComplete") - - public static let rowExpanded = AXNotification(rawValue: "AXRowExpanded") - public static let rowCollapsed = AXNotification(rawValue: "AXRowCollapsed") - - // Cell-table notifications - public static let selectedCellsChanged = AXNotification(rawValue: "AXSelectedCellsChanged") - - // Layout area notifications - public static let unitsChanged = AXNotification(rawValue: "AXUnitsChanged") - public static let selectedChildrenMoved = AXNotification(rawValue: "AXSelectedChildrenMoved") - - // This notification allows an application to request that an announcement be made to the user - // by an assistive application such as VoiceOver. The notification requires a user info - // dictionary with the key NSAccessibilityAnnouncementKey and the announcement as a localized - // string. In addition, the key NSAccessibilityAnnouncementPriorityKey should also be used to - // help an assistive application determine the importance of this announcement. This - // notification should be posted for the application element. - public static let announcementRequested = AXNotification(rawValue: "AXAnnouncementRequested") - } + /// Provides all known possible notifications you can subscribe to with `Observer`. + /// - seeAlso: [Notificatons](https://developer.apple.com/library/mac/documentation/AppKit/Reference/NSAccessibility_Protocol_Reference/index.html#//apple_ref/c/data/NSAccessibilityAnnouncementRequestedNotification) + public struct AXNotification: RawRepresentable, Hashable, Sendable { + public let rawValue: String + public var rawCFStringValue: CFString { rawValue as CFString } + + public init(rawValue: String) { + self.rawValue = rawValue + } + + // Focus notifications + public static let mainWindowChanged = AXNotification(rawValue: "AXMainWindowChanged") + public static let focusedWindowChanged = AXNotification(rawValue: "AXFocusedWindowChanged") + public static let focusedUIElementChanged = AXNotification(rawValue: "AXFocusedUIElementChanged") + public static let focusedTabChanged = AXNotification(rawValue: "AXFocusedTabChanged") + + // Application notifications + public static let applicationActivated = AXNotification(rawValue: "AXApplicationActivated") + public static let applicationDeactivated = AXNotification(rawValue: "AXApplicationDeactivated") + public static let applicationHidden = AXNotification(rawValue: "AXApplicationHidden") + public static let applicationShown = AXNotification(rawValue: "AXApplicationShown") + + // Window notifications + public static let windowCreated = AXNotification(rawValue: "AXWindowCreated") + public static let windowMoved = AXNotification(rawValue: "AXWindowMoved") + public static let windowResized = AXNotification(rawValue: "AXWindowResized") + public static let windowMiniaturized = AXNotification(rawValue: "AXWindowMiniaturized") + public static let windowDeminiaturized = AXNotification(rawValue: "AXWindowDeminiaturized") + + // Drawer & sheet notifications + public static let drawerCreated = AXNotification(rawValue: "AXDrawerCreated") + public static let sheetCreated = AXNotification(rawValue: "AXSheetCreated") + + // Element notifications + public static let uiElementDestroyed = AXNotification(rawValue: "AXUIElementDestroyed") + public static let valueChanged = AXNotification(rawValue: "AXValueChanged") + public static let titleChanged = AXNotification(rawValue: "AXTitleChanged") + public static let resized = AXNotification(rawValue: "AXResized") + public static let moved = AXNotification(rawValue: "AXMoved") + public static let created = AXNotification(rawValue: "AXCreated") + + // Used when UI changes require the attention of assistive application. Pass along a user info + // dictionary with the key NSAccessibilityUIElementsKey and an array of elements that have been + // added or changed as a result of this layout change. + public static let layoutChanged = AXNotification(rawValue: "AXLayoutChanged") + + // Misc notifications + public static let helpTagCreated = AXNotification(rawValue: "AXHelpTagCreated") + public static let selectedTextChanged = AXNotification(rawValue: "AXSelectedTextChanged") + public static let rowCountChanged = AXNotification(rawValue: "AXRowCountChanged") + public static let selectedChildrenChanged = AXNotification(rawValue: "AXSelectedChildrenChanged") + public static let selectedRowsChanged = AXNotification(rawValue: "AXSelectedRowsChanged") + public static let selectedColumnsChanged = AXNotification(rawValue: "AXSelectedColumnsChanged") + public static let loadComplete = AXNotification(rawValue: "AXLoadComplete") + + public static let rowExpanded = AXNotification(rawValue: "AXRowExpanded") + public static let rowCollapsed = AXNotification(rawValue: "AXRowCollapsed") + + // Cell-table notifications + public static let selectedCellsChanged = AXNotification(rawValue: "AXSelectedCellsChanged") + + // Layout area notifications + public static let unitsChanged = AXNotification(rawValue: "AXUnitsChanged") + public static let selectedChildrenMoved = AXNotification(rawValue: "AXSelectedChildrenMoved") + + // This notification allows an application to request that an announcement be made to the user + // by an assistive application such as VoiceOver. The notification requires a user info + // dictionary with the key NSAccessibilityAnnouncementKey and the announcement as a localized + // string. In addition, the key NSAccessibilityAnnouncementPriorityKey should also be used to + // help an assistive application determine the importance of this announcement. This + // notification should be posted for the application element. + public static let announcementRequested = AXNotification(rawValue: "AXAnnouncementRequested") + } } diff --git a/Sources/Constants/Action.swift b/Sources/Constants/Action.swift index 1da9345..815fb1d 100644 --- a/Sources/Constants/Action.swift +++ b/Sources/Constants/Action.swift @@ -3,26 +3,26 @@ import Foundation @available(*, deprecated, renamed: "UIElement.Action", message: "Provided for drop in replacement, but now the type is located under the `UIElement` namespace.") public typealias Action = UIElement.Action extension UIElement { - /// Provides all known actions a `UIElement` can support. - /// - seeAlso: [Actions](https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Protocols/NSAccessibility_Protocol/#//apple_ref/doc/constant_group/Actions) - public struct Action: RawRepresentable, Hashable, Sendable { - public let rawValue: String - public var rawCFStringValue: CFString { rawValue as CFString } - - public init(rawValue: String) { - self.rawValue = rawValue - } - - public static let press = Action(rawValue: "AXPress") - public static let increment = Action(rawValue: "AXIncrement") - public static let decrement = Action(rawValue: "AXDecrement") - public static let confirm = Action(rawValue: "AXConfirm") - public static let pick = Action(rawValue: "AXPick") - public static let cancel = Action(rawValue: "AXCancel") - public static let raise = Action(rawValue: "AXRaise") - public static let showMenu = Action(rawValue: "AXShowMenu") - public static let delete = Action(rawValue: "AXDelete") - public static let showAlternateUI = Action(rawValue: "AXShowAlternateUI") - public static let showDefaultUI = Action(rawValue: "AXShowDefaultUI") - } + /// Provides all known actions a `UIElement` can support. + /// - seeAlso: [Actions](https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Protocols/NSAccessibility_Protocol/#//apple_ref/doc/constant_group/Actions) + public struct Action: RawRepresentable, Hashable, Sendable { + public let rawValue: String + public var rawCFStringValue: CFString { rawValue as CFString } + + public init(rawValue: String) { + self.rawValue = rawValue + } + + public static let press = Action(rawValue: "AXPress") + public static let increment = Action(rawValue: "AXIncrement") + public static let decrement = Action(rawValue: "AXDecrement") + public static let confirm = Action(rawValue: "AXConfirm") + public static let pick = Action(rawValue: "AXPick") + public static let cancel = Action(rawValue: "AXCancel") + public static let raise = Action(rawValue: "AXRaise") + public static let showMenu = Action(rawValue: "AXShowMenu") + public static let delete = Action(rawValue: "AXDelete") + public static let showAlternateUI = Action(rawValue: "AXShowAlternateUI") + public static let showDefaultUI = Action(rawValue: "AXShowDefaultUI") + } } diff --git a/Sources/Constants/Attribute.swift b/Sources/Constants/Attribute.swift index 96862dc..f8ecbc5 100644 --- a/Sources/Constants/Attribute.swift +++ b/Sources/Constants/Attribute.swift @@ -3,234 +3,234 @@ import Foundation @available(*, deprecated, renamed: "UIElement.Attribute", message: "Provided for drop in replacement, but now the type is located under the `UIElement` namespace.") public typealias Attribute = UIElement.Attribute extension UIElement { - public struct Attribute: RawRepresentable, Hashable, Sendable { - public let rawValue: String - public var rawCFStringValue: CFString { rawValue as CFString } - - public init(rawValue: String) { - self.rawValue = rawValue - } - - // Standard attributes - public static let role = Attribute(rawValue: "AXRole") //(NSString *) - type, non-localized (e.g. radioButton) - public static let roleDescription = Attribute(rawValue: "AXRoleDescription") //(NSString *) - user readable role (e.g. "radio button") - public static let subrole = Attribute(rawValue: "AXSubrole") //(NSString *) - type, non-localized (e.g. closeButton) - public static let help = Attribute(rawValue: "AXHelp") //(NSString *) - instance description (e.g. a tool tip) - public static let value = Attribute(rawValue: "AXValue") //(id) - element's value - public static let minValue = Attribute(rawValue: "AXMinValue") //(id) - element's min value - public static let maxValue = Attribute(rawValue: "AXMaxValue") //(id) - element's max value - public static let enabled = Attribute(rawValue: "AXEnabled") //(NSNumber *) - (boolValue) responds to user? - public static let focused = Attribute(rawValue: "AXFocused") //(NSNumber *) - (boolValue) has keyboard focus? - public static let parent = Attribute(rawValue: "AXParent") //(id) - element containing you - public static let children = Attribute(rawValue: "AXChildren") //(NSArray *) - elements you contain - public static let window = Attribute(rawValue: "AXWindow") //(id) - UIElement for the containing window - public static let topLevelUIElement = Attribute(rawValue: "AXTopLevelUIElement") //(id) - UIElement for the containing top level element - public static let selectedChildren = Attribute(rawValue: "AXSelectedChildren") //(NSArray *) - child elements which are selected - public static let visibleChildren = Attribute(rawValue: "AXVisibleChildren") //(NSArray *) - child elements which are visible - public static let position = Attribute(rawValue: "AXPosition") //(NSValue *) - (pointValue) position in screen coords - public static let size = Attribute(rawValue: "AXSize") //(NSValue *) - (sizeValue) size - public static let frame = Attribute(rawValue: "AXFrame") //(NSValue *) - (rectValue) frame - public static let contents = Attribute(rawValue: "AXContents") //(NSArray *) - main elements - public static let title = Attribute(rawValue: "AXTitle") //(NSString *) - visible text (e.g. of a push button) - public static let description = Attribute(rawValue: "AXDescription") //(NSString *) - instance description - public static let shownMenu = Attribute(rawValue: "AXShownMenu") //(id) - menu being displayed - public static let valueDescription = Attribute(rawValue: "AXValueDescription") //(NSString *) - text description of value - - public static let sharedFocusElements = Attribute(rawValue: "AXSharedFocusElements") //(NSArray *) - elements that share focus - - // Misc attributes - public static let previousContents = Attribute(rawValue: "AXPreviousContents") //(NSArray *) - main elements - public static let nextContents = Attribute(rawValue: "AXNextContents") //(NSArray *) - main elements - public static let header = Attribute(rawValue: "AXHeader") //(id) - UIElement for header. - public static let edited = Attribute(rawValue: "AXEdited") //(NSNumber *) - (boolValue) is it dirty? - public static let tabs = Attribute(rawValue: "AXTabs") //(NSArray *) - UIElements for tabs - public static let horizontalScrollBar = Attribute(rawValue: "AXHorizontalScrollBar") //(id) - UIElement for the horizontal scroller - public static let verticalScrollBar = Attribute(rawValue: "AXVerticalScrollBar") //(id) - UIElement for the vertical scroller - public static let overflowButton = Attribute(rawValue: "AXOverflowButton") //(id) - UIElement for overflow - public static let incrementButton = Attribute(rawValue: "AXIncrementButton") //(id) - UIElement for increment - public static let decrementButton = Attribute(rawValue: "AXDecrementButton") //(id) - UIElement for decrement - public static let filename = Attribute(rawValue: "AXFilename") //(NSString *) - filename - public static let expanded = Attribute(rawValue: "AXExpanded") //(NSNumber *) - (boolValue) is expanded? - public static let selected = Attribute(rawValue: "AXSelected") //(NSNumber *) - (boolValue) is selected? - public static let splitters = Attribute(rawValue: "AXSplitters") //(NSArray *) - UIElements for splitters - public static let document = Attribute(rawValue: "AXDocument") //(NSString *) - url as string - for open document - public static let activationPoint = Attribute(rawValue: "AXActivationPoint") //(NSValue *) - (pointValue) - - public static let url = Attribute(rawValue: "AXURL") //(NSURL *) - url - public static let index = Attribute(rawValue: "AXIndex") //(NSNumber *) - (intValue) - - public static let rowCount = Attribute(rawValue: "AXRowCount") //(NSNumber *) - (intValue) number of rows - - public static let columnCount = Attribute(rawValue: "AXColumnCount") //(NSNumber *) - (intValue) number of columns - - public static let orderedByRow = Attribute(rawValue: "AXOrderedByRow") //(NSNumber *) - (boolValue) is ordered by row? - - public static let warningValue = Attribute(rawValue: "AXWarningValue") //(id) - warning value of a level indicator, typically a number - - public static let criticalValue = Attribute(rawValue: "AXCriticalValue") //(id) - critical value of a level indicator, typically a number - - public static let placeholderValue = Attribute(rawValue: "AXPlaceholderValue") //(NSString *) - placeholder value of a control such as a text field - - public static let containsProtectedContent = Attribute(rawValue: "AXContainsProtectedContent") // (NSNumber *) - (boolValue) contains protected content? - public static let alternateUIVisible = Attribute(rawValue: "AXAlternateUIVisible") //(NSNumber *) - (boolValue) - - // Linkage attributes - public static let titleUIElement = Attribute(rawValue: "AXTitleUIElement") //(id) - UIElement for the title - public static let servesAsTitleForUIElements = Attribute(rawValue: "AXServesAsTitleForUIElements") //(NSArray *) - UIElements this titles - public static let linkedUIElements = Attribute(rawValue: "AXLinkedUIElements") //(NSArray *) - corresponding UIElements - - // Text-specific attributes - public static let selectedText = Attribute(rawValue: "AXSelectedText") //(NSString *) - selected text - public static let selectedTextRange = Attribute(rawValue: "AXSelectedTextRange") //(NSValue *) - (rangeValue) range of selected text - public static let numberOfCharacters = Attribute(rawValue: "AXNumberOfCharacters") //(NSNumber *) - number of characters - public static let visibleCharacterRange = Attribute(rawValue: "AXVisibleCharacterRange") //(NSValue *) - (rangeValue) range of visible text - public static let sharedTextUIElements = Attribute(rawValue: "AXSharedTextUIElements") //(NSArray *) - text views sharing text - public static let sharedCharacterRange = Attribute(rawValue: "AXSharedCharacterRange") //(NSValue *) - (rangeValue) part of shared text in this view - public static let insertionPointLineNumber = Attribute(rawValue: "AXInsertionPointLineNumber") //(NSNumber *) - line# containing caret - public static let selectedTextRanges = Attribute(rawValue: "AXSelectedTextRanges") //(NSArray *) - array of NSValue (rangeValue) ranges of selected text - /// - note: private/undocumented attribute - public static let textInputMarkedRange = Attribute(rawValue: "AXTextInputMarkedRange") - - // Parameterized text-specific attributes - public static let lineForIndexParameterized = Attribute(rawValue: "AXLineForIndexParameterized") //(NSNumber *) - line# for char index; param:(NSNumber *) - public static let rangeForLineParameterized = Attribute(rawValue: "AXRangeForLineParameterized") //(NSValue *) - (rangeValue) range of line; param:(NSNumber *) - public static let stringForRangeParameterized = Attribute(rawValue: "AXStringForRangeParameterized") //(NSString *) - substring; param:(NSValue * - rangeValue) - public static let rangeForPositionParameterized = Attribute(rawValue: "AXRangeForPositionParameterized") //(NSValue *) - (rangeValue) composed char range; param:(NSValue * - pointValue) - public static let rangeForIndexParameterized = Attribute(rawValue: "AXRangeForIndexParameterized") //(NSValue *) - (rangeValue) composed char range; param:(NSNumber *) - public static let boundsForRangeParameterized = Attribute(rawValue: "AXBoundsForRangeParameterized") //(NSValue *) - (rectValue) bounds of text; param:(NSValue * - rangeValue) - public static let rtfForRangeParameterized = Attribute(rawValue: "AXRTFForRangeParameterized") //(NSData *) - rtf for text; param:(NSValue * - rangeValue) - public static let styleRangeForIndexParameterized = Attribute(rawValue: "AXStyleRangeForIndexParameterized") //(NSValue *) - (rangeValue) extent of style run; param:(NSNumber *) - public static let attributedStringForRangeParameterized = Attribute(rawValue: "AXAttributedStringForRangeParameterized") //(NSAttributedString *) - does _not_ use attributes from Appkit/AttributedString.h - - // Text attributed string attributes and constants - public static let fontText = Attribute(rawValue: "AXFontText") //(NSDictionary *) - NSAccessibilityFontXXXKey's - public static let foregroundColorText = Attribute(rawValue: "AXForegroundColorText") //CGColorRef - public static let backgroundColorText = Attribute(rawValue: "AXBackgroundColorText") //CGColorRef - public static let underlineColorText = Attribute(rawValue: "AXUnderlineColorText") //CGColorRef - public static let strikethroughColorText = Attribute(rawValue: "AXStrikethroughColorText") //CGColorRef - public static let underlineText = Attribute(rawValue: "AXUnderlineText") //(NSNumber *) - underline style - public static let superscriptText = Attribute(rawValue: "AXSuperscriptText") //(NSNumber *) - superscript>0, subscript<0 - public static let strikethroughText = Attribute(rawValue: "AXStrikethroughText") //(NSNumber *) - (boolValue) - public static let shadowText = Attribute(rawValue: "AXShadowText") //(NSNumber *) - (boolValue) - public static let attachmentText = Attribute(rawValue: "AXAttachmentText") //id - corresponding element - public static let linkText = Attribute(rawValue: "AXLinkText") //id - corresponding element - public static let autocorrectedText = Attribute(rawValue: "AXAutocorrectedText") //(NSNumber *) - (boolValue) - - // Textual list attributes and constants. Examples: unordered or ordered lists in a document. - public static let listItemPrefixText = Attribute(rawValue: "AXListItemPrefixText") // NSAttributedString, the prepended string of the list item. If the string is a common unicode character (e.g. a bullet •), return that unicode character. For lists with images before the text, return a reasonable label of the image. - public static let listItemIndexText = Attribute(rawValue: "AXListItemIndexText") // NSNumber, integerValue of the line index. Each list item increments the index, even for unordered lists. The first item should have index 0. - public static let listItemLevelText = Attribute(rawValue: "AXListItemLevelText") // NSNumber, integerValue of the indent level. Each sublist increments the level. The first item should have level 0. - - // MisspelledText attributes - public static let misspelledText = Attribute(rawValue: "AXMisspelledText") //(NSNumber *) - (boolValue) - public static let markedMisspelledText = Attribute(rawValue: "AXMarkedMisspelledText") //(NSNumber *) - (boolValue) - - // Window-specific attributes - public static let main = Attribute(rawValue: "AXMain") //(NSNumber *) - (boolValue) is it the main window? - public static let minimized = Attribute(rawValue: "AXMinimized") //(NSNumber *) - (boolValue) is window minimized? - public static let closeButton = Attribute(rawValue: "AXCloseButton") //(id) - UIElement for close box (or nil) - public static let zoomButton = Attribute(rawValue: "AXZoomButton") //(id) - UIElement for zoom box (or nil) - public static let minimizeButton = Attribute(rawValue: "AXMinimizeButton") //(id) - UIElement for miniaturize box (or nil) - public static let toolbarButton = Attribute(rawValue: "AXToolbarButton") //(id) - UIElement for toolbar box (or nil) - public static let proxy = Attribute(rawValue: "AXProxy") //(id) - UIElement for title's icon (or nil) - public static let growArea = Attribute(rawValue: "AXGrowArea") //(id) - UIElement for grow box (or nil) - public static let modal = Attribute(rawValue: "AXModal") //(NSNumber *) - (boolValue) is the window modal - public static let defaultButton = Attribute(rawValue: "AXDefaultButton") //(id) - UIElement for default button - public static let cancelButton = Attribute(rawValue: "AXCancelButton") //(id) - UIElement for cancel button - public static let fullScreenButton = Attribute(rawValue: "AXFullScreenButton") //(id) - UIElement for full screen button (or nil) - /// - note: private/undocumented attribute - public static let fullScreen = Attribute(rawValue: "AXFullScreen") //(NSNumber *) - (boolValue) is the window fullscreen - - // Application-specific attributes - public static let menuBar = Attribute(rawValue: "AXMenuBar") //(id) - UIElement for the menu bar - public static let windows = Attribute(rawValue: "AXWindows") //(NSArray *) - UIElements for the windows - public static let frontmost = Attribute(rawValue: "AXFrontmost") //(NSNumber *) - (boolValue) is the app active? - public static let hidden = Attribute(rawValue: "AXHidden") //(NSNumber *) - (boolValue) is the app hidden? - public static let mainWindow = Attribute(rawValue: "AXMainWindow") //(id) - UIElement for the main window. - public static let focusedWindow = Attribute(rawValue: "AXFocusedWindow") //(id) - UIElement for the key window. - public static let focusedUIElement = Attribute(rawValue: "AXFocusedUIElement") //(id) - Currently focused UIElement. - public static let extrasMenuBar = Attribute(rawValue: "AXExtrasMenuBar") //(id) - UIElement for the application extras menu bar. - /// - note: private/undocumented attribute - public static let enhancedUserInterface = Attribute(rawValue: "AXEnhancedUserInterface") //(NSNumber *) - (boolValue) is the enhanced user interface active? - - public static let orientation = Attribute(rawValue: "AXOrientation") //(NSString *) - NSAccessibilityXXXOrientationValue - - public static let columnTitles = Attribute(rawValue: "AXColumnTitles") //(NSArray *) - UIElements for titles - - public static let searchButton = Attribute(rawValue: "AXSearchButton") //(id) - UIElement for search field search btn - public static let searchMenu = Attribute(rawValue: "AXSearchMenu") //(id) - UIElement for search field menu - public static let clearButton = Attribute(rawValue: "AXClearButton") //(id) - UIElement for search field clear btn - - // Table/outline view attributes - public static let rows = Attribute(rawValue: "AXRows") //(NSArray *) - UIElements for rows - public static let visibleRows = Attribute(rawValue: "AXVisibleRows") //(NSArray *) - UIElements for visible rows - public static let selectedRows = Attribute(rawValue: "AXSelectedRows") //(NSArray *) - UIElements for selected rows - public static let columns = Attribute(rawValue: "AXColumns") //(NSArray *) - UIElements for columns - public static let visibleColumns = Attribute(rawValue: "AXVisibleColumns") //(NSArray *) - UIElements for visible columns - public static let selectedColumns = Attribute(rawValue: "AXSelectedColumns") //(NSArray *) - UIElements for selected columns - public static let sortDirection = Attribute(rawValue: "AXSortDirection") //(NSString *) - see sort direction values below - - // Cell-based table attributes - public static let selectedCells = Attribute(rawValue: "AXSelectedCells") //(NSArray *) - UIElements for selected cells - public static let visibleCells = Attribute(rawValue: "AXVisibleCells") //(NSArray *) - UIElements for visible cells - public static let rowHeaderUIElements = Attribute(rawValue: "AXRowHeaderUIElements") //(NSArray *) - UIElements for row headers - public static let columnHeaderUIElements = Attribute(rawValue: "AXColumnHeaderUIElements") //(NSArray *) - UIElements for column headers - - // Cell-based table parameterized attributes. The parameter for this attribute is an NSArray containing two NSNumbers, the first NSNumber specifies the column index, the second NSNumber specifies the row index. - public static let cellForColumnAndRowParameterized = Attribute(rawValue: "AXCellForColumnAndRowParameterized") // (id) - UIElement for cell at specified row and column - - // Cell attributes. The index range contains both the starting index, and the index span in a table. - public static let rowIndexRange = Attribute(rawValue: "AXRowIndexRange") //(NSValue *) - (rangeValue) location and row span - public static let columnIndexRange = Attribute(rawValue: "AXColumnIndexRange") //(NSValue *) - (rangeValue) location and column span - - // Layout area attributes - public static let horizontalUnits = Attribute(rawValue: "AXHorizontalUnits") //(NSString *) - see ruler unit values below - public static let verticalUnits = Attribute(rawValue: "AXVerticalUnits") //(NSString *) - see ruler unit values below - public static let horizontalUnitDescription = Attribute(rawValue: "AXHorizontalUnitDescription") //(NSString *) - public static let verticalUnitDescription = Attribute(rawValue: "AXVerticalUnitDescription") //(NSString *) - - // Layout area parameterized attributes - public static let layoutPointForScreenPointParameterized = "Attribute(rawValue: AXLayoutPointForScreenPointParameterized" //)(NSValue *) - (pointValue); param:(NSValue * - pointValue) - public static let layoutSizeForScreenSizeParameterized = Attribute(rawValue: "AXLayoutSizeForScreenSizeParameterized") //(NSValue *) - (sizeValue); param:(NSValue * - sizeValue) - public static let screenPointForLayoutPointParameterized = "Attribute(rawValue: AXScreenPointForLayoutPointParameterized" //)(NSValue *) - (pointValue); param:(NSValue * - pointValue) - public static let screenSizeForLayoutSizeParameterized = Attribute(rawValue: "AXScreenSizeForLayoutSizeParameterized") //(NSValue *) - (sizeValue); param:(NSValue * - sizeValue) - - // Layout item attributes - public static let handles = Attribute(rawValue: "AXHandles") //(NSArray *) - UIElements for handles - - // Outline attributes - public static let disclosing = Attribute(rawValue: "AXDisclosing") //(NSNumber *) - (boolValue) is disclosing rows? - public static let disclosedRows = Attribute(rawValue: "AXDisclosedRows") //(NSArray *) - UIElements for disclosed rows - public static let disclosedByRow = Attribute(rawValue: "AXDisclosedByRow") //(id) - UIElement for disclosing row - public static let disclosureLevel = Attribute(rawValue: "AXDisclosureLevel") //(NSNumber *) - indentation level - - // Slider attributes - public static let allowedValues = Attribute(rawValue: "AXAllowedValues") //(NSArray *) - array of allowed values - public static let labelUIElements = Attribute(rawValue: "AXLabelUIElements") //(NSArray *) - array of label UIElements - public static let labelValue = Attribute(rawValue: "AXLabelValue") //(NSNumber *) - value of a label UIElement - - // Matte attributes - // Attributes no longer supported - public static let matteHole = Attribute(rawValue: "AXMatteHole") //(NSValue *) - (rect value) bounds of matte hole in screen coords - public static let matteContentUIElement = Attribute(rawValue: "AXMatteContentUIElement") //(id) - UIElement clipped by the matte - - // Ruler view attributes - public static let markerUIElements = Attribute(rawValue: "AXMarkerUIElements") //(NSArray *) - public static let markerValues = Attribute(rawValue: "AXMarkerValues") // - public static let markerGroupUIElement = Attribute(rawValue: "AXMarkerGroupUIElement") //(id) - public static let units = Attribute(rawValue: "AXUnits") //(NSString *) - see ruler unit values below - public static let unitDescription = Attribute(rawValue: "AXUnitDescription") //(NSString *) - public static let markerType = Attribute(rawValue: "AXMarkerType") //(NSString *) - see ruler marker type values below - public static let markerTypeDescription = Attribute(rawValue: "AXMarkerTypeDescription") //(NSString *) - - // UI element identification attributes - public static let identifier = Attribute(rawValue: "AXIdentifier") //(NSString *) - - // System-wide attributes - public static let focusedApplication = Attribute(rawValue: "AXFocusedApplication") - - // Unknown attributes - public static let functionRowTopLevelElements = Attribute(rawValue: "AXFunctionRowTopLevelElements") - public static let childrenInNavigationOrder = Attribute(rawValue: "AXChildrenInNavigationOrder") - } + public struct Attribute: RawRepresentable, Hashable, Sendable { + public let rawValue: String + public var rawCFStringValue: CFString { rawValue as CFString } + + public init(rawValue: String) { + self.rawValue = rawValue + } + + // Standard attributes + public static let role = Attribute(rawValue: "AXRole") //(NSString *) - type, non-localized (e.g. radioButton) + public static let roleDescription = Attribute(rawValue: "AXRoleDescription") //(NSString *) - user readable role (e.g. "radio button") + public static let subrole = Attribute(rawValue: "AXSubrole") //(NSString *) - type, non-localized (e.g. closeButton) + public static let help = Attribute(rawValue: "AXHelp") //(NSString *) - instance description (e.g. a tool tip) + public static let value = Attribute(rawValue: "AXValue") //(id) - element's value + public static let minValue = Attribute(rawValue: "AXMinValue") //(id) - element's min value + public static let maxValue = Attribute(rawValue: "AXMaxValue") //(id) - element's max value + public static let enabled = Attribute(rawValue: "AXEnabled") //(NSNumber *) - (boolValue) responds to user? + public static let focused = Attribute(rawValue: "AXFocused") //(NSNumber *) - (boolValue) has keyboard focus? + public static let parent = Attribute(rawValue: "AXParent") //(id) - element containing you + public static let children = Attribute(rawValue: "AXChildren") //(NSArray *) - elements you contain + public static let window = Attribute(rawValue: "AXWindow") //(id) - UIElement for the containing window + public static let topLevelUIElement = Attribute(rawValue: "AXTopLevelUIElement") //(id) - UIElement for the containing top level element + public static let selectedChildren = Attribute(rawValue: "AXSelectedChildren") //(NSArray *) - child elements which are selected + public static let visibleChildren = Attribute(rawValue: "AXVisibleChildren") //(NSArray *) - child elements which are visible + public static let position = Attribute(rawValue: "AXPosition") //(NSValue *) - (pointValue) position in screen coords + public static let size = Attribute(rawValue: "AXSize") //(NSValue *) - (sizeValue) size + public static let frame = Attribute(rawValue: "AXFrame") //(NSValue *) - (rectValue) frame + public static let contents = Attribute(rawValue: "AXContents") //(NSArray *) - main elements + public static let title = Attribute(rawValue: "AXTitle") //(NSString *) - visible text (e.g. of a push button) + public static let description = Attribute(rawValue: "AXDescription") //(NSString *) - instance description + public static let shownMenu = Attribute(rawValue: "AXShownMenu") //(id) - menu being displayed + public static let valueDescription = Attribute(rawValue: "AXValueDescription") //(NSString *) - text description of value + + public static let sharedFocusElements = Attribute(rawValue: "AXSharedFocusElements") //(NSArray *) - elements that share focus + + // Misc attributes + public static let previousContents = Attribute(rawValue: "AXPreviousContents") //(NSArray *) - main elements + public static let nextContents = Attribute(rawValue: "AXNextContents") //(NSArray *) - main elements + public static let header = Attribute(rawValue: "AXHeader") //(id) - UIElement for header. + public static let edited = Attribute(rawValue: "AXEdited") //(NSNumber *) - (boolValue) is it dirty? + public static let tabs = Attribute(rawValue: "AXTabs") //(NSArray *) - UIElements for tabs + public static let horizontalScrollBar = Attribute(rawValue: "AXHorizontalScrollBar") //(id) - UIElement for the horizontal scroller + public static let verticalScrollBar = Attribute(rawValue: "AXVerticalScrollBar") //(id) - UIElement for the vertical scroller + public static let overflowButton = Attribute(rawValue: "AXOverflowButton") //(id) - UIElement for overflow + public static let incrementButton = Attribute(rawValue: "AXIncrementButton") //(id) - UIElement for increment + public static let decrementButton = Attribute(rawValue: "AXDecrementButton") //(id) - UIElement for decrement + public static let filename = Attribute(rawValue: "AXFilename") //(NSString *) - filename + public static let expanded = Attribute(rawValue: "AXExpanded") //(NSNumber *) - (boolValue) is expanded? + public static let selected = Attribute(rawValue: "AXSelected") //(NSNumber *) - (boolValue) is selected? + public static let splitters = Attribute(rawValue: "AXSplitters") //(NSArray *) - UIElements for splitters + public static let document = Attribute(rawValue: "AXDocument") //(NSString *) - url as string - for open document + public static let activationPoint = Attribute(rawValue: "AXActivationPoint") //(NSValue *) - (pointValue) + + public static let url = Attribute(rawValue: "AXURL") //(NSURL *) - url + public static let index = Attribute(rawValue: "AXIndex") //(NSNumber *) - (intValue) + + public static let rowCount = Attribute(rawValue: "AXRowCount") //(NSNumber *) - (intValue) number of rows + + public static let columnCount = Attribute(rawValue: "AXColumnCount") //(NSNumber *) - (intValue) number of columns + + public static let orderedByRow = Attribute(rawValue: "AXOrderedByRow") //(NSNumber *) - (boolValue) is ordered by row? + + public static let warningValue = Attribute(rawValue: "AXWarningValue") //(id) - warning value of a level indicator, typically a number + + public static let criticalValue = Attribute(rawValue: "AXCriticalValue") //(id) - critical value of a level indicator, typically a number + + public static let placeholderValue = Attribute(rawValue: "AXPlaceholderValue") //(NSString *) - placeholder value of a control such as a text field + + public static let containsProtectedContent = Attribute(rawValue: "AXContainsProtectedContent") // (NSNumber *) - (boolValue) contains protected content? + public static let alternateUIVisible = Attribute(rawValue: "AXAlternateUIVisible") //(NSNumber *) - (boolValue) + + // Linkage attributes + public static let titleUIElement = Attribute(rawValue: "AXTitleUIElement") //(id) - UIElement for the title + public static let servesAsTitleForUIElements = Attribute(rawValue: "AXServesAsTitleForUIElements") //(NSArray *) - UIElements this titles + public static let linkedUIElements = Attribute(rawValue: "AXLinkedUIElements") //(NSArray *) - corresponding UIElements + + // Text-specific attributes + public static let selectedText = Attribute(rawValue: "AXSelectedText") //(NSString *) - selected text + public static let selectedTextRange = Attribute(rawValue: "AXSelectedTextRange") //(NSValue *) - (rangeValue) range of selected text + public static let numberOfCharacters = Attribute(rawValue: "AXNumberOfCharacters") //(NSNumber *) - number of characters + public static let visibleCharacterRange = Attribute(rawValue: "AXVisibleCharacterRange") //(NSValue *) - (rangeValue) range of visible text + public static let sharedTextUIElements = Attribute(rawValue: "AXSharedTextUIElements") //(NSArray *) - text views sharing text + public static let sharedCharacterRange = Attribute(rawValue: "AXSharedCharacterRange") //(NSValue *) - (rangeValue) part of shared text in this view + public static let insertionPointLineNumber = Attribute(rawValue: "AXInsertionPointLineNumber") //(NSNumber *) - line# containing caret + public static let selectedTextRanges = Attribute(rawValue: "AXSelectedTextRanges") //(NSArray *) - array of NSValue (rangeValue) ranges of selected text + /// - note: private/undocumented attribute + public static let textInputMarkedRange = Attribute(rawValue: "AXTextInputMarkedRange") + + // Parameterized text-specific attributes + public static let lineForIndexParameterized = Attribute(rawValue: "AXLineForIndexParameterized") //(NSNumber *) - line# for char index; param:(NSNumber *) + public static let rangeForLineParameterized = Attribute(rawValue: "AXRangeForLineParameterized") //(NSValue *) - (rangeValue) range of line; param:(NSNumber *) + public static let stringForRangeParameterized = Attribute(rawValue: "AXStringForRangeParameterized") //(NSString *) - substring; param:(NSValue * - rangeValue) + public static let rangeForPositionParameterized = Attribute(rawValue: "AXRangeForPositionParameterized") //(NSValue *) - (rangeValue) composed char range; param:(NSValue * - pointValue) + public static let rangeForIndexParameterized = Attribute(rawValue: "AXRangeForIndexParameterized") //(NSValue *) - (rangeValue) composed char range; param:(NSNumber *) + public static let boundsForRangeParameterized = Attribute(rawValue: "AXBoundsForRangeParameterized") //(NSValue *) - (rectValue) bounds of text; param:(NSValue * - rangeValue) + public static let rtfForRangeParameterized = Attribute(rawValue: "AXRTFForRangeParameterized") //(NSData *) - rtf for text; param:(NSValue * - rangeValue) + public static let styleRangeForIndexParameterized = Attribute(rawValue: "AXStyleRangeForIndexParameterized") //(NSValue *) - (rangeValue) extent of style run; param:(NSNumber *) + public static let attributedStringForRangeParameterized = Attribute(rawValue: "AXAttributedStringForRangeParameterized") //(NSAttributedString *) - does _not_ use attributes from Appkit/AttributedString.h + + // Text attributed string attributes and constants + public static let fontText = Attribute(rawValue: "AXFontText") //(NSDictionary *) - NSAccessibilityFontXXXKey's + public static let foregroundColorText = Attribute(rawValue: "AXForegroundColorText") //CGColorRef + public static let backgroundColorText = Attribute(rawValue: "AXBackgroundColorText") //CGColorRef + public static let underlineColorText = Attribute(rawValue: "AXUnderlineColorText") //CGColorRef + public static let strikethroughColorText = Attribute(rawValue: "AXStrikethroughColorText") //CGColorRef + public static let underlineText = Attribute(rawValue: "AXUnderlineText") //(NSNumber *) - underline style + public static let superscriptText = Attribute(rawValue: "AXSuperscriptText") //(NSNumber *) - superscript>0, subscript<0 + public static let strikethroughText = Attribute(rawValue: "AXStrikethroughText") //(NSNumber *) - (boolValue) + public static let shadowText = Attribute(rawValue: "AXShadowText") //(NSNumber *) - (boolValue) + public static let attachmentText = Attribute(rawValue: "AXAttachmentText") //id - corresponding element + public static let linkText = Attribute(rawValue: "AXLinkText") //id - corresponding element + public static let autocorrectedText = Attribute(rawValue: "AXAutocorrectedText") //(NSNumber *) - (boolValue) + + // Textual list attributes and constants. Examples: unordered or ordered lists in a document. + public static let listItemPrefixText = Attribute(rawValue: "AXListItemPrefixText") // NSAttributedString, the prepended string of the list item. If the string is a common unicode character (e.g. a bullet •), return that unicode character. For lists with images before the text, return a reasonable label of the image. + public static let listItemIndexText = Attribute(rawValue: "AXListItemIndexText") // NSNumber, integerValue of the line index. Each list item increments the index, even for unordered lists. The first item should have index 0. + public static let listItemLevelText = Attribute(rawValue: "AXListItemLevelText") // NSNumber, integerValue of the indent level. Each sublist increments the level. The first item should have level 0. + + // MisspelledText attributes + public static let misspelledText = Attribute(rawValue: "AXMisspelledText") //(NSNumber *) - (boolValue) + public static let markedMisspelledText = Attribute(rawValue: "AXMarkedMisspelledText") //(NSNumber *) - (boolValue) + + // Window-specific attributes + public static let main = Attribute(rawValue: "AXMain") //(NSNumber *) - (boolValue) is it the main window? + public static let minimized = Attribute(rawValue: "AXMinimized") //(NSNumber *) - (boolValue) is window minimized? + public static let closeButton = Attribute(rawValue: "AXCloseButton") //(id) - UIElement for close box (or nil) + public static let zoomButton = Attribute(rawValue: "AXZoomButton") //(id) - UIElement for zoom box (or nil) + public static let minimizeButton = Attribute(rawValue: "AXMinimizeButton") //(id) - UIElement for miniaturize box (or nil) + public static let toolbarButton = Attribute(rawValue: "AXToolbarButton") //(id) - UIElement for toolbar box (or nil) + public static let proxy = Attribute(rawValue: "AXProxy") //(id) - UIElement for title's icon (or nil) + public static let growArea = Attribute(rawValue: "AXGrowArea") //(id) - UIElement for grow box (or nil) + public static let modal = Attribute(rawValue: "AXModal") //(NSNumber *) - (boolValue) is the window modal + public static let defaultButton = Attribute(rawValue: "AXDefaultButton") //(id) - UIElement for default button + public static let cancelButton = Attribute(rawValue: "AXCancelButton") //(id) - UIElement for cancel button + public static let fullScreenButton = Attribute(rawValue: "AXFullScreenButton") //(id) - UIElement for full screen button (or nil) + /// - note: private/undocumented attribute + public static let fullScreen = Attribute(rawValue: "AXFullScreen") //(NSNumber *) - (boolValue) is the window fullscreen + + // Application-specific attributes + public static let menuBar = Attribute(rawValue: "AXMenuBar") //(id) - UIElement for the menu bar + public static let windows = Attribute(rawValue: "AXWindows") //(NSArray *) - UIElements for the windows + public static let frontmost = Attribute(rawValue: "AXFrontmost") //(NSNumber *) - (boolValue) is the app active? + public static let hidden = Attribute(rawValue: "AXHidden") //(NSNumber *) - (boolValue) is the app hidden? + public static let mainWindow = Attribute(rawValue: "AXMainWindow") //(id) - UIElement for the main window. + public static let focusedWindow = Attribute(rawValue: "AXFocusedWindow") //(id) - UIElement for the key window. + public static let focusedUIElement = Attribute(rawValue: "AXFocusedUIElement") //(id) - Currently focused UIElement. + public static let extrasMenuBar = Attribute(rawValue: "AXExtrasMenuBar") //(id) - UIElement for the application extras menu bar. + /// - note: private/undocumented attribute + public static let enhancedUserInterface = Attribute(rawValue: "AXEnhancedUserInterface") //(NSNumber *) - (boolValue) is the enhanced user interface active? + + public static let orientation = Attribute(rawValue: "AXOrientation") //(NSString *) - NSAccessibilityXXXOrientationValue + + public static let columnTitles = Attribute(rawValue: "AXColumnTitles") //(NSArray *) - UIElements for titles + + public static let searchButton = Attribute(rawValue: "AXSearchButton") //(id) - UIElement for search field search btn + public static let searchMenu = Attribute(rawValue: "AXSearchMenu") //(id) - UIElement for search field menu + public static let clearButton = Attribute(rawValue: "AXClearButton") //(id) - UIElement for search field clear btn + + // Table/outline view attributes + public static let rows = Attribute(rawValue: "AXRows") //(NSArray *) - UIElements for rows + public static let visibleRows = Attribute(rawValue: "AXVisibleRows") //(NSArray *) - UIElements for visible rows + public static let selectedRows = Attribute(rawValue: "AXSelectedRows") //(NSArray *) - UIElements for selected rows + public static let columns = Attribute(rawValue: "AXColumns") //(NSArray *) - UIElements for columns + public static let visibleColumns = Attribute(rawValue: "AXVisibleColumns") //(NSArray *) - UIElements for visible columns + public static let selectedColumns = Attribute(rawValue: "AXSelectedColumns") //(NSArray *) - UIElements for selected columns + public static let sortDirection = Attribute(rawValue: "AXSortDirection") //(NSString *) - see sort direction values below + + // Cell-based table attributes + public static let selectedCells = Attribute(rawValue: "AXSelectedCells") //(NSArray *) - UIElements for selected cells + public static let visibleCells = Attribute(rawValue: "AXVisibleCells") //(NSArray *) - UIElements for visible cells + public static let rowHeaderUIElements = Attribute(rawValue: "AXRowHeaderUIElements") //(NSArray *) - UIElements for row headers + public static let columnHeaderUIElements = Attribute(rawValue: "AXColumnHeaderUIElements") //(NSArray *) - UIElements for column headers + + // Cell-based table parameterized attributes. The parameter for this attribute is an NSArray containing two NSNumbers, the first NSNumber specifies the column index, the second NSNumber specifies the row index. + public static let cellForColumnAndRowParameterized = Attribute(rawValue: "AXCellForColumnAndRowParameterized") // (id) - UIElement for cell at specified row and column + + // Cell attributes. The index range contains both the starting index, and the index span in a table. + public static let rowIndexRange = Attribute(rawValue: "AXRowIndexRange") //(NSValue *) - (rangeValue) location and row span + public static let columnIndexRange = Attribute(rawValue: "AXColumnIndexRange") //(NSValue *) - (rangeValue) location and column span + + // Layout area attributes + public static let horizontalUnits = Attribute(rawValue: "AXHorizontalUnits") //(NSString *) - see ruler unit values below + public static let verticalUnits = Attribute(rawValue: "AXVerticalUnits") //(NSString *) - see ruler unit values below + public static let horizontalUnitDescription = Attribute(rawValue: "AXHorizontalUnitDescription") //(NSString *) + public static let verticalUnitDescription = Attribute(rawValue: "AXVerticalUnitDescription") //(NSString *) + + // Layout area parameterized attributes + public static let layoutPointForScreenPointParameterized = "Attribute(rawValue: AXLayoutPointForScreenPointParameterized" //)(NSValue *) - (pointValue); param:(NSValue * - pointValue) + public static let layoutSizeForScreenSizeParameterized = Attribute(rawValue: "AXLayoutSizeForScreenSizeParameterized") //(NSValue *) - (sizeValue); param:(NSValue * - sizeValue) + public static let screenPointForLayoutPointParameterized = "Attribute(rawValue: AXScreenPointForLayoutPointParameterized" //)(NSValue *) - (pointValue); param:(NSValue * - pointValue) + public static let screenSizeForLayoutSizeParameterized = Attribute(rawValue: "AXScreenSizeForLayoutSizeParameterized") //(NSValue *) - (sizeValue); param:(NSValue * - sizeValue) + + // Layout item attributes + public static let handles = Attribute(rawValue: "AXHandles") //(NSArray *) - UIElements for handles + + // Outline attributes + public static let disclosing = Attribute(rawValue: "AXDisclosing") //(NSNumber *) - (boolValue) is disclosing rows? + public static let disclosedRows = Attribute(rawValue: "AXDisclosedRows") //(NSArray *) - UIElements for disclosed rows + public static let disclosedByRow = Attribute(rawValue: "AXDisclosedByRow") //(id) - UIElement for disclosing row + public static let disclosureLevel = Attribute(rawValue: "AXDisclosureLevel") //(NSNumber *) - indentation level + + // Slider attributes + public static let allowedValues = Attribute(rawValue: "AXAllowedValues") //(NSArray *) - array of allowed values + public static let labelUIElements = Attribute(rawValue: "AXLabelUIElements") //(NSArray *) - array of label UIElements + public static let labelValue = Attribute(rawValue: "AXLabelValue") //(NSNumber *) - value of a label UIElement + + // Matte attributes + // Attributes no longer supported + public static let matteHole = Attribute(rawValue: "AXMatteHole") //(NSValue *) - (rect value) bounds of matte hole in screen coords + public static let matteContentUIElement = Attribute(rawValue: "AXMatteContentUIElement") //(id) - UIElement clipped by the matte + + // Ruler view attributes + public static let markerUIElements = Attribute(rawValue: "AXMarkerUIElements") //(NSArray *) + public static let markerValues = Attribute(rawValue: "AXMarkerValues") // + public static let markerGroupUIElement = Attribute(rawValue: "AXMarkerGroupUIElement") //(id) + public static let units = Attribute(rawValue: "AXUnits") //(NSString *) - see ruler unit values below + public static let unitDescription = Attribute(rawValue: "AXUnitDescription") //(NSString *) + public static let markerType = Attribute(rawValue: "AXMarkerType") //(NSString *) - see ruler marker type values below + public static let markerTypeDescription = Attribute(rawValue: "AXMarkerTypeDescription") //(NSString *) + + // UI element identification attributes + public static let identifier = Attribute(rawValue: "AXIdentifier") //(NSString *) + + // System-wide attributes + public static let focusedApplication = Attribute(rawValue: "AXFocusedApplication") + + // Unknown attributes + public static let functionRowTopLevelElements = Attribute(rawValue: "AXFunctionRowTopLevelElements") + public static let childrenInNavigationOrder = Attribute(rawValue: "AXChildrenInNavigationOrder") + } } diff --git a/Sources/Constants/Orientation.swift b/Sources/Constants/Orientation.swift index 2f27264..5ca86a6 100644 --- a/Sources/Constants/Orientation.swift +++ b/Sources/Constants/Orientation.swift @@ -3,11 +3,11 @@ import Foundation @available(*, deprecated, renamed: "UIElement.Orientation", message: "Provided for drop in replacement, but now the type is located under the `UIElement` namespace.") public typealias Orientation = UIElement.Orientation extension UIElement { - /// Orientations returned by the orientation property. - /// - seeAlso: [NSAccessibilityOrientation](https://developer.apple.com/library/mac/documentation/AppKit/Reference/NSAccessibility_Protocol_Reference/index.html#//apple_ref/c/tdef/NSAccessibilityOrientation) - public enum Orientation: Int { - case unknown = 0 - case vertical = 1 - case horizontal = 2 - } + /// Orientations returned by the orientation property. + /// - seeAlso: [NSAccessibilityOrientation](https://developer.apple.com/library/mac/documentation/AppKit/Reference/NSAccessibility_Protocol_Reference/index.html#//apple_ref/c/tdef/NSAccessibilityOrientation) + public enum Orientation: Int { + case unknown = 0 + case vertical = 1 + case horizontal = 2 + } } diff --git a/Sources/Constants/Role.swift b/Sources/Constants/Role.swift index 74d7653..d48c586 100644 --- a/Sources/Constants/Role.swift +++ b/Sources/Constants/Role.swift @@ -3,70 +3,70 @@ import Foundation @available(*, deprecated, renamed: "UIElement.Role", message: "Provided for drop in replacement, but now the type is located under the `UIElement` namespace.") public typealias Role = UIElement.Role extension UIElement { - /// Provides all known UIElement roles. - /// - seeAlso: [Roles](https://developer.apple.com/library/mac/documentation/AppKit/Reference/NSAccessibility_Protocol_Reference/index.html#//apple_ref/doc/constant_group/Roles) - public struct Role: RawRepresentable, Hashable, Sendable { - public let rawValue: String - public var rawCFStringValue: CFString { rawValue as CFString } - - public init(rawValue: String) { - self.rawValue = rawValue - } - - public static let unknown = Role(rawValue: "AXUnknown") - public static let button = Role(rawValue: "AXButton") - public static let radioButton = Role(rawValue: "AXRadioButton") - public static let checkBox = Role(rawValue: "AXCheckBox") - public static let slider = Role(rawValue: "AXSlider") - public static let tabGroup = Role(rawValue: "AXTabGroup") - public static let textField = Role(rawValue: "AXTextField") - public static let staticText = Role(rawValue: "AXStaticText") - public static let textArea = Role(rawValue: "AXTextArea") - public static let scrollArea = Role(rawValue: "AXScrollArea") - public static let popUpButton = Role(rawValue: "AXPopUpButton") - public static let menuButton = Role(rawValue: "AXMenuButton") - public static let table = Role(rawValue: "AXTable") - public static let application = Role(rawValue: "AXApplication") - public static let group = Role(rawValue: "AXGroup") - public static let radioGroup = Role(rawValue: "AXRadioGroup") - public static let list = Role(rawValue: "AXList") - public static let scrollBar = Role(rawValue: "AXScrollBar") - public static let valueIndicator = Role(rawValue: "AXValueIndicator") - public static let image = Role(rawValue: "AXImage") - public static let menuBar = Role(rawValue: "AXMenuBar") - public static let menu = Role(rawValue: "AXMenu") - public static let menuItem = Role(rawValue: "AXMenuItem") - public static let menuBarItem = Role(rawValue: "AXMenuBarItem") - public static let column = Role(rawValue: "AXColumn") - public static let row = Role(rawValue: "AXRow") - public static let toolbar = Role(rawValue: "AXToolbar") - public static let busyIndicator = Role(rawValue: "AXBusyIndicator") - public static let progressIndicator = Role(rawValue: "AXProgressIndicator") - public static let window = Role(rawValue: "AXWindow") - public static let drawer = Role(rawValue: "AXDrawer") - public static let systemWide = Role(rawValue: "AXSystemWide") - public static let outline = Role(rawValue: "AXOutline") - public static let incrementor = Role(rawValue: "AXIncrementor") - public static let browser = Role(rawValue: "AXBrowser") - public static let comboBox = Role(rawValue: "AXComboBox") - public static let splitGroup = Role(rawValue: "AXSplitGroup") - public static let splitter = Role(rawValue: "AXSplitter") - public static let colorWell = Role(rawValue: "AXColorWell") - public static let growArea = Role(rawValue: "AXGrowArea") - public static let sheet = Role(rawValue: "AXSheet") - public static let helpTag = Role(rawValue: "AXHelpTag") - public static let matte = Role(rawValue: "AXMatte") - public static let ruler = Role(rawValue: "AXRuler") - public static let rulerMarker = Role(rawValue: "AXRulerMarker") - public static let link = Role(rawValue: "AXLink") - public static let disclosureTriangle = Role(rawValue: "AXDisclosureTriangle") - public static let grid = Role(rawValue: "AXGrid") - public static let relevanceIndicator = Role(rawValue: "AXRelevanceIndicator") - public static let levelIndicator = Role(rawValue: "AXLevelIndicator") - public static let cell = Role(rawValue: "AXCell") - public static let popover = Role(rawValue: "AXPopover") - public static let layoutArea = Role(rawValue: "AXLayoutArea") - public static let layoutItem = Role(rawValue: "AXLayoutItem") - public static let handle = Role(rawValue: "AXHandle") - } + /// Provides all known UIElement roles. + /// - seeAlso: [Roles](https://developer.apple.com/library/mac/documentation/AppKit/Reference/NSAccessibility_Protocol_Reference/index.html#//apple_ref/doc/constant_group/Roles) + public struct Role: RawRepresentable, Hashable, Sendable { + public let rawValue: String + public var rawCFStringValue: CFString { rawValue as CFString } + + public init(rawValue: String) { + self.rawValue = rawValue + } + + public static let unknown = Role(rawValue: "AXUnknown") + public static let button = Role(rawValue: "AXButton") + public static let radioButton = Role(rawValue: "AXRadioButton") + public static let checkBox = Role(rawValue: "AXCheckBox") + public static let slider = Role(rawValue: "AXSlider") + public static let tabGroup = Role(rawValue: "AXTabGroup") + public static let textField = Role(rawValue: "AXTextField") + public static let staticText = Role(rawValue: "AXStaticText") + public static let textArea = Role(rawValue: "AXTextArea") + public static let scrollArea = Role(rawValue: "AXScrollArea") + public static let popUpButton = Role(rawValue: "AXPopUpButton") + public static let menuButton = Role(rawValue: "AXMenuButton") + public static let table = Role(rawValue: "AXTable") + public static let application = Role(rawValue: "AXApplication") + public static let group = Role(rawValue: "AXGroup") + public static let radioGroup = Role(rawValue: "AXRadioGroup") + public static let list = Role(rawValue: "AXList") + public static let scrollBar = Role(rawValue: "AXScrollBar") + public static let valueIndicator = Role(rawValue: "AXValueIndicator") + public static let image = Role(rawValue: "AXImage") + public static let menuBar = Role(rawValue: "AXMenuBar") + public static let menu = Role(rawValue: "AXMenu") + public static let menuItem = Role(rawValue: "AXMenuItem") + public static let menuBarItem = Role(rawValue: "AXMenuBarItem") + public static let column = Role(rawValue: "AXColumn") + public static let row = Role(rawValue: "AXRow") + public static let toolbar = Role(rawValue: "AXToolbar") + public static let busyIndicator = Role(rawValue: "AXBusyIndicator") + public static let progressIndicator = Role(rawValue: "AXProgressIndicator") + public static let window = Role(rawValue: "AXWindow") + public static let drawer = Role(rawValue: "AXDrawer") + public static let systemWide = Role(rawValue: "AXSystemWide") + public static let outline = Role(rawValue: "AXOutline") + public static let incrementor = Role(rawValue: "AXIncrementor") + public static let browser = Role(rawValue: "AXBrowser") + public static let comboBox = Role(rawValue: "AXComboBox") + public static let splitGroup = Role(rawValue: "AXSplitGroup") + public static let splitter = Role(rawValue: "AXSplitter") + public static let colorWell = Role(rawValue: "AXColorWell") + public static let growArea = Role(rawValue: "AXGrowArea") + public static let sheet = Role(rawValue: "AXSheet") + public static let helpTag = Role(rawValue: "AXHelpTag") + public static let matte = Role(rawValue: "AXMatte") + public static let ruler = Role(rawValue: "AXRuler") + public static let rulerMarker = Role(rawValue: "AXRulerMarker") + public static let link = Role(rawValue: "AXLink") + public static let disclosureTriangle = Role(rawValue: "AXDisclosureTriangle") + public static let grid = Role(rawValue: "AXGrid") + public static let relevanceIndicator = Role(rawValue: "AXRelevanceIndicator") + public static let levelIndicator = Role(rawValue: "AXLevelIndicator") + public static let cell = Role(rawValue: "AXCell") + public static let popover = Role(rawValue: "AXPopover") + public static let layoutArea = Role(rawValue: "AXLayoutArea") + public static let layoutItem = Role(rawValue: "AXLayoutItem") + public static let handle = Role(rawValue: "AXHandle") + } } diff --git a/Sources/Constants/Subrole.swift b/Sources/Constants/Subrole.swift index ac28b76..ce00aea 100644 --- a/Sources/Constants/Subrole.swift +++ b/Sources/Constants/Subrole.swift @@ -3,44 +3,44 @@ import Foundation @available(*, deprecated, renamed: "UIElement.Role.Subrole", message: "Provided for drop in replacement, but now the type is located under the `UIElement.Role` namespace.") public typealias Subrole = UIElement.Role.Subrole extension UIElement.Role { - /// Provides all known UIElement subroles. - /// - seeAlso: [Subroles](https://developer.apple.com/library/mac/documentation/AppKit/Reference/NSAccessibility_Protocol_Reference/index.html#//apple_ref/doc/constant_group/Subroles) - public struct Subrole: RawRepresentable, Hashable, Sendable { - public let rawValue: String - public var rawCFStringValue: CFString { rawValue as CFString } - - public init(rawValue: String) { - self.rawValue = rawValue - } - - public static let unknown = Subrole(rawValue: "AXUnknown") - public static let closeButton = Subrole(rawValue: "AXCloseButton") - public static let zoomButton = Subrole(rawValue: "AXZoomButton") - public static let minimizeButton = Subrole(rawValue: "AXMinimizeButton") - public static let toolbarButton = Subrole(rawValue: "AXToolbarButton") - public static let tableRow = Subrole(rawValue: "AXTableRow") - public static let outlineRow = Subrole(rawValue: "AXOutlineRow") - public static let secureTextField = Subrole(rawValue: "AXSecureTextField") - public static let standardWindow = Subrole(rawValue: "AXStandardWindow") - public static let dialog = Subrole(rawValue: "AXDialog") - public static let systemDialog = Subrole(rawValue: "AXSystemDialog") - public static let floatingWindow = Subrole(rawValue: "AXFloatingWindow") - public static let systemFloatingWindow = Subrole(rawValue: "AXSystemFloatingWindow") - public static let incrementArrow = Subrole(rawValue: "AXIncrementArrow") - public static let decrementArrow = Subrole(rawValue: "AXDecrementArrow") - public static let incrementPage = Subrole(rawValue: "AXIncrementPage") - public static let decrementPage = Subrole(rawValue: "AXDecrementPage") - public static let searchField = Subrole(rawValue: "AXSearchField") - public static let textAttachment = Subrole(rawValue: "AXTextAttachment") - public static let textLink = Subrole(rawValue: "AXTextLink") - public static let timeline = Subrole(rawValue: "AXTimeline") - public static let sortButton = Subrole(rawValue: "AXSortButton") - public static let ratingIndicator = Subrole(rawValue: "AXRatingIndicator") - public static let contentList = Subrole(rawValue: "AXContentList") - public static let definitionList = Subrole(rawValue: "AXDefinitionList") - public static let fullScreenButton = Subrole(rawValue: "AXFullScreenButton") - public static let toggle = Subrole(rawValue: "AXToggle") - public static let switchSubrole = Subrole(rawValue: "AXSwitch") - public static let descriptionList = Subrole(rawValue: "AXDescriptionList") - } + /// Provides all known UIElement subroles. + /// - seeAlso: [Subroles](https://developer.apple.com/library/mac/documentation/AppKit/Reference/NSAccessibility_Protocol_Reference/index.html#//apple_ref/doc/constant_group/Subroles) + public struct Subrole: RawRepresentable, Hashable, Sendable { + public let rawValue: String + public var rawCFStringValue: CFString { rawValue as CFString } + + public init(rawValue: String) { + self.rawValue = rawValue + } + + public static let unknown = Subrole(rawValue: "AXUnknown") + public static let closeButton = Subrole(rawValue: "AXCloseButton") + public static let zoomButton = Subrole(rawValue: "AXZoomButton") + public static let minimizeButton = Subrole(rawValue: "AXMinimizeButton") + public static let toolbarButton = Subrole(rawValue: "AXToolbarButton") + public static let tableRow = Subrole(rawValue: "AXTableRow") + public static let outlineRow = Subrole(rawValue: "AXOutlineRow") + public static let secureTextField = Subrole(rawValue: "AXSecureTextField") + public static let standardWindow = Subrole(rawValue: "AXStandardWindow") + public static let dialog = Subrole(rawValue: "AXDialog") + public static let systemDialog = Subrole(rawValue: "AXSystemDialog") + public static let floatingWindow = Subrole(rawValue: "AXFloatingWindow") + public static let systemFloatingWindow = Subrole(rawValue: "AXSystemFloatingWindow") + public static let incrementArrow = Subrole(rawValue: "AXIncrementArrow") + public static let decrementArrow = Subrole(rawValue: "AXDecrementArrow") + public static let incrementPage = Subrole(rawValue: "AXIncrementPage") + public static let decrementPage = Subrole(rawValue: "AXDecrementPage") + public static let searchField = Subrole(rawValue: "AXSearchField") + public static let textAttachment = Subrole(rawValue: "AXTextAttachment") + public static let textLink = Subrole(rawValue: "AXTextLink") + public static let timeline = Subrole(rawValue: "AXTimeline") + public static let sortButton = Subrole(rawValue: "AXSortButton") + public static let ratingIndicator = Subrole(rawValue: "AXRatingIndicator") + public static let contentList = Subrole(rawValue: "AXContentList") + public static let definitionList = Subrole(rawValue: "AXDefinitionList") + public static let fullScreenButton = Subrole(rawValue: "AXFullScreenButton") + public static let toggle = Subrole(rawValue: "AXToggle") + public static let switchSubrole = Subrole(rawValue: "AXSwitch") + public static let descriptionList = Subrole(rawValue: "AXDescriptionList") + } } diff --git a/Sources/Observer.swift b/Sources/Observer.swift index eaf919d..479f67a 100644 --- a/Sources/Observer.swift +++ b/Sources/Observer.swift @@ -10,10 +10,10 @@ import Darwin public final class Observer { public typealias Callback = (_ observer: Observer, _ element: UIElement, - _ notification: UIElement.AXNotification) -> Void + _ notification: UIElement.AXNotification) -> Void public typealias CallbackWithInfo = (_ observer: Observer, _ element: UIElement, - _ notification: UIElement.AXNotification, + _ notification: UIElement.AXNotification, _ info: [String: AnyObject]?) -> Void let pid: pid_t @@ -22,7 +22,7 @@ public final class Observer { let callbackWithInfo: CallbackWithInfo? public fileprivate(set) lazy var application: Application = - Application(forKnownProcessID: self.pid)! + Application(forKnownProcessID: self.pid)! /// Creates and starts an observer on the given `processID`. public init(processID: pid_t, callback: @escaping Callback) throws { @@ -100,7 +100,7 @@ public final class Observer { /// error is not passed on for consistency with `start()` and `stop()`. /// - throws: `Error.NotificationUnsupported`: The element does not support notifications (note /// that the system-wide element does not support notifications). - public func addNotification(_ notification: UIElement.AXNotification, + public func addNotification(_ notification: UIElement.AXNotification, forElement element: UIElement) throws { let selfPtr = UnsafeMutableRawPointer(Unmanaged.passUnretained(self).toOpaque()) let error = AXObserverAddNotification( @@ -119,7 +119,7 @@ public final class Observer { /// error is not passed on for consistency with `start()` and `stop()`. /// - throws: `Error.NotificationUnsupported`: The element does not support notifications (note /// that the system-wide element does not support notifications). - public func removeNotification(_ notification: UIElement.AXNotification, + public func removeNotification(_ notification: UIElement.AXNotification, forElement element: UIElement) throws { let error = AXObserverRemoveNotification( axObserver, element.element, notification.rawValue as CFString @@ -138,11 +138,11 @@ private func internalCallback(_ axObserver: AXObserver, let observer = Unmanaged.fromOpaque(userData).takeUnretainedValue() let element = UIElement(axElement) - let notif = UIElement.AXNotification(rawValue: notification as String) -// guard let notif = UIElement.AXNotification(rawValue: notification as String) else { -// NSLog("Unknown AX notification %s received", notification as String) -// return -// } + let notif = UIElement.AXNotification(rawValue: notification as String) + // guard let notif = UIElement.AXNotification(rawValue: notification as String) else { + // NSLog("Unknown AX notification %s received", notification as String) + // return + // } observer.callback!(observer, element, notif) } @@ -156,10 +156,10 @@ private func internalInfoCallback(_ axObserver: AXObserver, let observer = Unmanaged.fromOpaque(userData).takeUnretainedValue() let element = UIElement(axElement) let info = cfInfo as NSDictionary? as! [String: AnyObject]? - let notif = UIElement.AXNotification(rawValue: notification as String) -// guard let notif = UIElement.AXNotification(rawValue: notification as String) else { -// NSLog("Unknown AX notification %s received", notification as String) -// return -// } + let notif = UIElement.AXNotification(rawValue: notification as String) + // guard let notif = UIElement.AXNotification(rawValue: notification as String) else { + // NSLog("Unknown AX notification %s received", notification as String) + // return + // } observer.callbackWithInfo!(observer, element, notif, info) } diff --git a/Sources/UIElement.swift b/Sources/UIElement.swift index 9eab8ec..b0eb510 100644 --- a/Sources/UIElement.swift +++ b/Sources/UIElement.swift @@ -40,7 +40,7 @@ import Foundation /// - seeAlso: [AXUIElement.h reference](https://developer.apple.com/library/mac/documentation/ApplicationServices/Reference/AXUIElement_header_reference/) open class UIElement { public let element: AXUIElement - + /// Create a UIElement from a raw AXUIElement object. /// /// The state and role of the AXUIElement is not checked. @@ -48,10 +48,10 @@ open class UIElement { // Since we are dealing with low-level C APIs, it never hurts to double check types. assert(CFGetTypeID(nativeElement) == AXUIElementGetTypeID(), "nativeElement is not an AXUIElement") - + element = nativeElement } - + /// Checks if the current process is a trusted accessibility client. If false, all APIs will /// throw errors. /// @@ -63,45 +63,45 @@ open class UIElement { ] return AXIsProcessTrustedWithOptions(options as CFDictionary) } - + /// Timeout in seconds for all UIElement messages. Use this to control how long a method call /// can delay execution. The default is `0` which means to use the system default. open class var globalMessagingTimeout: Float { get { return systemWideElement.messagingTimeout } set { systemWideElement.messagingTimeout = newValue } } - + // MARK: - Attributes - + /// Returns the list of all attributes. /// /// Does not include parameterized attributes. open func attributes() throws(AXError) -> [Attribute] { var names: CFArray! let error = AXUIElementCopyAttributeNames(element, &names) - + guard error != .noValue, error != .attributeUnsupported, let names else { return [] } - + guard error == .success else { throw error } - + // We must first convert the CFArray to a native array, then downcast to an array of // strings. let strings = names as! [String] - + return strings.map(Attribute.init(rawValue:)) } - + // This version is named differently so the caller doesn't have to specify the return type when // using the enum version. @available(*, deprecated, renamed: "attributes", message: "If you need strings, just call `attributes().map(\\.rawValue)`") open func attributesAsStrings() throws(AXError) -> [String] { try attributes().map(\.rawValue) } - + /// Returns whether `attribute` is supported by this element. /// /// The `attribute` method returns nil for unsupported attributes and empty attributes alike, @@ -112,48 +112,48 @@ open class UIElement { // Ask to copy 0 values, since we are only interested in the return code. var value: CFArray? let error = AXUIElementCopyAttributeValues(element, attribute.rawCFStringValue, 0, 0, &value) - + if error == .attributeUnsupported { return false } - + if error == .noValue { return true } - + guard error == .success else { throw error } - + return true } - + @available(*, deprecated, renamed: "attributeIsSupported") open func attributeIsSupported(_ attribute: String) throws(AXError) -> Bool { try attributeIsSupported(Attribute(rawValue: attribute)) } - + /// Returns whether `attribute` is writeable. open func attributeIsSettable(_ attribute: Attribute) throws(AXError) -> Bool { var settable: DarwinBoolean = false let error = AXUIElementIsAttributeSettable(element, attribute.rawCFStringValue, &settable) - + if error == .noValue || error == .attributeUnsupported { return false } - + guard error == .success else { throw error } - + return settable.boolValue } - + @available(*, deprecated, renamed: "attributeIsSettable") open func attributeIsSettable(_ attribute: String) throws(AXError) -> Bool { try attributeIsSettable(Attribute(rawValue: attribute)) } - + /// Returns the value of `attribute`, if it exists. /// /// - parameter attribute: The name of a (non-parameterized) attribute. @@ -166,29 +166,29 @@ open class UIElement { open func attribute(_ attribute: Attribute) throws(AXError) -> T? { var value: AnyObject? let error = AXUIElementCopyAttributeValue(element, attribute.rawCFStringValue, &value) - + guard error != .noValue, error != .attributeUnsupported, let value else { return nil } - + guard error == .success else { throw error } - + guard let unpackedValue = (unpackAXValue(value) as? T) else { throw AXError.illegalArgument } - + return unpackedValue } - + @available(*, deprecated, renamed: "attribute") open func attribute(_ attribute: String) throws(AXError) -> T? { try self.attribute(Attribute(rawValue: attribute)) } - + /// Sets the value of `attribute` to `value`. /// /// - warning: Unlike read-only methods, this method throws(AXError) if the attribute doesn't exist. @@ -199,17 +199,17 @@ open class UIElement { /// - `Error.Failure`: A temporary failure occurred. open func setAttribute(_ attribute: Attribute, value: Any) throws(AXError) { let error = AXUIElementSetAttributeValue(element, attribute.rawCFStringValue, packAXValue(value)) - + guard error == .success else { throw error } } - + @available(*, deprecated, renamed: "setAttribute") open func setAttribute(_ attribute: String, value: Any) throws(AXError) { try setAttribute(Attribute(rawValue: attribute), value: value) } - + /// Gets multiple attributes of the element at once. /// /// - parameter attributes: An array of attribute names. Nonexistent attributes are ignored. @@ -225,17 +225,17 @@ open class UIElement { open func getMultipleAttributes(_ names: Attribute...) throws(AXError) -> [Attribute: Any] { return try getMultipleAttributes(names) } - + open func getMultipleAttributes(_ attributes: [Attribute]) throws(AXError) -> [Attribute: Any] { let values = try fetchMultiAttrValues(attributes) return try packMultiAttrValues(attributes, values: values) } - + open func getMultipleAttributes(_ attributes: [String]) throws(AXError) -> [String: Any] { let values = try fetchMultiAttrValues(attributes.map(Attribute.init(rawValue:))) return try packMultiAttrValues(attributes, values: values) } - + // Helper: Gets list of values fileprivate func fetchMultiAttrValues(_ attributes: [Attribute]) throws(AXError) -> [AnyObject] { var valuesCF: CFArray? @@ -245,19 +245,19 @@ open class UIElement { // keep going on errors (particularly NoValue) AXCopyMultipleAttributeOptions(rawValue: 0), &valuesCF) - + guard error == .success else { throw error } - + return valuesCF! as [AnyObject] } - + // Helper: Packs names, values into dictionary - fileprivate func packMultiAttrValues( - _ attributes: [Attr], - values: [AnyObject] - ) throws(AXError) -> [Attr: Any] { + fileprivate func packMultiAttrValues( + _ attributes: [Attr], + values: [AnyObject] + ) throws(AXError) -> [Attr: Any] { var result = [Attr: Any]() for (index, attribute) in attributes.enumerated() { if try checkMultiAttrValue(values[index]) { @@ -266,20 +266,20 @@ open class UIElement { } return result } - + // Helper: Checks if value is present and not an error (throws on nontrivial errors). fileprivate func checkMultiAttrValue(_ value: AnyObject) throws(AXError) -> Bool { // Check for null if value is NSNull { return false } - + // Check for error if CFGetTypeID(value) == AXValueGetTypeID() && AXValueGetType(value as! AXValue).rawValue == kAXValueAXErrorType { var error: AXError = AXError.success AXValueGetValue(value as! AXValue, AXValueType(rawValue: kAXValueAXErrorType)!, &error) - + assert(error != .success) if error == .noValue || error == .attributeUnsupported { return false @@ -287,12 +287,12 @@ open class UIElement { throw error } } - + return true } - + // MARK: Array attributes - + /// Returns all the values of the attribute as an array of the given type. /// /// - parameter attribute: The name of the array attribute. @@ -308,12 +308,12 @@ open class UIElement { } return array.map({ unpackAXValue($0) as! T }) } - + @available(*, deprecated, renamed: "arrayAttribute") open func arrayAttribute(_ attribute: String) throws(AXError) -> [T]? { try arrayAttribute(Attribute(rawValue: attribute)) } - + /// Returns a subset of values from an array attribute. /// /// - parameter attribute: The name of the array attribute. @@ -331,51 +331,51 @@ open class UIElement { let error = AXUIElementCopyAttributeValues( element, attribute.rawCFStringValue, index, maxValues, &values ) - + guard error != .noValue, error != .attributeUnsupported, let values else { return nil } - + guard error == .success else { throw error } - + let array = values as [AnyObject] return array.map({ unpackAXValue($0) as! T }) } - + @available(*, deprecated, renamed: "valuesForAttribute") open func valuesForAttribute (_ attribute: String, startAtIndex index: Int, maxValues: Int) throws(AXError) -> [T]? { try valuesForAttribute(Attribute(rawValue: attribute), startAtIndex: index, maxValues: maxValues) } - + /// Returns the number of values an array attribute has. /// - returns: The number of values, or `nil` if `attribute` isn't an array (or doesn't exist). open func valueCountForAttribute(_ attribute: Attribute) throws(AXError) -> Int? { var count: Int = 0 let error = AXUIElementGetAttributeValueCount(element, attribute.rawCFStringValue, &count) - + if error == .attributeUnsupported || error == .illegalArgument { return nil } - + guard error == .success else { throw error } - + return count } - + @available(*, deprecated, renamed: "valueCountForAttribute") open func valueCountForAttribute(_ attribute: String) throws(AXError) -> Int? { try valueCountForAttribute(Attribute(rawValue: attribute)) } - + // MARK: Parameterized attributes - + /// Returns a list of all parameterized attributes of the element. /// /// Parameterized attributes are attributes that require parameters to retrieve. For example, @@ -383,31 +383,31 @@ open class UIElement { open func parameterizedAttributes() throws(AXError) -> [Attribute] { var names: CFArray? let error = AXUIElementCopyParameterizedAttributeNames(element, &names) - + guard error != .noValue, error != .attributeUnsupported, let names = names as? [AnyObject] else { return [] } - + guard error == .success else { throw error } - + // We must first convert the CFArray to a native array, then downcast to an array of // strings. guard let strings = names as? [String] else { return [] } - + return strings.map(Attribute.init(rawValue:)) } - + @available(*, deprecated, renamed: "parameterizedAttributes") open func parameterizedAttributesAsStrings() throws(AXError) -> [String] { try parameterizedAttributes().map(\.rawValue) } - + /// Returns the value of the parameterized attribute `attribute` with parameter `param`. /// /// The expected type of `param` depends on the attribute. See the @@ -418,27 +418,27 @@ open class UIElement { let error = AXUIElementCopyParameterizedAttributeValue( element, attribute.rawCFStringValue, param as AnyObject, &value ) - + guard error != .noValue, error != .attributeUnsupported, let value else { return nil } - + guard error == .success else { throw error } - + return (unpackAXValue(value) as! T) } - + @available(*, deprecated, renamed: "parameterizedAttribute") open func parameterizedAttribute(_ attribute: String, param: U) throws(AXError) -> T? { try parameterizedAttribute(Attribute(rawValue: attribute), param: param) } - + // MARK: Attribute helpers - + // Checks if the value is an AXValue and if so, unwraps it. // If the value is an AXUIElement, wraps it in UIElement. fileprivate func unpackAXValue(_ value: AnyObject) -> Any { @@ -482,7 +482,7 @@ open class UIElement { return value } } - + // Checks if the value is one supported by AXValue and if so, wraps it. // If the value is a UIElement, unwraps it to an AXUIElement. fileprivate func packAXValue(_ value: Any) -> AnyObject { @@ -501,14 +501,14 @@ open class UIElement { return value as AnyObject // must be an object to pass to AX } } - + // MARK: - Actions - + /// Returns a list of actions that can be performed on the element. open func actions() throws(AXError) -> [Action] { var names: CFArray? let error = AXUIElementCopyActionNames(element, &names) - + if error == .noValue || error == .attributeUnsupported { return [] } @@ -517,46 +517,46 @@ open class UIElement { error != .attributeUnsupported, let names = names as? [AnyObject] else { return [] } - + guard error == .success else { throw error } - + // We must first convert the CFArray to a native array, then downcast to an array of strings. guard let strings = names as? [String] else { return [] } - + return strings.map(Action.init(rawValue:)) } - + @available(*, deprecated, renamed: "actions") open func actionsAsStrings() throws(AXError) -> [String] { try actions().map(\.rawValue) } - + /// Returns the human-readable description of `action`. open func actionDescription(_ action: Action) throws(AXError) -> String? { var description: CFString? let error = AXUIElementCopyActionDescription(element, action.rawCFStringValue, &description) - + guard error != .noValue, error != .attributeUnsupported else { return nil } - + guard error == .success else { throw error } - + return description as? String } - + @available(*, deprecated, renamed: "actionDescription") open func actionDescription(_ action: String) throws(AXError) -> String? { try actionDescription(Action(rawValue: action)) } - + /// Performs the action `action` on the element, returning on success. /// /// - note: If the action times out, it might mean that the application is taking a long time to @@ -565,33 +565,33 @@ open class UIElement { /// - throws: `Error.ActionUnsupported` if the action is not supported. open func performAction(_ action: Action) throws(AXError) { let error = AXUIElementPerformAction(element, action.rawCFStringValue) - + guard error == .success else { throw error } } - + @available(*, deprecated, renamed: "performAction") open func performAction(_ action: String) throws(AXError) { try performAction(Action(rawValue: action)) } - + // MARK: - - + /// Returns the process ID of the application that the element is a part of. /// /// throws(AXError) only if the element is invalid (`Errors.InvalidUIElement`). open func pid() throws(AXError) -> pid_t { var pid: pid_t = -1 let error = AXUIElementGetPid(element, &pid) - + guard error == .success else { throw error } - + return pid } - + /// The timeout in seconds for all messages sent to this element. Use this to control how long a /// method call can delay execution. The default is `0`, which means to use the global timeout. /// @@ -602,7 +602,7 @@ open class UIElement { didSet { messagingTimeout = max(messagingTimeout, 0) let error = AXUIElementSetMessagingTimeout(element, messagingTimeout) - + // InvalidUIElement errors are only relevant when actually passing messages, so we can // ignore them here. guard error == .success || error == .invalidUIElement else { @@ -610,28 +610,28 @@ open class UIElement { } } } - + // Gets the element at the specified coordinates. // This can only be called on applications and the system-wide element, so it is internal here. func elementAtPosition(_ x: Float, _ y: Float) throws(AXError) -> UIElement? { var result: AXUIElement? let error = AXUIElementCopyElementAtPosition(element, x, y, &result) - + if error == .noValue { return nil } - + guard error == .success else { throw error } - + return result.map(UIElement.init) } - + func elementAtPosition(_ position: CGPoint) throws(AXError) -> UIElement? { try elementAtPosition(Float(position.x), Float(position.y)) } - + // TODO: convenience functions for attributes // TODO: get any attribute as a UIElement or [UIElement] (or a subclass) // TODO: promoters @@ -647,7 +647,7 @@ extension UIElement: CustomStringConvertible { do { let role = try self.role() roleString = role?.rawValue ?? "UIElementNoRole" - + switch role { case .some(.application): description = pid @@ -663,13 +663,13 @@ extension UIElement: CustomStringConvertible { } catch { roleString = "UnknownUIElement" } - + let pidString = (pid == nil) ? "??" : String(pid!) return "<\(roleString) \"" - + "\(description ?? String(describing: element))" - + "\" (pid=\(pidString))>" + + "\(description ?? String(describing: element))" + + "\" (pid=\(pidString))>" } - + public var inspect: String { guard let attributeNames = try? attributes() else { return "InvalidUIElement" @@ -689,10 +689,10 @@ public func ==(lhs: UIElement, rhs: UIElement) -> Bool { } extension UIElement: Hashable { - public func hash(into hasher: inout Hasher) { - let hashCode = CFHash(self) - hasher.combine(hashCode) - } + public func hash(into hasher: inout Hasher) { + let hashCode = CFHash(self) + hasher.combine(hashCode) + } } // MARK: - Convenience getters @@ -712,7 +712,7 @@ extension UIElement { return nil } } - + /// - seeAlso: [Subroles](https://developer.apple.com/library/mac/documentation/AppKit/Reference/NSAccessibility_Protocol_Reference/index.html#//apple_ref/doc/constant_group/Subroles) public func subrole() throws(AXError) -> Role.Subrole? { if let str: String = try self.attribute(.subrole) { From fc406f0dbf217f58195d1e7c08f86b4e1501aab8 Mon Sep 17 00:00:00 2001 From: Michael Redig Date: Sat, 14 Jun 2025 17:13:52 -0500 Subject: [PATCH 28/39] (nit) delete empty whitespace --- Sources/UIElement.swift | 202 ++++++++++++++++++++-------------------- 1 file changed, 101 insertions(+), 101 deletions(-) diff --git a/Sources/UIElement.swift b/Sources/UIElement.swift index b0eb510..ef43c8d 100644 --- a/Sources/UIElement.swift +++ b/Sources/UIElement.swift @@ -40,7 +40,7 @@ import Foundation /// - seeAlso: [AXUIElement.h reference](https://developer.apple.com/library/mac/documentation/ApplicationServices/Reference/AXUIElement_header_reference/) open class UIElement { public let element: AXUIElement - + /// Create a UIElement from a raw AXUIElement object. /// /// The state and role of the AXUIElement is not checked. @@ -48,10 +48,10 @@ open class UIElement { // Since we are dealing with low-level C APIs, it never hurts to double check types. assert(CFGetTypeID(nativeElement) == AXUIElementGetTypeID(), "nativeElement is not an AXUIElement") - + element = nativeElement } - + /// Checks if the current process is a trusted accessibility client. If false, all APIs will /// throw errors. /// @@ -63,45 +63,45 @@ open class UIElement { ] return AXIsProcessTrustedWithOptions(options as CFDictionary) } - + /// Timeout in seconds for all UIElement messages. Use this to control how long a method call /// can delay execution. The default is `0` which means to use the system default. open class var globalMessagingTimeout: Float { get { return systemWideElement.messagingTimeout } set { systemWideElement.messagingTimeout = newValue } } - + // MARK: - Attributes - + /// Returns the list of all attributes. /// /// Does not include parameterized attributes. open func attributes() throws(AXError) -> [Attribute] { var names: CFArray! let error = AXUIElementCopyAttributeNames(element, &names) - + guard error != .noValue, error != .attributeUnsupported, let names else { return [] } - + guard error == .success else { throw error } - + // We must first convert the CFArray to a native array, then downcast to an array of // strings. let strings = names as! [String] - + return strings.map(Attribute.init(rawValue:)) } - + // This version is named differently so the caller doesn't have to specify the return type when // using the enum version. @available(*, deprecated, renamed: "attributes", message: "If you need strings, just call `attributes().map(\\.rawValue)`") open func attributesAsStrings() throws(AXError) -> [String] { try attributes().map(\.rawValue) } - + /// Returns whether `attribute` is supported by this element. /// /// The `attribute` method returns nil for unsupported attributes and empty attributes alike, @@ -112,48 +112,48 @@ open class UIElement { // Ask to copy 0 values, since we are only interested in the return code. var value: CFArray? let error = AXUIElementCopyAttributeValues(element, attribute.rawCFStringValue, 0, 0, &value) - + if error == .attributeUnsupported { return false } - + if error == .noValue { return true } - + guard error == .success else { throw error } - + return true } - + @available(*, deprecated, renamed: "attributeIsSupported") open func attributeIsSupported(_ attribute: String) throws(AXError) -> Bool { try attributeIsSupported(Attribute(rawValue: attribute)) } - + /// Returns whether `attribute` is writeable. open func attributeIsSettable(_ attribute: Attribute) throws(AXError) -> Bool { var settable: DarwinBoolean = false let error = AXUIElementIsAttributeSettable(element, attribute.rawCFStringValue, &settable) - + if error == .noValue || error == .attributeUnsupported { return false } - + guard error == .success else { throw error } - + return settable.boolValue } - + @available(*, deprecated, renamed: "attributeIsSettable") open func attributeIsSettable(_ attribute: String) throws(AXError) -> Bool { try attributeIsSettable(Attribute(rawValue: attribute)) } - + /// Returns the value of `attribute`, if it exists. /// /// - parameter attribute: The name of a (non-parameterized) attribute. @@ -166,29 +166,29 @@ open class UIElement { open func attribute(_ attribute: Attribute) throws(AXError) -> T? { var value: AnyObject? let error = AXUIElementCopyAttributeValue(element, attribute.rawCFStringValue, &value) - + guard error != .noValue, error != .attributeUnsupported, let value else { return nil } - + guard error == .success else { throw error } - + guard let unpackedValue = (unpackAXValue(value) as? T) else { throw AXError.illegalArgument } - + return unpackedValue } - + @available(*, deprecated, renamed: "attribute") open func attribute(_ attribute: String) throws(AXError) -> T? { try self.attribute(Attribute(rawValue: attribute)) } - + /// Sets the value of `attribute` to `value`. /// /// - warning: Unlike read-only methods, this method throws(AXError) if the attribute doesn't exist. @@ -199,17 +199,17 @@ open class UIElement { /// - `Error.Failure`: A temporary failure occurred. open func setAttribute(_ attribute: Attribute, value: Any) throws(AXError) { let error = AXUIElementSetAttributeValue(element, attribute.rawCFStringValue, packAXValue(value)) - + guard error == .success else { throw error } } - + @available(*, deprecated, renamed: "setAttribute") open func setAttribute(_ attribute: String, value: Any) throws(AXError) { try setAttribute(Attribute(rawValue: attribute), value: value) } - + /// Gets multiple attributes of the element at once. /// /// - parameter attributes: An array of attribute names. Nonexistent attributes are ignored. @@ -225,17 +225,17 @@ open class UIElement { open func getMultipleAttributes(_ names: Attribute...) throws(AXError) -> [Attribute: Any] { return try getMultipleAttributes(names) } - + open func getMultipleAttributes(_ attributes: [Attribute]) throws(AXError) -> [Attribute: Any] { let values = try fetchMultiAttrValues(attributes) return try packMultiAttrValues(attributes, values: values) } - + open func getMultipleAttributes(_ attributes: [String]) throws(AXError) -> [String: Any] { let values = try fetchMultiAttrValues(attributes.map(Attribute.init(rawValue:))) return try packMultiAttrValues(attributes, values: values) } - + // Helper: Gets list of values fileprivate func fetchMultiAttrValues(_ attributes: [Attribute]) throws(AXError) -> [AnyObject] { var valuesCF: CFArray? @@ -245,14 +245,14 @@ open class UIElement { // keep going on errors (particularly NoValue) AXCopyMultipleAttributeOptions(rawValue: 0), &valuesCF) - + guard error == .success else { throw error } - + return valuesCF! as [AnyObject] } - + // Helper: Packs names, values into dictionary fileprivate func packMultiAttrValues( _ attributes: [Attr], @@ -266,20 +266,20 @@ open class UIElement { } return result } - + // Helper: Checks if value is present and not an error (throws on nontrivial errors). fileprivate func checkMultiAttrValue(_ value: AnyObject) throws(AXError) -> Bool { // Check for null if value is NSNull { return false } - + // Check for error if CFGetTypeID(value) == AXValueGetTypeID() && AXValueGetType(value as! AXValue).rawValue == kAXValueAXErrorType { var error: AXError = AXError.success AXValueGetValue(value as! AXValue, AXValueType(rawValue: kAXValueAXErrorType)!, &error) - + assert(error != .success) if error == .noValue || error == .attributeUnsupported { return false @@ -287,12 +287,12 @@ open class UIElement { throw error } } - + return true } - + // MARK: Array attributes - + /// Returns all the values of the attribute as an array of the given type. /// /// - parameter attribute: The name of the array attribute. @@ -308,12 +308,12 @@ open class UIElement { } return array.map({ unpackAXValue($0) as! T }) } - + @available(*, deprecated, renamed: "arrayAttribute") open func arrayAttribute(_ attribute: String) throws(AXError) -> [T]? { try arrayAttribute(Attribute(rawValue: attribute)) } - + /// Returns a subset of values from an array attribute. /// /// - parameter attribute: The name of the array attribute. @@ -331,51 +331,51 @@ open class UIElement { let error = AXUIElementCopyAttributeValues( element, attribute.rawCFStringValue, index, maxValues, &values ) - + guard error != .noValue, error != .attributeUnsupported, let values else { return nil } - + guard error == .success else { throw error } - + let array = values as [AnyObject] return array.map({ unpackAXValue($0) as! T }) } - + @available(*, deprecated, renamed: "valuesForAttribute") open func valuesForAttribute (_ attribute: String, startAtIndex index: Int, maxValues: Int) throws(AXError) -> [T]? { try valuesForAttribute(Attribute(rawValue: attribute), startAtIndex: index, maxValues: maxValues) } - + /// Returns the number of values an array attribute has. /// - returns: The number of values, or `nil` if `attribute` isn't an array (or doesn't exist). open func valueCountForAttribute(_ attribute: Attribute) throws(AXError) -> Int? { var count: Int = 0 let error = AXUIElementGetAttributeValueCount(element, attribute.rawCFStringValue, &count) - + if error == .attributeUnsupported || error == .illegalArgument { return nil } - + guard error == .success else { throw error } - + return count } - + @available(*, deprecated, renamed: "valueCountForAttribute") open func valueCountForAttribute(_ attribute: String) throws(AXError) -> Int? { try valueCountForAttribute(Attribute(rawValue: attribute)) } - + // MARK: Parameterized attributes - + /// Returns a list of all parameterized attributes of the element. /// /// Parameterized attributes are attributes that require parameters to retrieve. For example, @@ -383,31 +383,31 @@ open class UIElement { open func parameterizedAttributes() throws(AXError) -> [Attribute] { var names: CFArray? let error = AXUIElementCopyParameterizedAttributeNames(element, &names) - + guard error != .noValue, error != .attributeUnsupported, let names = names as? [AnyObject] else { return [] } - + guard error == .success else { throw error } - + // We must first convert the CFArray to a native array, then downcast to an array of // strings. guard let strings = names as? [String] else { return [] } - + return strings.map(Attribute.init(rawValue:)) } - + @available(*, deprecated, renamed: "parameterizedAttributes") open func parameterizedAttributesAsStrings() throws(AXError) -> [String] { try parameterizedAttributes().map(\.rawValue) } - + /// Returns the value of the parameterized attribute `attribute` with parameter `param`. /// /// The expected type of `param` depends on the attribute. See the @@ -418,27 +418,27 @@ open class UIElement { let error = AXUIElementCopyParameterizedAttributeValue( element, attribute.rawCFStringValue, param as AnyObject, &value ) - + guard error != .noValue, error != .attributeUnsupported, let value else { return nil } - + guard error == .success else { throw error } - + return (unpackAXValue(value) as! T) } - + @available(*, deprecated, renamed: "parameterizedAttribute") open func parameterizedAttribute(_ attribute: String, param: U) throws(AXError) -> T? { try parameterizedAttribute(Attribute(rawValue: attribute), param: param) } - + // MARK: Attribute helpers - + // Checks if the value is an AXValue and if so, unwraps it. // If the value is an AXUIElement, wraps it in UIElement. fileprivate func unpackAXValue(_ value: AnyObject) -> Any { @@ -482,7 +482,7 @@ open class UIElement { return value } } - + // Checks if the value is one supported by AXValue and if so, wraps it. // If the value is a UIElement, unwraps it to an AXUIElement. fileprivate func packAXValue(_ value: Any) -> AnyObject { @@ -501,14 +501,14 @@ open class UIElement { return value as AnyObject // must be an object to pass to AX } } - + // MARK: - Actions - + /// Returns a list of actions that can be performed on the element. open func actions() throws(AXError) -> [Action] { var names: CFArray? let error = AXUIElementCopyActionNames(element, &names) - + if error == .noValue || error == .attributeUnsupported { return [] } @@ -517,46 +517,46 @@ open class UIElement { error != .attributeUnsupported, let names = names as? [AnyObject] else { return [] } - + guard error == .success else { throw error } - + // We must first convert the CFArray to a native array, then downcast to an array of strings. guard let strings = names as? [String] else { return [] } - + return strings.map(Action.init(rawValue:)) } - + @available(*, deprecated, renamed: "actions") open func actionsAsStrings() throws(AXError) -> [String] { try actions().map(\.rawValue) } - + /// Returns the human-readable description of `action`. open func actionDescription(_ action: Action) throws(AXError) -> String? { var description: CFString? let error = AXUIElementCopyActionDescription(element, action.rawCFStringValue, &description) - + guard error != .noValue, error != .attributeUnsupported else { return nil } - + guard error == .success else { throw error } - + return description as? String } - + @available(*, deprecated, renamed: "actionDescription") open func actionDescription(_ action: String) throws(AXError) -> String? { try actionDescription(Action(rawValue: action)) } - + /// Performs the action `action` on the element, returning on success. /// /// - note: If the action times out, it might mean that the application is taking a long time to @@ -565,33 +565,33 @@ open class UIElement { /// - throws: `Error.ActionUnsupported` if the action is not supported. open func performAction(_ action: Action) throws(AXError) { let error = AXUIElementPerformAction(element, action.rawCFStringValue) - + guard error == .success else { throw error } } - + @available(*, deprecated, renamed: "performAction") open func performAction(_ action: String) throws(AXError) { try performAction(Action(rawValue: action)) } - + // MARK: - - + /// Returns the process ID of the application that the element is a part of. /// /// throws(AXError) only if the element is invalid (`Errors.InvalidUIElement`). open func pid() throws(AXError) -> pid_t { var pid: pid_t = -1 let error = AXUIElementGetPid(element, &pid) - + guard error == .success else { throw error } - + return pid } - + /// The timeout in seconds for all messages sent to this element. Use this to control how long a /// method call can delay execution. The default is `0`, which means to use the global timeout. /// @@ -602,7 +602,7 @@ open class UIElement { didSet { messagingTimeout = max(messagingTimeout, 0) let error = AXUIElementSetMessagingTimeout(element, messagingTimeout) - + // InvalidUIElement errors are only relevant when actually passing messages, so we can // ignore them here. guard error == .success || error == .invalidUIElement else { @@ -610,28 +610,28 @@ open class UIElement { } } } - + // Gets the element at the specified coordinates. // This can only be called on applications and the system-wide element, so it is internal here. func elementAtPosition(_ x: Float, _ y: Float) throws(AXError) -> UIElement? { var result: AXUIElement? let error = AXUIElementCopyElementAtPosition(element, x, y, &result) - + if error == .noValue { return nil } - + guard error == .success else { throw error } - + return result.map(UIElement.init) } - + func elementAtPosition(_ position: CGPoint) throws(AXError) -> UIElement? { try elementAtPosition(Float(position.x), Float(position.y)) } - + // TODO: convenience functions for attributes // TODO: get any attribute as a UIElement or [UIElement] (or a subclass) // TODO: promoters @@ -647,7 +647,7 @@ extension UIElement: CustomStringConvertible { do { let role = try self.role() roleString = role?.rawValue ?? "UIElementNoRole" - + switch role { case .some(.application): description = pid @@ -663,13 +663,13 @@ extension UIElement: CustomStringConvertible { } catch { roleString = "UnknownUIElement" } - + let pidString = (pid == nil) ? "??" : String(pid!) return "<\(roleString) \"" + "\(description ?? String(describing: element))" + "\" (pid=\(pidString))>" } - + public var inspect: String { guard let attributeNames = try? attributes() else { return "InvalidUIElement" @@ -712,7 +712,7 @@ extension UIElement { return nil } } - + /// - seeAlso: [Subroles](https://developer.apple.com/library/mac/documentation/AppKit/Reference/NSAccessibility_Protocol_Reference/index.html#//apple_ref/doc/constant_group/Subroles) public func subrole() throws(AXError) -> Role.Subrole? { if let str: String = try self.attribute(.subrole) { From 57e87c146baf8d9b74df9778ae1ad01eb863e713 Mon Sep 17 00:00:00 2001 From: Michael Redig Date: Sat, 14 Jun 2025 17:20:15 -0500 Subject: [PATCH 29/39] (refactor) organize file to group all deprecated Strings methods together --- Sources/UIElement.swift | 146 +++++++++++++++++++++------------------- 1 file changed, 76 insertions(+), 70 deletions(-) diff --git a/Sources/UIElement.swift b/Sources/UIElement.swift index ef43c8d..dd805d0 100644 --- a/Sources/UIElement.swift +++ b/Sources/UIElement.swift @@ -95,13 +95,6 @@ open class UIElement { return strings.map(Attribute.init(rawValue:)) } - // This version is named differently so the caller doesn't have to specify the return type when - // using the enum version. - @available(*, deprecated, renamed: "attributes", message: "If you need strings, just call `attributes().map(\\.rawValue)`") - open func attributesAsStrings() throws(AXError) -> [String] { - try attributes().map(\.rawValue) - } - /// Returns whether `attribute` is supported by this element. /// /// The `attribute` method returns nil for unsupported attributes and empty attributes alike, @@ -128,11 +121,6 @@ open class UIElement { return true } - @available(*, deprecated, renamed: "attributeIsSupported") - open func attributeIsSupported(_ attribute: String) throws(AXError) -> Bool { - try attributeIsSupported(Attribute(rawValue: attribute)) - } - /// Returns whether `attribute` is writeable. open func attributeIsSettable(_ attribute: Attribute) throws(AXError) -> Bool { var settable: DarwinBoolean = false @@ -149,11 +137,6 @@ open class UIElement { return settable.boolValue } - @available(*, deprecated, renamed: "attributeIsSettable") - open func attributeIsSettable(_ attribute: String) throws(AXError) -> Bool { - try attributeIsSettable(Attribute(rawValue: attribute)) - } - /// Returns the value of `attribute`, if it exists. /// /// - parameter attribute: The name of a (non-parameterized) attribute. @@ -184,11 +167,6 @@ open class UIElement { return unpackedValue } - @available(*, deprecated, renamed: "attribute") - open func attribute(_ attribute: String) throws(AXError) -> T? { - try self.attribute(Attribute(rawValue: attribute)) - } - /// Sets the value of `attribute` to `value`. /// /// - warning: Unlike read-only methods, this method throws(AXError) if the attribute doesn't exist. @@ -205,11 +183,6 @@ open class UIElement { } } - @available(*, deprecated, renamed: "setAttribute") - open func setAttribute(_ attribute: String, value: Any) throws(AXError) { - try setAttribute(Attribute(rawValue: attribute), value: value) - } - /// Gets multiple attributes of the element at once. /// /// - parameter attributes: An array of attribute names. Nonexistent attributes are ignored. @@ -231,11 +204,6 @@ open class UIElement { return try packMultiAttrValues(attributes, values: values) } - open func getMultipleAttributes(_ attributes: [String]) throws(AXError) -> [String: Any] { - let values = try fetchMultiAttrValues(attributes.map(Attribute.init(rawValue:))) - return try packMultiAttrValues(attributes, values: values) - } - // Helper: Gets list of values fileprivate func fetchMultiAttrValues(_ attributes: [Attribute]) throws(AXError) -> [AnyObject] { var valuesCF: CFArray? @@ -309,11 +277,6 @@ open class UIElement { return array.map({ unpackAXValue($0) as! T }) } - @available(*, deprecated, renamed: "arrayAttribute") - open func arrayAttribute(_ attribute: String) throws(AXError) -> [T]? { - try arrayAttribute(Attribute(rawValue: attribute)) - } - /// Returns a subset of values from an array attribute. /// /// - parameter attribute: The name of the array attribute. @@ -346,12 +309,6 @@ open class UIElement { return array.map({ unpackAXValue($0) as! T }) } - @available(*, deprecated, renamed: "valuesForAttribute") - open func valuesForAttribute - (_ attribute: String, startAtIndex index: Int, maxValues: Int) throws(AXError) -> [T]? { - try valuesForAttribute(Attribute(rawValue: attribute), startAtIndex: index, maxValues: maxValues) - } - /// Returns the number of values an array attribute has. /// - returns: The number of values, or `nil` if `attribute` isn't an array (or doesn't exist). open func valueCountForAttribute(_ attribute: Attribute) throws(AXError) -> Int? { @@ -369,10 +326,6 @@ open class UIElement { return count } - @available(*, deprecated, renamed: "valueCountForAttribute") - open func valueCountForAttribute(_ attribute: String) throws(AXError) -> Int? { - try valueCountForAttribute(Attribute(rawValue: attribute)) - } // MARK: Parameterized attributes @@ -403,11 +356,6 @@ open class UIElement { return strings.map(Attribute.init(rawValue:)) } - @available(*, deprecated, renamed: "parameterizedAttributes") - open func parameterizedAttributesAsStrings() throws(AXError) -> [String] { - try parameterizedAttributes().map(\.rawValue) - } - /// Returns the value of the parameterized attribute `attribute` with parameter `param`. /// /// The expected type of `param` depends on the attribute. See the @@ -432,10 +380,6 @@ open class UIElement { return (unpackAXValue(value) as! T) } - @available(*, deprecated, renamed: "parameterizedAttribute") - open func parameterizedAttribute(_ attribute: String, param: U) throws(AXError) -> T? { - try parameterizedAttribute(Attribute(rawValue: attribute), param: param) - } // MARK: Attribute helpers @@ -530,10 +474,6 @@ open class UIElement { return strings.map(Action.init(rawValue:)) } - @available(*, deprecated, renamed: "actions") - open func actionsAsStrings() throws(AXError) -> [String] { - try actions().map(\.rawValue) - } /// Returns the human-readable description of `action`. open func actionDescription(_ action: Action) throws(AXError) -> String? { @@ -552,11 +492,6 @@ open class UIElement { return description as? String } - @available(*, deprecated, renamed: "actionDescription") - open func actionDescription(_ action: String) throws(AXError) -> String? { - try actionDescription(Action(rawValue: action)) - } - /// Performs the action `action` on the element, returning on success. /// /// - note: If the action times out, it might mean that the application is taking a long time to @@ -571,11 +506,6 @@ open class UIElement { } } - @available(*, deprecated, renamed: "performAction") - open func performAction(_ action: String) throws(AXError) { - try performAction(Action(rawValue: action)) - } - // MARK: - /// Returns the process ID of the application that the element is a part of. @@ -632,6 +562,82 @@ open class UIElement { try elementAtPosition(Float(position.x), Float(position.y)) } + // MARK: - Deprecated Strings Methods + + // This version is named differently so the caller doesn't have to specify the return type when + // using the enum version. + @available(*, deprecated, renamed: "attributes", message: "If you need strings, just call `attributes().map(\\.rawValue)`") + open func attributesAsStrings() throws(AXError) -> [String] { + try attributes().map(\.rawValue) + } + + @available(*, deprecated, renamed: "attributeIsSupported") + open func attributeIsSupported(_ attribute: String) throws(AXError) -> Bool { + try attributeIsSupported(Attribute(rawValue: attribute)) + } + + @available(*, deprecated, renamed: "attributeIsSettable") + open func attributeIsSettable(_ attribute: String) throws(AXError) -> Bool { + try attributeIsSettable(Attribute(rawValue: attribute)) + } + + @available(*, deprecated, renamed: "attribute") + open func attribute(_ attribute: String) throws(AXError) -> T? { + try self.attribute(Attribute(rawValue: attribute)) + } + + @available(*, deprecated, renamed: "setAttribute") + open func setAttribute(_ attribute: String, value: Any) throws(AXError) { + try setAttribute(Attribute(rawValue: attribute), value: value) + } + + @available(*, deprecated, renamed: "getMultipleAttributes") + open func getMultipleAttributes(_ attributes: [String]) throws(AXError) -> [String: Any] { + let values = try fetchMultiAttrValues(attributes.map(Attribute.init(rawValue:))) + return try packMultiAttrValues(attributes, values: values) + } + + @available(*, deprecated, renamed: "arrayAttribute") + open func arrayAttribute(_ attribute: String) throws(AXError) -> [T]? { + try arrayAttribute(Attribute(rawValue: attribute)) + } + + @available(*, deprecated, renamed: "valuesForAttribute") + open func valuesForAttribute + (_ attribute: String, startAtIndex index: Int, maxValues: Int) throws(AXError) -> [T]? { + try valuesForAttribute(Attribute(rawValue: attribute), startAtIndex: index, maxValues: maxValues) + } + + @available(*, deprecated, renamed: "valueCountForAttribute") + open func valueCountForAttribute(_ attribute: String) throws(AXError) -> Int? { + try valueCountForAttribute(Attribute(rawValue: attribute)) + } + + @available(*, deprecated, renamed: "parameterizedAttributes") + open func parameterizedAttributesAsStrings() throws(AXError) -> [String] { + try parameterizedAttributes().map(\.rawValue) + } + + @available(*, deprecated, renamed: "parameterizedAttribute") + open func parameterizedAttribute(_ attribute: String, param: U) throws(AXError) -> T? { + try parameterizedAttribute(Attribute(rawValue: attribute), param: param) + } + + @available(*, deprecated, renamed: "actions") + open func actionsAsStrings() throws(AXError) -> [String] { + try actions().map(\.rawValue) + } + + @available(*, deprecated, renamed: "actionDescription") + open func actionDescription(_ action: String) throws(AXError) -> String? { + try actionDescription(Action(rawValue: action)) + } + + @available(*, deprecated, renamed: "performAction") + open func performAction(_ action: String) throws(AXError) { + try performAction(Action(rawValue: action)) + } + // TODO: convenience functions for attributes // TODO: get any attribute as a UIElement or [UIElement] (or a subclass) // TODO: promoters From 85485c5ac4658d8ee4380a6bc25290fead46f8e0 Mon Sep 17 00:00:00 2001 From: Michael Redig Date: Sat, 14 Jun 2025 17:28:45 -0500 Subject: [PATCH 30/39] (refactor) update docs --- Sources/UIElement.swift | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/Sources/UIElement.swift b/Sources/UIElement.swift index dd805d0..38104e5 100644 --- a/Sources/UIElement.swift +++ b/Sources/UIElement.swift @@ -11,14 +11,24 @@ import Foundation /// means that operations are synchronous and can hang until they time out. The default timeout is /// 6 seconds, but it can be changed using `setMessagingTimeout` and `setGlobalMessagingTimeout`. /// -/// Every attribute- or action-related function has an enum version and a String version. This is -/// because certain processes might report attributes or actions not documented in the standard API. -/// These will be ignored by enum functions (and you can't specify them). Most users will want to -/// use the enum-based versions, but if you want to be exhaustive or use non-standard attributes and -/// actions, you can use the String versions. +/// Every attribute- or action-related function has an RawRepresentable type safe version and a deprecated String +/// version. There are attributes and actions that might not be included in the lists in this package, and while this +/// was previously handled by provided a raw String interface, now the RawRepresentable structs can serve both +/// purposes. Dot syntax will still work (`element.attribute(.windows)`) and you can add additionally +/// unaccounted for values through extending the `Attribute`, `Action` or whatever type like so: +/// ```swift +/// extension Attribute { +/// static let windows = Attribute(rawValue: "AXWindows") +/// } +/// ``` +/// +/// Additionally, unaccounteded for attributes will now be provided in their appropriate RawRepresentable type +/// when returned from the system. /// /// ### Error handling /// +/// All throwing methods throw typed errors (Specifically `AXError`) +/// /// Unless otherwise specified, during reads, "missing data/attribute" errors are handled by /// returning optionals as nil. During writes, missing attribute errors are thrown. /// From cd7f589b54b0a7c872974b6b36ec0de1fe524917 Mon Sep 17 00:00:00 2001 From: Michael Redig Date: Sat, 14 Jun 2025 17:38:57 -0500 Subject: [PATCH 31/39] (nit) remove empty whitespace --- Sources/Application.swift | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Sources/Application.swift b/Sources/Application.swift index deb6e40..e71e466 100644 --- a/Sources/Application.swift +++ b/Sources/Application.swift @@ -7,12 +7,12 @@ public final class Application: UIElement { convenience init?(forKnownProcessID processID: pid_t) { let appElement = AXUIElementCreateApplication(processID) self.init(appElement) - + if processID < 0 { return nil } } - + /// Creates an `Application` from a `NSRunningApplication` instance. /// - returns: The `Application`, or `nil` if the given application is not running. public convenience init?(_ app: NSRunningApplication) { @@ -21,7 +21,7 @@ public final class Application: UIElement { } self.init(forKnownProcessID: app.processIdentifier) } - + /// Create an `Application` from the process ID of a running application. /// - returns: The `Application`, or `nil` if the PID is invalid or the given application /// is not running. @@ -31,7 +31,7 @@ public final class Application: UIElement { } self.init(app) } - + /// Creates an `Application` for every running application with a UI. /// - returns: An array of `Application`s. public class func all() -> [Application] { @@ -40,7 +40,7 @@ public final class Application: UIElement { .filter({ $0.activationPolicy != .prohibited }) .compactMap({ Application($0) }) } - + /// Creates an `Application` for every running instance of the given `bundleID`. /// - returns: A (potentially empty) array of `Application`s. public class func allForBundleID(_ bundleID: String) -> [Application] { @@ -49,7 +49,7 @@ public final class Application: UIElement { .filter({ $0.bundleIdentifier == bundleID }) .compactMap({ Application($0) }) } - + /// Creates an `Observer` on this application, if it is still alive. public func createObserver(_ callback: @escaping Observer.Callback) -> Observer? { do { @@ -60,7 +60,7 @@ public final class Application: UIElement { fatalError("Caught unexpected error creating observer: \(error)") } } - + /// Creates an `Observer` on this application, if it is still alive. public func createObserver(_ callback: @escaping Observer.CallbackWithInfo) -> Observer? { do { @@ -71,7 +71,7 @@ public final class Application: UIElement { fatalError("Caught unexpected error creating observer: \(error)") } } - + /// Returns a list of the application's visible windows. /// - returns: An array of `UIElement`s, one for every visible window. Or `nil` if the list /// cannot be retrieved. @@ -79,7 +79,7 @@ public final class Application: UIElement { let axWindows: [AXUIElement]? = try attribute(.windows) return axWindows?.map({ UIElement($0) }) } - + /// Returns the element at the specified top-down coordinates, or nil if there is none. public override func elementAtPosition(_ x: Float, _ y: Float) throws(AXError) -> UIElement? { return try super.elementAtPosition(x, y) From 9142fb210bdb65d0004cc61c7d260bd5aaae2280 Mon Sep 17 00:00:00 2001 From: Michael Redig Date: Sat, 14 Jun 2025 17:40:53 -0500 Subject: [PATCH 32/39] (refactor) delete commented code --- Sources/Observer.swift | 8 -------- 1 file changed, 8 deletions(-) diff --git a/Sources/Observer.swift b/Sources/Observer.swift index 479f67a..ec0c6f1 100644 --- a/Sources/Observer.swift +++ b/Sources/Observer.swift @@ -139,10 +139,6 @@ private func internalCallback(_ axObserver: AXObserver, let observer = Unmanaged.fromOpaque(userData).takeUnretainedValue() let element = UIElement(axElement) let notif = UIElement.AXNotification(rawValue: notification as String) - // guard let notif = UIElement.AXNotification(rawValue: notification as String) else { - // NSLog("Unknown AX notification %s received", notification as String) - // return - // } observer.callback!(observer, element, notif) } @@ -157,9 +153,5 @@ private func internalInfoCallback(_ axObserver: AXObserver, let element = UIElement(axElement) let info = cfInfo as NSDictionary? as! [String: AnyObject]? let notif = UIElement.AXNotification(rawValue: notification as String) - // guard let notif = UIElement.AXNotification(rawValue: notification as String) else { - // NSLog("Unknown AX notification %s received", notification as String) - // return - // } observer.callbackWithInfo!(observer, element, notif, info) } From 033445bc715e843c3d539aaeebd19b25e6d91daa Mon Sep 17 00:00:00 2001 From: Michael Redig Date: Sat, 14 Jun 2025 17:48:31 -0500 Subject: [PATCH 33/39] (refactor) dry up trusted prompt check --- Sources/AXSwift.swift | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Sources/AXSwift.swift b/Sources/AXSwift.swift index 22085c5..2996895 100644 --- a/Sources/AXSwift.swift +++ b/Sources/AXSwift.swift @@ -2,7 +2,5 @@ import Cocoa @discardableResult public func checkIsProcessTrusted(prompt: Bool = false) -> Bool { - let promptKey = kAXTrustedCheckOptionPrompt.takeUnretainedValue() as String - let opts = [promptKey: prompt] as CFDictionary - return AXIsProcessTrustedWithOptions(opts) + UIElement.isProcessTrusted(withPrompt: prompt) } From 46b467626adb9c6b53a5d48e68bac97777c58cd3 Mon Sep 17 00:00:00 2001 From: Michael Redig Date: Sat, 14 Jun 2025 18:01:36 -0500 Subject: [PATCH 34/39] (fix) replace sample String call --- AXSwiftExample/AppDelegate.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AXSwiftExample/AppDelegate.swift b/AXSwiftExample/AppDelegate.swift index acd2af6..0ab861a 100644 --- a/AXSwiftExample/AppDelegate.swift +++ b/AXSwiftExample/AppDelegate.swift @@ -33,7 +33,7 @@ class ApplicationDelegate: NSObject, NSApplicationDelegate { if let title: String = try! app.attribute(.title) { NSLog("title: \(title)") } - NSLog("multi: \(try! app.getMultipleAttributes(["AXRole", "asdf", "AXTitle"]))") + NSLog("multi: \(try! app.getMultipleAttributes([.role, .init(rawValue: "asdf"), .title]))") NSLog("multi: \(try! app.getMultipleAttributes(.role, .title))") // Try to set an unsettable attribute From d05582a5aed0f28e2e76fb941035dd7b35ebfaf2 Mon Sep 17 00:00:00 2001 From: Michael Redig Date: Sat, 14 Jun 2025 18:03:26 -0500 Subject: [PATCH 35/39] (fix) resolve concurrency race condition --- AXSwiftObserverExample/AppDelegate.swift | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/AXSwiftObserverExample/AppDelegate.swift b/AXSwiftObserverExample/AppDelegate.swift index b032abc..8fae6c5 100644 --- a/AXSwiftObserverExample/AppDelegate.swift +++ b/AXSwiftObserverExample/AppDelegate.swift @@ -21,8 +21,23 @@ class AppDelegate: NSObject, NSApplicationDelegate { } } + private class Sendly: @unchecked Sendable { + private let lock = NSLock() + private var _value: T + var value: T { + get { lock.withLock { _value } } + set { lock.withLock { _value = newValue } } + } + + init(_ value: T) { + lock.lock() + defer { lock.unlock() } + self._value = value + } + } + func startWatcher(_ app: Application) throws { - var updated = false + let updated = Sendly(false) observer = app.createObserver { (observer: Observer, element: UIElement, event: UIElement.AXNotification, info: [String: AnyObject]?) in var elementDesc: String! if let role = try? element.role()!, role == .window { @@ -43,12 +58,12 @@ class AppDelegate: NSObject, NSApplicationDelegate { } // Group simultaneous events together with --- lines - if !updated { - updated = true + if !updated.value { + updated.value = true // Set this code to run after the current run loop, which is dispatching all notifications. DispatchQueue.main.async { print("---") - updated = false + updated.value = false } } } From 85bc750967375d518fe1e156bf2d54a4ea827a22 Mon Sep 17 00:00:00 2001 From: Michael Redig Date: Sat, 14 Jun 2025 21:42:24 -0500 Subject: [PATCH 36/39] (fix) typed throws on overlooked methods --- Sources/Application.swift | 2 +- Sources/Observer.swift | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Sources/Application.swift b/Sources/Application.swift index e71e466..99f55d1 100644 --- a/Sources/Application.swift +++ b/Sources/Application.swift @@ -75,7 +75,7 @@ public final class Application: UIElement { /// Returns a list of the application's visible windows. /// - returns: An array of `UIElement`s, one for every visible window. Or `nil` if the list /// cannot be retrieved. - public func windows() throws -> [UIElement]? { + public func windows() throws(AXError) -> [UIElement]? { let axWindows: [AXUIElement]? = try attribute(.windows) return axWindows?.map({ UIElement($0) }) } diff --git a/Sources/Observer.swift b/Sources/Observer.swift index ec0c6f1..682c22e 100644 --- a/Sources/Observer.swift +++ b/Sources/Observer.swift @@ -25,7 +25,7 @@ public final class Observer { Application(forKnownProcessID: self.pid)! /// Creates and starts an observer on the given `processID`. - public init(processID: pid_t, callback: @escaping Callback) throws { + public init(processID: pid_t, callback: @escaping Callback) throws(AXError) { var axObserver: AXObserver? let error = AXObserverCreate(processID, internalCallback, &axObserver) @@ -46,7 +46,7 @@ public final class Observer { /// /// Use this initializer if you want the extra user info provided with notifications. /// - seeAlso: [UserInfo Keys for Posting Accessibility Notifications](https://developer.apple.com/library/mac/documentation/AppKit/Reference/NSAccessibility_Protocol_Reference/index.html#//apple_ref/doc/constant_group/UserInfo_Keys_for_Posting_Accessibility_Notifications) - public init(processID: pid_t, callback: @escaping CallbackWithInfo) throws { + public init(processID: pid_t, callback: @escaping CallbackWithInfo) throws(AXError) { var axObserver: AXObserver? let error = AXObserverCreateWithInfoCallback(processID, internalInfoCallback, &axObserver) @@ -101,7 +101,7 @@ public final class Observer { /// - throws: `Error.NotificationUnsupported`: The element does not support notifications (note /// that the system-wide element does not support notifications). public func addNotification(_ notification: UIElement.AXNotification, - forElement element: UIElement) throws { + forElement element: UIElement) throws(AXError) { let selfPtr = UnsafeMutableRawPointer(Unmanaged.passUnretained(self).toOpaque()) let error = AXObserverAddNotification( axObserver, element.element, notification.rawValue as CFString, selfPtr @@ -120,7 +120,7 @@ public final class Observer { /// - throws: `Error.NotificationUnsupported`: The element does not support notifications (note /// that the system-wide element does not support notifications). public func removeNotification(_ notification: UIElement.AXNotification, - forElement element: UIElement) throws { + forElement element: UIElement) throws(AXError) { let error = AXObserverRemoveNotification( axObserver, element.element, notification.rawValue as CFString ) From 9c713442698f2fbe1508905f4c915f8143778116 Mon Sep 17 00:00:00 2001 From: Michael Redig Date: Sun, 15 Jun 2025 00:44:43 -0500 Subject: [PATCH 37/39] (fix) operation order --- Sources/UIElement.swift | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Sources/UIElement.swift b/Sources/UIElement.swift index 38104e5..f839718 100644 --- a/Sources/UIElement.swift +++ b/Sources/UIElement.swift @@ -162,14 +162,17 @@ open class UIElement { guard error != .noValue, - error != .attributeUnsupported, - let value - else { return nil } + error != .attributeUnsupported + else { return nil } guard error == .success else { throw error } + guard let value else { + return nil + } + guard let unpackedValue = (unpackAXValue(value) as? T) else { throw AXError.illegalArgument } From 5d73ab4b3510df614185f124d0c4b9b6a57dffdf Mon Sep 17 00:00:00 2001 From: Michael Redig Date: Sun, 15 Jun 2025 03:21:16 -0500 Subject: [PATCH 38/39] (fix) spacing --- Sources/Constants/Attribute.swift | 318 +++++++++++++++--------------- 1 file changed, 159 insertions(+), 159 deletions(-) diff --git a/Sources/Constants/Attribute.swift b/Sources/Constants/Attribute.swift index f8ecbc5..efa11ee 100644 --- a/Sources/Constants/Attribute.swift +++ b/Sources/Constants/Attribute.swift @@ -12,225 +12,225 @@ extension UIElement { } // Standard attributes - public static let role = Attribute(rawValue: "AXRole") //(NSString *) - type, non-localized (e.g. radioButton) - public static let roleDescription = Attribute(rawValue: "AXRoleDescription") //(NSString *) - user readable role (e.g. "radio button") - public static let subrole = Attribute(rawValue: "AXSubrole") //(NSString *) - type, non-localized (e.g. closeButton) - public static let help = Attribute(rawValue: "AXHelp") //(NSString *) - instance description (e.g. a tool tip) - public static let value = Attribute(rawValue: "AXValue") //(id) - element's value - public static let minValue = Attribute(rawValue: "AXMinValue") //(id) - element's min value - public static let maxValue = Attribute(rawValue: "AXMaxValue") //(id) - element's max value - public static let enabled = Attribute(rawValue: "AXEnabled") //(NSNumber *) - (boolValue) responds to user? - public static let focused = Attribute(rawValue: "AXFocused") //(NSNumber *) - (boolValue) has keyboard focus? - public static let parent = Attribute(rawValue: "AXParent") //(id) - element containing you - public static let children = Attribute(rawValue: "AXChildren") //(NSArray *) - elements you contain - public static let window = Attribute(rawValue: "AXWindow") //(id) - UIElement for the containing window - public static let topLevelUIElement = Attribute(rawValue: "AXTopLevelUIElement") //(id) - UIElement for the containing top level element - public static let selectedChildren = Attribute(rawValue: "AXSelectedChildren") //(NSArray *) - child elements which are selected - public static let visibleChildren = Attribute(rawValue: "AXVisibleChildren") //(NSArray *) - child elements which are visible - public static let position = Attribute(rawValue: "AXPosition") //(NSValue *) - (pointValue) position in screen coords - public static let size = Attribute(rawValue: "AXSize") //(NSValue *) - (sizeValue) size - public static let frame = Attribute(rawValue: "AXFrame") //(NSValue *) - (rectValue) frame - public static let contents = Attribute(rawValue: "AXContents") //(NSArray *) - main elements - public static let title = Attribute(rawValue: "AXTitle") //(NSString *) - visible text (e.g. of a push button) - public static let description = Attribute(rawValue: "AXDescription") //(NSString *) - instance description - public static let shownMenu = Attribute(rawValue: "AXShownMenu") //(id) - menu being displayed - public static let valueDescription = Attribute(rawValue: "AXValueDescription") //(NSString *) - text description of value - - public static let sharedFocusElements = Attribute(rawValue: "AXSharedFocusElements") //(NSArray *) - elements that share focus + public static let role = Attribute(rawValue: "AXRole") //(NSString *) - type, non-localized (e.g. radioButton) + public static let roleDescription = Attribute(rawValue: "AXRoleDescription") //(NSString *) - user readable role (e.g. "radio button") + public static let subrole = Attribute(rawValue: "AXSubrole") //(NSString *) - type, non-localized (e.g. closeButton) + public static let help = Attribute(rawValue: "AXHelp") //(NSString *) - instance description (e.g. a tool tip) + public static let value = Attribute(rawValue: "AXValue") //(id) - element's value + public static let minValue = Attribute(rawValue: "AXMinValue") //(id) - element's min value + public static let maxValue = Attribute(rawValue: "AXMaxValue") //(id) - element's max value + public static let enabled = Attribute(rawValue: "AXEnabled") //(NSNumber *) - (boolValue) responds to user? + public static let focused = Attribute(rawValue: "AXFocused") //(NSNumber *) - (boolValue) has keyboard focus? + public static let parent = Attribute(rawValue: "AXParent") //(id) - element containing you + public static let children = Attribute(rawValue: "AXChildren") //(NSArray *) - elements you contain + public static let window = Attribute(rawValue: "AXWindow") //(id) - UIElement for the containing window + public static let topLevelUIElement = Attribute(rawValue: "AXTopLevelUIElement") //(id) - UIElement for the containing top level element + public static let selectedChildren = Attribute(rawValue: "AXSelectedChildren") //(NSArray *) - child elements which are selected + public static let visibleChildren = Attribute(rawValue: "AXVisibleChildren") //(NSArray *) - child elements which are visible + public static let position = Attribute(rawValue: "AXPosition") //(NSValue *) - (pointValue) position in screen coords + public static let size = Attribute(rawValue: "AXSize") //(NSValue *) - (sizeValue) size + public static let frame = Attribute(rawValue: "AXFrame") //(NSValue *) - (rectValue) frame + public static let contents = Attribute(rawValue: "AXContents") //(NSArray *) - main elements + public static let title = Attribute(rawValue: "AXTitle") //(NSString *) - visible text (e.g. of a push button) + public static let description = Attribute(rawValue: "AXDescription") //(NSString *) - instance description + public static let shownMenu = Attribute(rawValue: "AXShownMenu") //(id) - menu being displayed + public static let valueDescription = Attribute(rawValue: "AXValueDescription") //(NSString *) - text description of value + + public static let sharedFocusElements = Attribute(rawValue: "AXSharedFocusElements") //(NSArray *) - elements that share focus // Misc attributes - public static let previousContents = Attribute(rawValue: "AXPreviousContents") //(NSArray *) - main elements - public static let nextContents = Attribute(rawValue: "AXNextContents") //(NSArray *) - main elements - public static let header = Attribute(rawValue: "AXHeader") //(id) - UIElement for header. - public static let edited = Attribute(rawValue: "AXEdited") //(NSNumber *) - (boolValue) is it dirty? - public static let tabs = Attribute(rawValue: "AXTabs") //(NSArray *) - UIElements for tabs - public static let horizontalScrollBar = Attribute(rawValue: "AXHorizontalScrollBar") //(id) - UIElement for the horizontal scroller - public static let verticalScrollBar = Attribute(rawValue: "AXVerticalScrollBar") //(id) - UIElement for the vertical scroller - public static let overflowButton = Attribute(rawValue: "AXOverflowButton") //(id) - UIElement for overflow - public static let incrementButton = Attribute(rawValue: "AXIncrementButton") //(id) - UIElement for increment - public static let decrementButton = Attribute(rawValue: "AXDecrementButton") //(id) - UIElement for decrement - public static let filename = Attribute(rawValue: "AXFilename") //(NSString *) - filename - public static let expanded = Attribute(rawValue: "AXExpanded") //(NSNumber *) - (boolValue) is expanded? - public static let selected = Attribute(rawValue: "AXSelected") //(NSNumber *) - (boolValue) is selected? - public static let splitters = Attribute(rawValue: "AXSplitters") //(NSArray *) - UIElements for splitters - public static let document = Attribute(rawValue: "AXDocument") //(NSString *) - url as string - for open document - public static let activationPoint = Attribute(rawValue: "AXActivationPoint") //(NSValue *) - (pointValue) + public static let previousContents = Attribute(rawValue: "AXPreviousContents") //(NSArray *) - main elements + public static let nextContents = Attribute(rawValue: "AXNextContents") //(NSArray *) - main elements + public static let header = Attribute(rawValue: "AXHeader") //(id) - UIElement for header. + public static let edited = Attribute(rawValue: "AXEdited") //(NSNumber *) - (boolValue) is it dirty? + public static let tabs = Attribute(rawValue: "AXTabs") //(NSArray *) - UIElements for tabs + public static let horizontalScrollBar = Attribute(rawValue: "AXHorizontalScrollBar") //(id) - UIElement for the horizontal scroller + public static let verticalScrollBar = Attribute(rawValue: "AXVerticalScrollBar") //(id) - UIElement for the vertical scroller + public static let overflowButton = Attribute(rawValue: "AXOverflowButton") //(id) - UIElement for overflow + public static let incrementButton = Attribute(rawValue: "AXIncrementButton") //(id) - UIElement for increment + public static let decrementButton = Attribute(rawValue: "AXDecrementButton") //(id) - UIElement for decrement + public static let filename = Attribute(rawValue: "AXFilename") //(NSString *) - filename + public static let expanded = Attribute(rawValue: "AXExpanded") //(NSNumber *) - (boolValue) is expanded? + public static let selected = Attribute(rawValue: "AXSelected") //(NSNumber *) - (boolValue) is selected? + public static let splitters = Attribute(rawValue: "AXSplitters") //(NSArray *) - UIElements for splitters + public static let document = Attribute(rawValue: "AXDocument") //(NSString *) - url as string - for open document + public static let activationPoint = Attribute(rawValue: "AXActivationPoint") //(NSValue *) - (pointValue) - public static let url = Attribute(rawValue: "AXURL") //(NSURL *) - url - public static let index = Attribute(rawValue: "AXIndex") //(NSNumber *) - (intValue) + public static let url = Attribute(rawValue: "AXURL") //(NSURL *) - url + public static let index = Attribute(rawValue: "AXIndex") //(NSNumber *) - (intValue) - public static let rowCount = Attribute(rawValue: "AXRowCount") //(NSNumber *) - (intValue) number of rows + public static let rowCount = Attribute(rawValue: "AXRowCount") //(NSNumber *) - (intValue) number of rows - public static let columnCount = Attribute(rawValue: "AXColumnCount") //(NSNumber *) - (intValue) number of columns + public static let columnCount = Attribute(rawValue: "AXColumnCount") //(NSNumber *) - (intValue) number of columns - public static let orderedByRow = Attribute(rawValue: "AXOrderedByRow") //(NSNumber *) - (boolValue) is ordered by row? + public static let orderedByRow = Attribute(rawValue: "AXOrderedByRow") //(NSNumber *) - (boolValue) is ordered by row? - public static let warningValue = Attribute(rawValue: "AXWarningValue") //(id) - warning value of a level indicator, typically a number + public static let warningValue = Attribute(rawValue: "AXWarningValue") //(id) - warning value of a level indicator, typically a number - public static let criticalValue = Attribute(rawValue: "AXCriticalValue") //(id) - critical value of a level indicator, typically a number + public static let criticalValue = Attribute(rawValue: "AXCriticalValue") //(id) - critical value of a level indicator, typically a number - public static let placeholderValue = Attribute(rawValue: "AXPlaceholderValue") //(NSString *) - placeholder value of a control such as a text field + public static let placeholderValue = Attribute(rawValue: "AXPlaceholderValue") //(NSString *) - placeholder value of a control such as a text field - public static let containsProtectedContent = Attribute(rawValue: "AXContainsProtectedContent") // (NSNumber *) - (boolValue) contains protected content? - public static let alternateUIVisible = Attribute(rawValue: "AXAlternateUIVisible") //(NSNumber *) - (boolValue) + public static let containsProtectedContent = Attribute(rawValue: "AXContainsProtectedContent") // (NSNumber *) - (boolValue) contains protected content? + public static let alternateUIVisible = Attribute(rawValue: "AXAlternateUIVisible") //(NSNumber *) - (boolValue) // Linkage attributes - public static let titleUIElement = Attribute(rawValue: "AXTitleUIElement") //(id) - UIElement for the title - public static let servesAsTitleForUIElements = Attribute(rawValue: "AXServesAsTitleForUIElements") //(NSArray *) - UIElements this titles - public static let linkedUIElements = Attribute(rawValue: "AXLinkedUIElements") //(NSArray *) - corresponding UIElements + public static let titleUIElement = Attribute(rawValue: "AXTitleUIElement") //(id) - UIElement for the title + public static let servesAsTitleForUIElements = Attribute(rawValue: "AXServesAsTitleForUIElements") //(NSArray *) - UIElements this titles + public static let linkedUIElements = Attribute(rawValue: "AXLinkedUIElements") //(NSArray *) - corresponding UIElements // Text-specific attributes - public static let selectedText = Attribute(rawValue: "AXSelectedText") //(NSString *) - selected text - public static let selectedTextRange = Attribute(rawValue: "AXSelectedTextRange") //(NSValue *) - (rangeValue) range of selected text - public static let numberOfCharacters = Attribute(rawValue: "AXNumberOfCharacters") //(NSNumber *) - number of characters - public static let visibleCharacterRange = Attribute(rawValue: "AXVisibleCharacterRange") //(NSValue *) - (rangeValue) range of visible text - public static let sharedTextUIElements = Attribute(rawValue: "AXSharedTextUIElements") //(NSArray *) - text views sharing text - public static let sharedCharacterRange = Attribute(rawValue: "AXSharedCharacterRange") //(NSValue *) - (rangeValue) part of shared text in this view - public static let insertionPointLineNumber = Attribute(rawValue: "AXInsertionPointLineNumber") //(NSNumber *) - line# containing caret - public static let selectedTextRanges = Attribute(rawValue: "AXSelectedTextRanges") //(NSArray *) - array of NSValue (rangeValue) ranges of selected text + public static let selectedText = Attribute(rawValue: "AXSelectedText") //(NSString *) - selected text + public static let selectedTextRange = Attribute(rawValue: "AXSelectedTextRange") //(NSValue *) - (rangeValue) range of selected text + public static let numberOfCharacters = Attribute(rawValue: "AXNumberOfCharacters") //(NSNumber *) - number of characters + public static let visibleCharacterRange = Attribute(rawValue: "AXVisibleCharacterRange") //(NSValue *) - (rangeValue) range of visible text + public static let sharedTextUIElements = Attribute(rawValue: "AXSharedTextUIElements") //(NSArray *) - text views sharing text + public static let sharedCharacterRange = Attribute(rawValue: "AXSharedCharacterRange") //(NSValue *) - (rangeValue) part of shared text in this view + public static let insertionPointLineNumber = Attribute(rawValue: "AXInsertionPointLineNumber") //(NSNumber *) - line# containing caret + public static let selectedTextRanges = Attribute(rawValue: "AXSelectedTextRanges") //(NSArray *) - array of NSValue (rangeValue) ranges of selected text /// - note: private/undocumented attribute - public static let textInputMarkedRange = Attribute(rawValue: "AXTextInputMarkedRange") + public static let textInputMarkedRange = Attribute(rawValue: "AXTextInputMarkedRange") // Parameterized text-specific attributes - public static let lineForIndexParameterized = Attribute(rawValue: "AXLineForIndexParameterized") //(NSNumber *) - line# for char index; param:(NSNumber *) - public static let rangeForLineParameterized = Attribute(rawValue: "AXRangeForLineParameterized") //(NSValue *) - (rangeValue) range of line; param:(NSNumber *) - public static let stringForRangeParameterized = Attribute(rawValue: "AXStringForRangeParameterized") //(NSString *) - substring; param:(NSValue * - rangeValue) - public static let rangeForPositionParameterized = Attribute(rawValue: "AXRangeForPositionParameterized") //(NSValue *) - (rangeValue) composed char range; param:(NSValue * - pointValue) - public static let rangeForIndexParameterized = Attribute(rawValue: "AXRangeForIndexParameterized") //(NSValue *) - (rangeValue) composed char range; param:(NSNumber *) - public static let boundsForRangeParameterized = Attribute(rawValue: "AXBoundsForRangeParameterized") //(NSValue *) - (rectValue) bounds of text; param:(NSValue * - rangeValue) - public static let rtfForRangeParameterized = Attribute(rawValue: "AXRTFForRangeParameterized") //(NSData *) - rtf for text; param:(NSValue * - rangeValue) - public static let styleRangeForIndexParameterized = Attribute(rawValue: "AXStyleRangeForIndexParameterized") //(NSValue *) - (rangeValue) extent of style run; param:(NSNumber *) - public static let attributedStringForRangeParameterized = Attribute(rawValue: "AXAttributedStringForRangeParameterized") //(NSAttributedString *) - does _not_ use attributes from Appkit/AttributedString.h + public static let lineForIndexParameterized = Attribute(rawValue: "AXLineForIndexParameterized") //(NSNumber *) - line# for char index; param:(NSNumber *) + public static let rangeForLineParameterized = Attribute(rawValue: "AXRangeForLineParameterized") //(NSValue *) - (rangeValue) range of line; param:(NSNumber *) + public static let stringForRangeParameterized = Attribute(rawValue: "AXStringForRangeParameterized") //(NSString *) - substring; param:(NSValue * - rangeValue) + public static let rangeForPositionParameterized = Attribute(rawValue: "AXRangeForPositionParameterized") //(NSValue *) - (rangeValue) composed char range; param:(NSValue * - pointValue) + public static let rangeForIndexParameterized = Attribute(rawValue: "AXRangeForIndexParameterized") //(NSValue *) - (rangeValue) composed char range; param:(NSNumber *) + public static let boundsForRangeParameterized = Attribute(rawValue: "AXBoundsForRangeParameterized") //(NSValue *) - (rectValue) bounds of text; param:(NSValue * - rangeValue) + public static let rtfForRangeParameterized = Attribute(rawValue: "AXRTFForRangeParameterized") //(NSData *) - rtf for text; param:(NSValue * - rangeValue) + public static let styleRangeForIndexParameterized = Attribute(rawValue: "AXStyleRangeForIndexParameterized") //(NSValue *) - (rangeValue) extent of style run; param:(NSNumber *) + public static let attributedStringForRangeParameterized = Attribute(rawValue: "AXAttributedStringForRangeParameterized") //(NSAttributedString *) - does _not_ use attributes from Appkit/AttributedString.h // Text attributed string attributes and constants - public static let fontText = Attribute(rawValue: "AXFontText") //(NSDictionary *) - NSAccessibilityFontXXXKey's - public static let foregroundColorText = Attribute(rawValue: "AXForegroundColorText") //CGColorRef - public static let backgroundColorText = Attribute(rawValue: "AXBackgroundColorText") //CGColorRef - public static let underlineColorText = Attribute(rawValue: "AXUnderlineColorText") //CGColorRef - public static let strikethroughColorText = Attribute(rawValue: "AXStrikethroughColorText") //CGColorRef - public static let underlineText = Attribute(rawValue: "AXUnderlineText") //(NSNumber *) - underline style - public static let superscriptText = Attribute(rawValue: "AXSuperscriptText") //(NSNumber *) - superscript>0, subscript<0 - public static let strikethroughText = Attribute(rawValue: "AXStrikethroughText") //(NSNumber *) - (boolValue) - public static let shadowText = Attribute(rawValue: "AXShadowText") //(NSNumber *) - (boolValue) - public static let attachmentText = Attribute(rawValue: "AXAttachmentText") //id - corresponding element - public static let linkText = Attribute(rawValue: "AXLinkText") //id - corresponding element - public static let autocorrectedText = Attribute(rawValue: "AXAutocorrectedText") //(NSNumber *) - (boolValue) + public static let fontText = Attribute(rawValue: "AXFontText") //(NSDictionary *) - NSAccessibilityFontXXXKey's + public static let foregroundColorText = Attribute(rawValue: "AXForegroundColorText") //CGColorRef + public static let backgroundColorText = Attribute(rawValue: "AXBackgroundColorText") //CGColorRef + public static let underlineColorText = Attribute(rawValue: "AXUnderlineColorText") //CGColorRef + public static let strikethroughColorText = Attribute(rawValue: "AXStrikethroughColorText") //CGColorRef + public static let underlineText = Attribute(rawValue: "AXUnderlineText") //(NSNumber *) - underline style + public static let superscriptText = Attribute(rawValue: "AXSuperscriptText") //(NSNumber *) - superscript>0, subscript<0 + public static let strikethroughText = Attribute(rawValue: "AXStrikethroughText") //(NSNumber *) - (boolValue) + public static let shadowText = Attribute(rawValue: "AXShadowText") //(NSNumber *) - (boolValue) + public static let attachmentText = Attribute(rawValue: "AXAttachmentText") //id - corresponding element + public static let linkText = Attribute(rawValue: "AXLinkText") //id - corresponding element + public static let autocorrectedText = Attribute(rawValue: "AXAutocorrectedText") //(NSNumber *) - (boolValue) // Textual list attributes and constants. Examples: unordered or ordered lists in a document. - public static let listItemPrefixText = Attribute(rawValue: "AXListItemPrefixText") // NSAttributedString, the prepended string of the list item. If the string is a common unicode character (e.g. a bullet •), return that unicode character. For lists with images before the text, return a reasonable label of the image. - public static let listItemIndexText = Attribute(rawValue: "AXListItemIndexText") // NSNumber, integerValue of the line index. Each list item increments the index, even for unordered lists. The first item should have index 0. - public static let listItemLevelText = Attribute(rawValue: "AXListItemLevelText") // NSNumber, integerValue of the indent level. Each sublist increments the level. The first item should have level 0. + public static let listItemPrefixText = Attribute(rawValue: "AXListItemPrefixText") // NSAttributedString, the prepended string of the list item. If the string is a common unicode character (e.g. a bullet •), return that unicode character. For lists with images before the text, return a reasonable label of the image. + public static let listItemIndexText = Attribute(rawValue: "AXListItemIndexText") // NSNumber, integerValue of the line index. Each list item increments the index, even for unordered lists. The first item should have index 0. + public static let listItemLevelText = Attribute(rawValue: "AXListItemLevelText") // NSNumber, integerValue of the indent level. Each sublist increments the level. The first item should have level 0. // MisspelledText attributes - public static let misspelledText = Attribute(rawValue: "AXMisspelledText") //(NSNumber *) - (boolValue) - public static let markedMisspelledText = Attribute(rawValue: "AXMarkedMisspelledText") //(NSNumber *) - (boolValue) + public static let misspelledText = Attribute(rawValue: "AXMisspelledText") //(NSNumber *) - (boolValue) + public static let markedMisspelledText = Attribute(rawValue: "AXMarkedMisspelledText") //(NSNumber *) - (boolValue) // Window-specific attributes - public static let main = Attribute(rawValue: "AXMain") //(NSNumber *) - (boolValue) is it the main window? - public static let minimized = Attribute(rawValue: "AXMinimized") //(NSNumber *) - (boolValue) is window minimized? - public static let closeButton = Attribute(rawValue: "AXCloseButton") //(id) - UIElement for close box (or nil) - public static let zoomButton = Attribute(rawValue: "AXZoomButton") //(id) - UIElement for zoom box (or nil) - public static let minimizeButton = Attribute(rawValue: "AXMinimizeButton") //(id) - UIElement for miniaturize box (or nil) - public static let toolbarButton = Attribute(rawValue: "AXToolbarButton") //(id) - UIElement for toolbar box (or nil) - public static let proxy = Attribute(rawValue: "AXProxy") //(id) - UIElement for title's icon (or nil) - public static let growArea = Attribute(rawValue: "AXGrowArea") //(id) - UIElement for grow box (or nil) - public static let modal = Attribute(rawValue: "AXModal") //(NSNumber *) - (boolValue) is the window modal - public static let defaultButton = Attribute(rawValue: "AXDefaultButton") //(id) - UIElement for default button - public static let cancelButton = Attribute(rawValue: "AXCancelButton") //(id) - UIElement for cancel button - public static let fullScreenButton = Attribute(rawValue: "AXFullScreenButton") //(id) - UIElement for full screen button (or nil) + public static let main = Attribute(rawValue: "AXMain") //(NSNumber *) - (boolValue) is it the main window? + public static let minimized = Attribute(rawValue: "AXMinimized") //(NSNumber *) - (boolValue) is window minimized? + public static let closeButton = Attribute(rawValue: "AXCloseButton") //(id) - UIElement for close box (or nil) + public static let zoomButton = Attribute(rawValue: "AXZoomButton") //(id) - UIElement for zoom box (or nil) + public static let minimizeButton = Attribute(rawValue: "AXMinimizeButton") //(id) - UIElement for miniaturize box (or nil) + public static let toolbarButton = Attribute(rawValue: "AXToolbarButton") //(id) - UIElement for toolbar box (or nil) + public static let proxy = Attribute(rawValue: "AXProxy") //(id) - UIElement for title's icon (or nil) + public static let growArea = Attribute(rawValue: "AXGrowArea") //(id) - UIElement for grow box (or nil) + public static let modal = Attribute(rawValue: "AXModal") //(NSNumber *) - (boolValue) is the window modal + public static let defaultButton = Attribute(rawValue: "AXDefaultButton") //(id) - UIElement for default button + public static let cancelButton = Attribute(rawValue: "AXCancelButton") //(id) - UIElement for cancel button + public static let fullScreenButton = Attribute(rawValue: "AXFullScreenButton") //(id) - UIElement for full screen button (or nil) /// - note: private/undocumented attribute - public static let fullScreen = Attribute(rawValue: "AXFullScreen") //(NSNumber *) - (boolValue) is the window fullscreen + public static let fullScreen = Attribute(rawValue: "AXFullScreen") //(NSNumber *) - (boolValue) is the window fullscreen // Application-specific attributes - public static let menuBar = Attribute(rawValue: "AXMenuBar") //(id) - UIElement for the menu bar - public static let windows = Attribute(rawValue: "AXWindows") //(NSArray *) - UIElements for the windows - public static let frontmost = Attribute(rawValue: "AXFrontmost") //(NSNumber *) - (boolValue) is the app active? - public static let hidden = Attribute(rawValue: "AXHidden") //(NSNumber *) - (boolValue) is the app hidden? - public static let mainWindow = Attribute(rawValue: "AXMainWindow") //(id) - UIElement for the main window. - public static let focusedWindow = Attribute(rawValue: "AXFocusedWindow") //(id) - UIElement for the key window. - public static let focusedUIElement = Attribute(rawValue: "AXFocusedUIElement") //(id) - Currently focused UIElement. - public static let extrasMenuBar = Attribute(rawValue: "AXExtrasMenuBar") //(id) - UIElement for the application extras menu bar. + public static let menuBar = Attribute(rawValue: "AXMenuBar") //(id) - UIElement for the menu bar + public static let windows = Attribute(rawValue: "AXWindows") //(NSArray *) - UIElements for the windows + public static let frontmost = Attribute(rawValue: "AXFrontmost") //(NSNumber *) - (boolValue) is the app active? + public static let hidden = Attribute(rawValue: "AXHidden") //(NSNumber *) - (boolValue) is the app hidden? + public static let mainWindow = Attribute(rawValue: "AXMainWindow") //(id) - UIElement for the main window. + public static let focusedWindow = Attribute(rawValue: "AXFocusedWindow") //(id) - UIElement for the key window. + public static let focusedUIElement = Attribute(rawValue: "AXFocusedUIElement") //(id) - Currently focused UIElement. + public static let extrasMenuBar = Attribute(rawValue: "AXExtrasMenuBar") //(id) - UIElement for the application extras menu bar. /// - note: private/undocumented attribute - public static let enhancedUserInterface = Attribute(rawValue: "AXEnhancedUserInterface") //(NSNumber *) - (boolValue) is the enhanced user interface active? + public static let enhancedUserInterface = Attribute(rawValue: "AXEnhancedUserInterface") //(NSNumber *) - (boolValue) is the enhanced user interface active? - public static let orientation = Attribute(rawValue: "AXOrientation") //(NSString *) - NSAccessibilityXXXOrientationValue + public static let orientation = Attribute(rawValue: "AXOrientation") //(NSString *) - NSAccessibilityXXXOrientationValue - public static let columnTitles = Attribute(rawValue: "AXColumnTitles") //(NSArray *) - UIElements for titles + public static let columnTitles = Attribute(rawValue: "AXColumnTitles") //(NSArray *) - UIElements for titles - public static let searchButton = Attribute(rawValue: "AXSearchButton") //(id) - UIElement for search field search btn - public static let searchMenu = Attribute(rawValue: "AXSearchMenu") //(id) - UIElement for search field menu - public static let clearButton = Attribute(rawValue: "AXClearButton") //(id) - UIElement for search field clear btn + public static let searchButton = Attribute(rawValue: "AXSearchButton") //(id) - UIElement for search field search btn + public static let searchMenu = Attribute(rawValue: "AXSearchMenu") //(id) - UIElement for search field menu + public static let clearButton = Attribute(rawValue: "AXClearButton") //(id) - UIElement for search field clear btn // Table/outline view attributes - public static let rows = Attribute(rawValue: "AXRows") //(NSArray *) - UIElements for rows - public static let visibleRows = Attribute(rawValue: "AXVisibleRows") //(NSArray *) - UIElements for visible rows - public static let selectedRows = Attribute(rawValue: "AXSelectedRows") //(NSArray *) - UIElements for selected rows - public static let columns = Attribute(rawValue: "AXColumns") //(NSArray *) - UIElements for columns - public static let visibleColumns = Attribute(rawValue: "AXVisibleColumns") //(NSArray *) - UIElements for visible columns - public static let selectedColumns = Attribute(rawValue: "AXSelectedColumns") //(NSArray *) - UIElements for selected columns - public static let sortDirection = Attribute(rawValue: "AXSortDirection") //(NSString *) - see sort direction values below + public static let rows = Attribute(rawValue: "AXRows") //(NSArray *) - UIElements for rows + public static let visibleRows = Attribute(rawValue: "AXVisibleRows") //(NSArray *) - UIElements for visible rows + public static let selectedRows = Attribute(rawValue: "AXSelectedRows") //(NSArray *) - UIElements for selected rows + public static let columns = Attribute(rawValue: "AXColumns") //(NSArray *) - UIElements for columns + public static let visibleColumns = Attribute(rawValue: "AXVisibleColumns") //(NSArray *) - UIElements for visible columns + public static let selectedColumns = Attribute(rawValue: "AXSelectedColumns") //(NSArray *) - UIElements for selected columns + public static let sortDirection = Attribute(rawValue: "AXSortDirection") //(NSString *) - see sort direction values below // Cell-based table attributes - public static let selectedCells = Attribute(rawValue: "AXSelectedCells") //(NSArray *) - UIElements for selected cells - public static let visibleCells = Attribute(rawValue: "AXVisibleCells") //(NSArray *) - UIElements for visible cells - public static let rowHeaderUIElements = Attribute(rawValue: "AXRowHeaderUIElements") //(NSArray *) - UIElements for row headers - public static let columnHeaderUIElements = Attribute(rawValue: "AXColumnHeaderUIElements") //(NSArray *) - UIElements for column headers + public static let selectedCells = Attribute(rawValue: "AXSelectedCells") //(NSArray *) - UIElements for selected cells + public static let visibleCells = Attribute(rawValue: "AXVisibleCells") //(NSArray *) - UIElements for visible cells + public static let rowHeaderUIElements = Attribute(rawValue: "AXRowHeaderUIElements") //(NSArray *) - UIElements for row headers + public static let columnHeaderUIElements = Attribute(rawValue: "AXColumnHeaderUIElements") //(NSArray *) - UIElements for column headers // Cell-based table parameterized attributes. The parameter for this attribute is an NSArray containing two NSNumbers, the first NSNumber specifies the column index, the second NSNumber specifies the row index. - public static let cellForColumnAndRowParameterized = Attribute(rawValue: "AXCellForColumnAndRowParameterized") // (id) - UIElement for cell at specified row and column + public static let cellForColumnAndRowParameterized = Attribute(rawValue: "AXCellForColumnAndRowParameterized") // (id) - UIElement for cell at specified row and column // Cell attributes. The index range contains both the starting index, and the index span in a table. - public static let rowIndexRange = Attribute(rawValue: "AXRowIndexRange") //(NSValue *) - (rangeValue) location and row span - public static let columnIndexRange = Attribute(rawValue: "AXColumnIndexRange") //(NSValue *) - (rangeValue) location and column span + public static let rowIndexRange = Attribute(rawValue: "AXRowIndexRange") //(NSValue *) - (rangeValue) location and row span + public static let columnIndexRange = Attribute(rawValue: "AXColumnIndexRange") //(NSValue *) - (rangeValue) location and column span // Layout area attributes - public static let horizontalUnits = Attribute(rawValue: "AXHorizontalUnits") //(NSString *) - see ruler unit values below - public static let verticalUnits = Attribute(rawValue: "AXVerticalUnits") //(NSString *) - see ruler unit values below - public static let horizontalUnitDescription = Attribute(rawValue: "AXHorizontalUnitDescription") //(NSString *) - public static let verticalUnitDescription = Attribute(rawValue: "AXVerticalUnitDescription") //(NSString *) + public static let horizontalUnits = Attribute(rawValue: "AXHorizontalUnits") //(NSString *) - see ruler unit values below + public static let verticalUnits = Attribute(rawValue: "AXVerticalUnits") //(NSString *) - see ruler unit values below + public static let horizontalUnitDescription = Attribute(rawValue: "AXHorizontalUnitDescription") //(NSString *) + public static let verticalUnitDescription = Attribute(rawValue: "AXVerticalUnitDescription") //(NSString *) // Layout area parameterized attributes - public static let layoutPointForScreenPointParameterized = "Attribute(rawValue: AXLayoutPointForScreenPointParameterized" //)(NSValue *) - (pointValue); param:(NSValue * - pointValue) - public static let layoutSizeForScreenSizeParameterized = Attribute(rawValue: "AXLayoutSizeForScreenSizeParameterized") //(NSValue *) - (sizeValue); param:(NSValue * - sizeValue) - public static let screenPointForLayoutPointParameterized = "Attribute(rawValue: AXScreenPointForLayoutPointParameterized" //)(NSValue *) - (pointValue); param:(NSValue * - pointValue) - public static let screenSizeForLayoutSizeParameterized = Attribute(rawValue: "AXScreenSizeForLayoutSizeParameterized") //(NSValue *) - (sizeValue); param:(NSValue * - sizeValue) + public static let layoutPointForScreenPointParameterized = "Attribute(rawValue: AXLayoutPointForScreenPointParameterized" //)(NSValue *) - (pointValue); param:(NSValue * - pointValue) + public static let layoutSizeForScreenSizeParameterized = Attribute(rawValue: "AXLayoutSizeForScreenSizeParameterized") //(NSValue *) - (sizeValue); param:(NSValue * - sizeValue) + public static let screenPointForLayoutPointParameterized = "Attribute(rawValue: AXScreenPointForLayoutPointParameterized" //)(NSValue *) - (pointValue); param:(NSValue * - pointValue) + public static let screenSizeForLayoutSizeParameterized = Attribute(rawValue: "AXScreenSizeForLayoutSizeParameterized") //(NSValue *) - (sizeValue); param:(NSValue * - sizeValue) // Layout item attributes - public static let handles = Attribute(rawValue: "AXHandles") //(NSArray *) - UIElements for handles + public static let handles = Attribute(rawValue: "AXHandles") //(NSArray *) - UIElements for handles // Outline attributes - public static let disclosing = Attribute(rawValue: "AXDisclosing") //(NSNumber *) - (boolValue) is disclosing rows? - public static let disclosedRows = Attribute(rawValue: "AXDisclosedRows") //(NSArray *) - UIElements for disclosed rows - public static let disclosedByRow = Attribute(rawValue: "AXDisclosedByRow") //(id) - UIElement for disclosing row - public static let disclosureLevel = Attribute(rawValue: "AXDisclosureLevel") //(NSNumber *) - indentation level + public static let disclosing = Attribute(rawValue: "AXDisclosing") //(NSNumber *) - (boolValue) is disclosing rows? + public static let disclosedRows = Attribute(rawValue: "AXDisclosedRows") //(NSArray *) - UIElements for disclosed rows + public static let disclosedByRow = Attribute(rawValue: "AXDisclosedByRow") //(id) - UIElement for disclosing row + public static let disclosureLevel = Attribute(rawValue: "AXDisclosureLevel") //(NSNumber *) - indentation level // Slider attributes - public static let allowedValues = Attribute(rawValue: "AXAllowedValues") //(NSArray *) - array of allowed values - public static let labelUIElements = Attribute(rawValue: "AXLabelUIElements") //(NSArray *) - array of label UIElements - public static let labelValue = Attribute(rawValue: "AXLabelValue") //(NSNumber *) - value of a label UIElement + public static let allowedValues = Attribute(rawValue: "AXAllowedValues") //(NSArray *) - array of allowed values + public static let labelUIElements = Attribute(rawValue: "AXLabelUIElements") //(NSArray *) - array of label UIElements + public static let labelValue = Attribute(rawValue: "AXLabelValue") //(NSNumber *) - value of a label UIElement // Matte attributes // Attributes no longer supported - public static let matteHole = Attribute(rawValue: "AXMatteHole") //(NSValue *) - (rect value) bounds of matte hole in screen coords - public static let matteContentUIElement = Attribute(rawValue: "AXMatteContentUIElement") //(id) - UIElement clipped by the matte + public static let matteHole = Attribute(rawValue: "AXMatteHole") //(NSValue *) - (rect value) bounds of matte hole in screen coords + public static let matteContentUIElement = Attribute(rawValue: "AXMatteContentUIElement") //(id) - UIElement clipped by the matte // Ruler view attributes - public static let markerUIElements = Attribute(rawValue: "AXMarkerUIElements") //(NSArray *) - public static let markerValues = Attribute(rawValue: "AXMarkerValues") // - public static let markerGroupUIElement = Attribute(rawValue: "AXMarkerGroupUIElement") //(id) - public static let units = Attribute(rawValue: "AXUnits") //(NSString *) - see ruler unit values below - public static let unitDescription = Attribute(rawValue: "AXUnitDescription") //(NSString *) - public static let markerType = Attribute(rawValue: "AXMarkerType") //(NSString *) - see ruler marker type values below - public static let markerTypeDescription = Attribute(rawValue: "AXMarkerTypeDescription") //(NSString *) + public static let markerUIElements = Attribute(rawValue: "AXMarkerUIElements") //(NSArray *) + public static let markerValues = Attribute(rawValue: "AXMarkerValues") // + public static let markerGroupUIElement = Attribute(rawValue: "AXMarkerGroupUIElement") //(id) + public static let units = Attribute(rawValue: "AXUnits") //(NSString *) - see ruler unit values below + public static let unitDescription = Attribute(rawValue: "AXUnitDescription") //(NSString *) + public static let markerType = Attribute(rawValue: "AXMarkerType") //(NSString *) - see ruler marker type values below + public static let markerTypeDescription = Attribute(rawValue: "AXMarkerTypeDescription") //(NSString *) // UI element identification attributes - public static let identifier = Attribute(rawValue: "AXIdentifier") //(NSString *) + public static let identifier = Attribute(rawValue: "AXIdentifier") //(NSString *) // System-wide attributes - public static let focusedApplication = Attribute(rawValue: "AXFocusedApplication") + public static let focusedApplication = Attribute(rawValue: "AXFocusedApplication") // Unknown attributes - public static let functionRowTopLevelElements = Attribute(rawValue: "AXFunctionRowTopLevelElements") - public static let childrenInNavigationOrder = Attribute(rawValue: "AXChildrenInNavigationOrder") + public static let functionRowTopLevelElements = Attribute(rawValue: "AXFunctionRowTopLevelElements") + public static let childrenInNavigationOrder = Attribute(rawValue: "AXChildrenInNavigationOrder") } } From 124ef9b0ffc45b6e09320e52aaccfb5db98a39cf Mon Sep 17 00:00:00 2001 From: Michael Redig Date: Sun, 15 Jun 2025 03:27:37 -0500 Subject: [PATCH 39/39] (refactor) mutate a bunch of Attribute comments to docs --- Sources/Constants/Attribute.swift | 486 ++++++++++++++++++++---------- 1 file changed, 319 insertions(+), 167 deletions(-) diff --git a/Sources/Constants/Attribute.swift b/Sources/Constants/Attribute.swift index efa11ee..88f0483 100644 --- a/Sources/Constants/Attribute.swift +++ b/Sources/Constants/Attribute.swift @@ -12,219 +12,371 @@ extension UIElement { } // Standard attributes - public static let role = Attribute(rawValue: "AXRole") //(NSString *) - type, non-localized (e.g. radioButton) - public static let roleDescription = Attribute(rawValue: "AXRoleDescription") //(NSString *) - user readable role (e.g. "radio button") - public static let subrole = Attribute(rawValue: "AXSubrole") //(NSString *) - type, non-localized (e.g. closeButton) - public static let help = Attribute(rawValue: "AXHelp") //(NSString *) - instance description (e.g. a tool tip) - public static let value = Attribute(rawValue: "AXValue") //(id) - element's value - public static let minValue = Attribute(rawValue: "AXMinValue") //(id) - element's min value - public static let maxValue = Attribute(rawValue: "AXMaxValue") //(id) - element's max value - public static let enabled = Attribute(rawValue: "AXEnabled") //(NSNumber *) - (boolValue) responds to user? - public static let focused = Attribute(rawValue: "AXFocused") //(NSNumber *) - (boolValue) has keyboard focus? - public static let parent = Attribute(rawValue: "AXParent") //(id) - element containing you - public static let children = Attribute(rawValue: "AXChildren") //(NSArray *) - elements you contain - public static let window = Attribute(rawValue: "AXWindow") //(id) - UIElement for the containing window - public static let topLevelUIElement = Attribute(rawValue: "AXTopLevelUIElement") //(id) - UIElement for the containing top level element - public static let selectedChildren = Attribute(rawValue: "AXSelectedChildren") //(NSArray *) - child elements which are selected - public static let visibleChildren = Attribute(rawValue: "AXVisibleChildren") //(NSArray *) - child elements which are visible - public static let position = Attribute(rawValue: "AXPosition") //(NSValue *) - (pointValue) position in screen coords - public static let size = Attribute(rawValue: "AXSize") //(NSValue *) - (sizeValue) size - public static let frame = Attribute(rawValue: "AXFrame") //(NSValue *) - (rectValue) frame - public static let contents = Attribute(rawValue: "AXContents") //(NSArray *) - main elements - public static let title = Attribute(rawValue: "AXTitle") //(NSString *) - visible text (e.g. of a push button) - public static let description = Attribute(rawValue: "AXDescription") //(NSString *) - instance description - public static let shownMenu = Attribute(rawValue: "AXShownMenu") //(id) - menu being displayed - public static let valueDescription = Attribute(rawValue: "AXValueDescription") //(NSString *) - text description of value - - public static let sharedFocusElements = Attribute(rawValue: "AXSharedFocusElements") //(NSArray *) - elements that share focus + ///(NSString *) - type, non-localized (e.g. radioButton) + public static let role = Attribute(rawValue: "AXRole") + ///(NSString *) - user readable role (e.g. "radio button") + public static let roleDescription = Attribute(rawValue: "AXRoleDescription") + ///(NSString *) - type, non-localized (e.g. closeButton) + public static let subrole = Attribute(rawValue: "AXSubrole") + ///(NSString *) - instance description (e.g. a tool tip) + public static let help = Attribute(rawValue: "AXHelp") + ///(id) - element's value + public static let value = Attribute(rawValue: "AXValue") + ///(id) - element's min value + public static let minValue = Attribute(rawValue: "AXMinValue") + ///(id) - element's max value + public static let maxValue = Attribute(rawValue: "AXMaxValue") + ///(NSNumber *) - (boolValue) responds to user? + public static let enabled = Attribute(rawValue: "AXEnabled") + ///(NSNumber *) - (boolValue) has keyboard focus? + public static let focused = Attribute(rawValue: "AXFocused") + ///(id) - element containing you + public static let parent = Attribute(rawValue: "AXParent") + ///(NSArray *) - elements you contain + public static let children = Attribute(rawValue: "AXChildren") + ///(id) - UIElement for the containing window + public static let window = Attribute(rawValue: "AXWindow") + ///(id) - UIElement for the containing top level element + public static let topLevelUIElement = Attribute(rawValue: "AXTopLevelUIElement") + ///(NSArray *) - child elements which are selected + public static let selectedChildren = Attribute(rawValue: "AXSelectedChildren") + ///(NSArray *) - child elements which are visible + public static let visibleChildren = Attribute(rawValue: "AXVisibleChildren") + ///(NSValue *) - (pointValue) position in screen coords + public static let position = Attribute(rawValue: "AXPosition") + ///(NSValue *) - (sizeValue) size + public static let size = Attribute(rawValue: "AXSize") + ///(NSValue *) - (rectValue) frame + public static let frame = Attribute(rawValue: "AXFrame") + ///(NSArray *) - main elements + public static let contents = Attribute(rawValue: "AXContents") + ///(NSString *) - visible text (e.g. of a push button) + public static let title = Attribute(rawValue: "AXTitle") + ///(NSString *) - instance description + public static let description = Attribute(rawValue: "AXDescription") + ///(id) - menu being displayed + public static let shownMenu = Attribute(rawValue: "AXShownMenu") + ///(NSString *) - text description of value + public static let valueDescription = Attribute(rawValue: "AXValueDescription") + + ///(NSArray *) - elements that share focus + public static let sharedFocusElements = Attribute(rawValue: "AXSharedFocusElements") // Misc attributes - public static let previousContents = Attribute(rawValue: "AXPreviousContents") //(NSArray *) - main elements - public static let nextContents = Attribute(rawValue: "AXNextContents") //(NSArray *) - main elements - public static let header = Attribute(rawValue: "AXHeader") //(id) - UIElement for header. - public static let edited = Attribute(rawValue: "AXEdited") //(NSNumber *) - (boolValue) is it dirty? - public static let tabs = Attribute(rawValue: "AXTabs") //(NSArray *) - UIElements for tabs - public static let horizontalScrollBar = Attribute(rawValue: "AXHorizontalScrollBar") //(id) - UIElement for the horizontal scroller - public static let verticalScrollBar = Attribute(rawValue: "AXVerticalScrollBar") //(id) - UIElement for the vertical scroller - public static let overflowButton = Attribute(rawValue: "AXOverflowButton") //(id) - UIElement for overflow - public static let incrementButton = Attribute(rawValue: "AXIncrementButton") //(id) - UIElement for increment - public static let decrementButton = Attribute(rawValue: "AXDecrementButton") //(id) - UIElement for decrement - public static let filename = Attribute(rawValue: "AXFilename") //(NSString *) - filename - public static let expanded = Attribute(rawValue: "AXExpanded") //(NSNumber *) - (boolValue) is expanded? - public static let selected = Attribute(rawValue: "AXSelected") //(NSNumber *) - (boolValue) is selected? - public static let splitters = Attribute(rawValue: "AXSplitters") //(NSArray *) - UIElements for splitters - public static let document = Attribute(rawValue: "AXDocument") //(NSString *) - url as string - for open document - public static let activationPoint = Attribute(rawValue: "AXActivationPoint") //(NSValue *) - (pointValue) - - public static let url = Attribute(rawValue: "AXURL") //(NSURL *) - url - public static let index = Attribute(rawValue: "AXIndex") //(NSNumber *) - (intValue) - - public static let rowCount = Attribute(rawValue: "AXRowCount") //(NSNumber *) - (intValue) number of rows - - public static let columnCount = Attribute(rawValue: "AXColumnCount") //(NSNumber *) - (intValue) number of columns - - public static let orderedByRow = Attribute(rawValue: "AXOrderedByRow") //(NSNumber *) - (boolValue) is ordered by row? - - public static let warningValue = Attribute(rawValue: "AXWarningValue") //(id) - warning value of a level indicator, typically a number - - public static let criticalValue = Attribute(rawValue: "AXCriticalValue") //(id) - critical value of a level indicator, typically a number - - public static let placeholderValue = Attribute(rawValue: "AXPlaceholderValue") //(NSString *) - placeholder value of a control such as a text field - - public static let containsProtectedContent = Attribute(rawValue: "AXContainsProtectedContent") // (NSNumber *) - (boolValue) contains protected content? - public static let alternateUIVisible = Attribute(rawValue: "AXAlternateUIVisible") //(NSNumber *) - (boolValue) + ///(NSArray *) - main elements + public static let previousContents = Attribute(rawValue: "AXPreviousContents") + ///(NSArray *) - main elements + public static let nextContents = Attribute(rawValue: "AXNextContents") + ///(id) - UIElement for header. + public static let header = Attribute(rawValue: "AXHeader") + ///(NSNumber *) - (boolValue) is it dirty? + public static let edited = Attribute(rawValue: "AXEdited") + ///(NSArray *) - UIElements for tabs + public static let tabs = Attribute(rawValue: "AXTabs") + ///(id) - UIElement for the horizontal scroller + public static let horizontalScrollBar = Attribute(rawValue: "AXHorizontalScrollBar") + ///(id) - UIElement for the vertical scroller + public static let verticalScrollBar = Attribute(rawValue: "AXVerticalScrollBar") + ///(id) - UIElement for overflow + public static let overflowButton = Attribute(rawValue: "AXOverflowButton") + ///(id) - UIElement for increment + public static let incrementButton = Attribute(rawValue: "AXIncrementButton") + ///(id) - UIElement for decrement + public static let decrementButton = Attribute(rawValue: "AXDecrementButton") + ///(NSString *) - filename + public static let filename = Attribute(rawValue: "AXFilename") + ///(NSNumber *) - (boolValue) is expanded? + public static let expanded = Attribute(rawValue: "AXExpanded") + ///(NSNumber *) - (boolValue) is selected? + public static let selected = Attribute(rawValue: "AXSelected") + ///(NSArray *) - UIElements for splitters + public static let splitters = Attribute(rawValue: "AXSplitters") + ///(NSString *) - url as string - for open document + public static let document = Attribute(rawValue: "AXDocument") + ///(NSValue *) - (pointValue) + public static let activationPoint = Attribute(rawValue: "AXActivationPoint") + + ///(NSURL *) - url + public static let url = Attribute(rawValue: "AXURL") + ///(NSNumber *) - (intValue) + public static let index = Attribute(rawValue: "AXIndex") + + ///(NSNumber *) - (intValue) number of rows + public static let rowCount = Attribute(rawValue: "AXRowCount") + + ///(NSNumber *) - (intValue) number of columns + public static let columnCount = Attribute(rawValue: "AXColumnCount") + + ///(NSNumber *) - (boolValue) is ordered by row? + public static let orderedByRow = Attribute(rawValue: "AXOrderedByRow") + + ///(id) - warning value of a level indicator, typically a number + public static let warningValue = Attribute(rawValue: "AXWarningValue") + + ///(id) - critical value of a level indicator, typically a number + public static let criticalValue = Attribute(rawValue: "AXCriticalValue") + + ///(NSString *) - placeholder value of a control such as a text field + public static let placeholderValue = Attribute(rawValue: "AXPlaceholderValue") + + /// (NSNumber *) - (boolValue) contains protected content? + public static let containsProtectedContent = Attribute(rawValue: "AXContainsProtectedContent") + ///(NSNumber *) - (boolValue) + public static let alternateUIVisible = Attribute(rawValue: "AXAlternateUIVisible") // Linkage attributes - public static let titleUIElement = Attribute(rawValue: "AXTitleUIElement") //(id) - UIElement for the title - public static let servesAsTitleForUIElements = Attribute(rawValue: "AXServesAsTitleForUIElements") //(NSArray *) - UIElements this titles - public static let linkedUIElements = Attribute(rawValue: "AXLinkedUIElements") //(NSArray *) - corresponding UIElements + ///(id) - UIElement for the title + public static let titleUIElement = Attribute(rawValue: "AXTitleUIElement") + ///(NSArray *) - UIElements this titles + public static let servesAsTitleForUIElements = Attribute(rawValue: "AXServesAsTitleForUIElements") + ///(NSArray *) - corresponding UIElements + public static let linkedUIElements = Attribute(rawValue: "AXLinkedUIElements") // Text-specific attributes - public static let selectedText = Attribute(rawValue: "AXSelectedText") //(NSString *) - selected text - public static let selectedTextRange = Attribute(rawValue: "AXSelectedTextRange") //(NSValue *) - (rangeValue) range of selected text - public static let numberOfCharacters = Attribute(rawValue: "AXNumberOfCharacters") //(NSNumber *) - number of characters - public static let visibleCharacterRange = Attribute(rawValue: "AXVisibleCharacterRange") //(NSValue *) - (rangeValue) range of visible text - public static let sharedTextUIElements = Attribute(rawValue: "AXSharedTextUIElements") //(NSArray *) - text views sharing text - public static let sharedCharacterRange = Attribute(rawValue: "AXSharedCharacterRange") //(NSValue *) - (rangeValue) part of shared text in this view - public static let insertionPointLineNumber = Attribute(rawValue: "AXInsertionPointLineNumber") //(NSNumber *) - line# containing caret - public static let selectedTextRanges = Attribute(rawValue: "AXSelectedTextRanges") //(NSArray *) - array of NSValue (rangeValue) ranges of selected text - /// - note: private/undocumented attribute + ///(NSString *) - selected text + public static let selectedText = Attribute(rawValue: "AXSelectedText") + ///(NSValue *) - (rangeValue) range of selected text + public static let selectedTextRange = Attribute(rawValue: "AXSelectedTextRange") + ///(NSNumber *) - number of characters + public static let numberOfCharacters = Attribute(rawValue: "AXNumberOfCharacters") + ///(NSValue *) - (rangeValue) range of visible text + public static let visibleCharacterRange = Attribute(rawValue: "AXVisibleCharacterRange") + ///(NSArray *) - text views sharing text + public static let sharedTextUIElements = Attribute(rawValue: "AXSharedTextUIElements") + ///(NSValue *) - (rangeValue) part of shared text in this view + public static let sharedCharacterRange = Attribute(rawValue: "AXSharedCharacterRange") + ///(NSNumber *) - line# containing caret + public static let insertionPointLineNumber = Attribute(rawValue: "AXInsertionPointLineNumber") + ///(NSArray *) - array of NSValue (rangeValue) ranges of selected text + public static let selectedTextRanges = Attribute(rawValue: "AXSelectedTextRanges") + /// - note: private/undocumented attribute public static let textInputMarkedRange = Attribute(rawValue: "AXTextInputMarkedRange") // Parameterized text-specific attributes - public static let lineForIndexParameterized = Attribute(rawValue: "AXLineForIndexParameterized") //(NSNumber *) - line# for char index; param:(NSNumber *) - public static let rangeForLineParameterized = Attribute(rawValue: "AXRangeForLineParameterized") //(NSValue *) - (rangeValue) range of line; param:(NSNumber *) - public static let stringForRangeParameterized = Attribute(rawValue: "AXStringForRangeParameterized") //(NSString *) - substring; param:(NSValue * - rangeValue) - public static let rangeForPositionParameterized = Attribute(rawValue: "AXRangeForPositionParameterized") //(NSValue *) - (rangeValue) composed char range; param:(NSValue * - pointValue) - public static let rangeForIndexParameterized = Attribute(rawValue: "AXRangeForIndexParameterized") //(NSValue *) - (rangeValue) composed char range; param:(NSNumber *) - public static let boundsForRangeParameterized = Attribute(rawValue: "AXBoundsForRangeParameterized") //(NSValue *) - (rectValue) bounds of text; param:(NSValue * - rangeValue) - public static let rtfForRangeParameterized = Attribute(rawValue: "AXRTFForRangeParameterized") //(NSData *) - rtf for text; param:(NSValue * - rangeValue) - public static let styleRangeForIndexParameterized = Attribute(rawValue: "AXStyleRangeForIndexParameterized") //(NSValue *) - (rangeValue) extent of style run; param:(NSNumber *) - public static let attributedStringForRangeParameterized = Attribute(rawValue: "AXAttributedStringForRangeParameterized") //(NSAttributedString *) - does _not_ use attributes from Appkit/AttributedString.h + ///(NSNumber *) - line# for char index; param:(NSNumber *) + public static let lineForIndexParameterized = Attribute(rawValue: "AXLineForIndexParameterized") + ///(NSValue *) - (rangeValue) range of line; param:(NSNumber *) + public static let rangeForLineParameterized = Attribute(rawValue: "AXRangeForLineParameterized") + ///(NSString *) - substring; param:(NSValue * - rangeValue) + public static let stringForRangeParameterized = Attribute(rawValue: "AXStringForRangeParameterized") + ///(NSValue *) - (rangeValue) composed char range; param:(NSValue * - pointValue) + public static let rangeForPositionParameterized = Attribute(rawValue: "AXRangeForPositionParameterized") + ///(NSValue *) - (rangeValue) composed char range; param:(NSNumber *) + public static let rangeForIndexParameterized = Attribute(rawValue: "AXRangeForIndexParameterized") + ///(NSValue *) - (rectValue) bounds of text; param:(NSValue * - rangeValue) + public static let boundsForRangeParameterized = Attribute(rawValue: "AXBoundsForRangeParameterized") + ///(NSData *) - rtf for text; param:(NSValue * - rangeValue) + public static let rtfForRangeParameterized = Attribute(rawValue: "AXRTFForRangeParameterized") + ///(NSValue *) - (rangeValue) extent of style run; param:(NSNumber *) + public static let styleRangeForIndexParameterized = Attribute(rawValue: "AXStyleRangeForIndexParameterized") + ///(NSAttributedString *) - does _not_ use attributes from Appkit/AttributedString.h + public static let attributedStringForRangeParameterized = Attribute(rawValue: "AXAttributedStringForRangeParameterized") // Text attributed string attributes and constants - public static let fontText = Attribute(rawValue: "AXFontText") //(NSDictionary *) - NSAccessibilityFontXXXKey's - public static let foregroundColorText = Attribute(rawValue: "AXForegroundColorText") //CGColorRef - public static let backgroundColorText = Attribute(rawValue: "AXBackgroundColorText") //CGColorRef - public static let underlineColorText = Attribute(rawValue: "AXUnderlineColorText") //CGColorRef - public static let strikethroughColorText = Attribute(rawValue: "AXStrikethroughColorText") //CGColorRef - public static let underlineText = Attribute(rawValue: "AXUnderlineText") //(NSNumber *) - underline style - public static let superscriptText = Attribute(rawValue: "AXSuperscriptText") //(NSNumber *) - superscript>0, subscript<0 - public static let strikethroughText = Attribute(rawValue: "AXStrikethroughText") //(NSNumber *) - (boolValue) - public static let shadowText = Attribute(rawValue: "AXShadowText") //(NSNumber *) - (boolValue) - public static let attachmentText = Attribute(rawValue: "AXAttachmentText") //id - corresponding element - public static let linkText = Attribute(rawValue: "AXLinkText") //id - corresponding element - public static let autocorrectedText = Attribute(rawValue: "AXAutocorrectedText") //(NSNumber *) - (boolValue) + ///(NSDictionary *) - NSAccessibilityFontXXXKey's + public static let fontText = Attribute(rawValue: "AXFontText") + ///CGColorRef + public static let foregroundColorText = Attribute(rawValue: "AXForegroundColorText") + ///CGColorRef + public static let backgroundColorText = Attribute(rawValue: "AXBackgroundColorText") + ///CGColorRef + public static let underlineColorText = Attribute(rawValue: "AXUnderlineColorText") + ///CGColorRef + public static let strikethroughColorText = Attribute(rawValue: "AXStrikethroughColorText") + ///(NSNumber *) - underline style + public static let underlineText = Attribute(rawValue: "AXUnderlineText") + ///(NSNumber *) - superscript>0, subscript<0 + public static let superscriptText = Attribute(rawValue: "AXSuperscriptText") + ///(NSNumber *) - (boolValue) + public static let strikethroughText = Attribute(rawValue: "AXStrikethroughText") + ///(NSNumber *) - (boolValue) + public static let shadowText = Attribute(rawValue: "AXShadowText") + ///id - corresponding element + public static let attachmentText = Attribute(rawValue: "AXAttachmentText") + ///id - corresponding element + public static let linkText = Attribute(rawValue: "AXLinkText") + ///(NSNumber *) - (boolValue) + public static let autocorrectedText = Attribute(rawValue: "AXAutocorrectedText") // Textual list attributes and constants. Examples: unordered or ordered lists in a document. - public static let listItemPrefixText = Attribute(rawValue: "AXListItemPrefixText") // NSAttributedString, the prepended string of the list item. If the string is a common unicode character (e.g. a bullet •), return that unicode character. For lists with images before the text, return a reasonable label of the image. - public static let listItemIndexText = Attribute(rawValue: "AXListItemIndexText") // NSNumber, integerValue of the line index. Each list item increments the index, even for unordered lists. The first item should have index 0. - public static let listItemLevelText = Attribute(rawValue: "AXListItemLevelText") // NSNumber, integerValue of the indent level. Each sublist increments the level. The first item should have level 0. + /// NSAttributedString, the prepended string of the list item. If the string is a common unicode character (e.g. a bullet •), return that unicode character. For lists with images before the text, return a reasonable label of the image. + public static let listItemPrefixText = Attribute(rawValue: "AXListItemPrefixText") + /// NSNumber, integerValue of the line index. Each list item increments the index, even for unordered lists. The first item should have index 0. + public static let listItemIndexText = Attribute(rawValue: "AXListItemIndexText") + /// NSNumber, integerValue of the indent level. Each sublist increments the level. The first item should have level 0. + public static let listItemLevelText = Attribute(rawValue: "AXListItemLevelText") // MisspelledText attributes - public static let misspelledText = Attribute(rawValue: "AXMisspelledText") //(NSNumber *) - (boolValue) - public static let markedMisspelledText = Attribute(rawValue: "AXMarkedMisspelledText") //(NSNumber *) - (boolValue) + ///(NSNumber *) - (boolValue) + public static let misspelledText = Attribute(rawValue: "AXMisspelledText") + ///(NSNumber *) - (boolValue) + public static let markedMisspelledText = Attribute(rawValue: "AXMarkedMisspelledText") // Window-specific attributes - public static let main = Attribute(rawValue: "AXMain") //(NSNumber *) - (boolValue) is it the main window? - public static let minimized = Attribute(rawValue: "AXMinimized") //(NSNumber *) - (boolValue) is window minimized? - public static let closeButton = Attribute(rawValue: "AXCloseButton") //(id) - UIElement for close box (or nil) - public static let zoomButton = Attribute(rawValue: "AXZoomButton") //(id) - UIElement for zoom box (or nil) - public static let minimizeButton = Attribute(rawValue: "AXMinimizeButton") //(id) - UIElement for miniaturize box (or nil) - public static let toolbarButton = Attribute(rawValue: "AXToolbarButton") //(id) - UIElement for toolbar box (or nil) - public static let proxy = Attribute(rawValue: "AXProxy") //(id) - UIElement for title's icon (or nil) - public static let growArea = Attribute(rawValue: "AXGrowArea") //(id) - UIElement for grow box (or nil) - public static let modal = Attribute(rawValue: "AXModal") //(NSNumber *) - (boolValue) is the window modal - public static let defaultButton = Attribute(rawValue: "AXDefaultButton") //(id) - UIElement for default button - public static let cancelButton = Attribute(rawValue: "AXCancelButton") //(id) - UIElement for cancel button - public static let fullScreenButton = Attribute(rawValue: "AXFullScreenButton") //(id) - UIElement for full screen button (or nil) - /// - note: private/undocumented attribute - public static let fullScreen = Attribute(rawValue: "AXFullScreen") //(NSNumber *) - (boolValue) is the window fullscreen + ///(NSNumber *) - (boolValue) is it the main window? + public static let main = Attribute(rawValue: "AXMain") + ///(NSNumber *) - (boolValue) is window minimized? + public static let minimized = Attribute(rawValue: "AXMinimized") + ///(id) - UIElement for close box (or nil) + public static let closeButton = Attribute(rawValue: "AXCloseButton") + ///(id) - UIElement for zoom box (or nil) + public static let zoomButton = Attribute(rawValue: "AXZoomButton") + ///(id) - UIElement for miniaturize box (or nil) + public static let minimizeButton = Attribute(rawValue: "AXMinimizeButton") + ///(id) - UIElement for toolbar box (or nil) + public static let toolbarButton = Attribute(rawValue: "AXToolbarButton") + ///(id) - UIElement for title's icon (or nil) + public static let proxy = Attribute(rawValue: "AXProxy") + ///(id) - UIElement for grow box (or nil) + public static let growArea = Attribute(rawValue: "AXGrowArea") + ///(NSNumber *) - (boolValue) is the window modal + public static let modal = Attribute(rawValue: "AXModal") + ///(id) - UIElement for default button + public static let defaultButton = Attribute(rawValue: "AXDefaultButton") + ///(id) - UIElement for cancel button + public static let cancelButton = Attribute(rawValue: "AXCancelButton") + ///(id) - UIElement for full screen button (or nil) + public static let fullScreenButton = Attribute(rawValue: "AXFullScreenButton") + /// - note: private/undocumented attribute + ///(NSNumber *) - (boolValue) is the window fullscreen + public static let fullScreen = Attribute(rawValue: "AXFullScreen") // Application-specific attributes - public static let menuBar = Attribute(rawValue: "AXMenuBar") //(id) - UIElement for the menu bar - public static let windows = Attribute(rawValue: "AXWindows") //(NSArray *) - UIElements for the windows - public static let frontmost = Attribute(rawValue: "AXFrontmost") //(NSNumber *) - (boolValue) is the app active? - public static let hidden = Attribute(rawValue: "AXHidden") //(NSNumber *) - (boolValue) is the app hidden? - public static let mainWindow = Attribute(rawValue: "AXMainWindow") //(id) - UIElement for the main window. - public static let focusedWindow = Attribute(rawValue: "AXFocusedWindow") //(id) - UIElement for the key window. - public static let focusedUIElement = Attribute(rawValue: "AXFocusedUIElement") //(id) - Currently focused UIElement. - public static let extrasMenuBar = Attribute(rawValue: "AXExtrasMenuBar") //(id) - UIElement for the application extras menu bar. - /// - note: private/undocumented attribute - public static let enhancedUserInterface = Attribute(rawValue: "AXEnhancedUserInterface") //(NSNumber *) - (boolValue) is the enhanced user interface active? - - public static let orientation = Attribute(rawValue: "AXOrientation") //(NSString *) - NSAccessibilityXXXOrientationValue - - public static let columnTitles = Attribute(rawValue: "AXColumnTitles") //(NSArray *) - UIElements for titles - - public static let searchButton = Attribute(rawValue: "AXSearchButton") //(id) - UIElement for search field search btn - public static let searchMenu = Attribute(rawValue: "AXSearchMenu") //(id) - UIElement for search field menu - public static let clearButton = Attribute(rawValue: "AXClearButton") //(id) - UIElement for search field clear btn + ///(id) - UIElement for the menu bar + public static let menuBar = Attribute(rawValue: "AXMenuBar") + ///(NSArray *) - UIElements for the windows + public static let windows = Attribute(rawValue: "AXWindows") + ///(NSNumber *) - (boolValue) is the app active? + public static let frontmost = Attribute(rawValue: "AXFrontmost") + ///(NSNumber *) - (boolValue) is the app hidden? + public static let hidden = Attribute(rawValue: "AXHidden") + ///(id) - UIElement for the main window. + public static let mainWindow = Attribute(rawValue: "AXMainWindow") + ///(id) - UIElement for the key window. + public static let focusedWindow = Attribute(rawValue: "AXFocusedWindow") + ///(id) - Currently focused UIElement. + public static let focusedUIElement = Attribute(rawValue: "AXFocusedUIElement") + ///(id) - UIElement for the application extras menu bar. + public static let extrasMenuBar = Attribute(rawValue: "AXExtrasMenuBar") + /// - note: private/undocumented attribute + ///(NSNumber *) - (boolValue) is the enhanced user interface active? + public static let enhancedUserInterface = Attribute(rawValue: "AXEnhancedUserInterface") + + ///(NSString *) - NSAccessibilityXXXOrientationValue + public static let orientation = Attribute(rawValue: "AXOrientation") + + ///(NSArray *) - UIElements for titles + public static let columnTitles = Attribute(rawValue: "AXColumnTitles") + + ///(id) - UIElement for search field search btn + public static let searchButton = Attribute(rawValue: "AXSearchButton") + ///(id) - UIElement for search field menu + public static let searchMenu = Attribute(rawValue: "AXSearchMenu") + ///(id) - UIElement for search field clear btn + public static let clearButton = Attribute(rawValue: "AXClearButton") // Table/outline view attributes - public static let rows = Attribute(rawValue: "AXRows") //(NSArray *) - UIElements for rows - public static let visibleRows = Attribute(rawValue: "AXVisibleRows") //(NSArray *) - UIElements for visible rows - public static let selectedRows = Attribute(rawValue: "AXSelectedRows") //(NSArray *) - UIElements for selected rows - public static let columns = Attribute(rawValue: "AXColumns") //(NSArray *) - UIElements for columns - public static let visibleColumns = Attribute(rawValue: "AXVisibleColumns") //(NSArray *) - UIElements for visible columns - public static let selectedColumns = Attribute(rawValue: "AXSelectedColumns") //(NSArray *) - UIElements for selected columns - public static let sortDirection = Attribute(rawValue: "AXSortDirection") //(NSString *) - see sort direction values below + ///(NSArray *) - UIElements for rows + public static let rows = Attribute(rawValue: "AXRows") + ///(NSArray *) - UIElements for visible rows + public static let visibleRows = Attribute(rawValue: "AXVisibleRows") + ///(NSArray *) - UIElements for selected rows + public static let selectedRows = Attribute(rawValue: "AXSelectedRows") + ///(NSArray *) - UIElements for columns + public static let columns = Attribute(rawValue: "AXColumns") + ///(NSArray *) - UIElements for visible columns + public static let visibleColumns = Attribute(rawValue: "AXVisibleColumns") + ///(NSArray *) - UIElements for selected columns + public static let selectedColumns = Attribute(rawValue: "AXSelectedColumns") + ///(NSString *) - see sort direction values below + public static let sortDirection = Attribute(rawValue: "AXSortDirection") // Cell-based table attributes - public static let selectedCells = Attribute(rawValue: "AXSelectedCells") //(NSArray *) - UIElements for selected cells - public static let visibleCells = Attribute(rawValue: "AXVisibleCells") //(NSArray *) - UIElements for visible cells - public static let rowHeaderUIElements = Attribute(rawValue: "AXRowHeaderUIElements") //(NSArray *) - UIElements for row headers - public static let columnHeaderUIElements = Attribute(rawValue: "AXColumnHeaderUIElements") //(NSArray *) - UIElements for column headers + ///(NSArray *) - UIElements for selected cells + public static let selectedCells = Attribute(rawValue: "AXSelectedCells") + ///(NSArray *) - UIElements for visible cells + public static let visibleCells = Attribute(rawValue: "AXVisibleCells") + ///(NSArray *) - UIElements for row headers + public static let rowHeaderUIElements = Attribute(rawValue: "AXRowHeaderUIElements") + ///(NSArray *) - UIElements for column headers + public static let columnHeaderUIElements = Attribute(rawValue: "AXColumnHeaderUIElements") // Cell-based table parameterized attributes. The parameter for this attribute is an NSArray containing two NSNumbers, the first NSNumber specifies the column index, the second NSNumber specifies the row index. - public static let cellForColumnAndRowParameterized = Attribute(rawValue: "AXCellForColumnAndRowParameterized") // (id) - UIElement for cell at specified row and column + /// (id) - UIElement for cell at specified row and column + public static let cellForColumnAndRowParameterized = Attribute(rawValue: "AXCellForColumnAndRowParameterized") // Cell attributes. The index range contains both the starting index, and the index span in a table. - public static let rowIndexRange = Attribute(rawValue: "AXRowIndexRange") //(NSValue *) - (rangeValue) location and row span - public static let columnIndexRange = Attribute(rawValue: "AXColumnIndexRange") //(NSValue *) - (rangeValue) location and column span + ///(NSValue *) - (rangeValue) location and row span + public static let rowIndexRange = Attribute(rawValue: "AXRowIndexRange") + ///(NSValue *) - (rangeValue) location and column span + public static let columnIndexRange = Attribute(rawValue: "AXColumnIndexRange") // Layout area attributes - public static let horizontalUnits = Attribute(rawValue: "AXHorizontalUnits") //(NSString *) - see ruler unit values below - public static let verticalUnits = Attribute(rawValue: "AXVerticalUnits") //(NSString *) - see ruler unit values below - public static let horizontalUnitDescription = Attribute(rawValue: "AXHorizontalUnitDescription") //(NSString *) - public static let verticalUnitDescription = Attribute(rawValue: "AXVerticalUnitDescription") //(NSString *) + ///(NSString *) - see ruler unit values below + public static let horizontalUnits = Attribute(rawValue: "AXHorizontalUnits") + ///(NSString *) - see ruler unit values below + public static let verticalUnits = Attribute(rawValue: "AXVerticalUnits") + ///(NSString *) + public static let horizontalUnitDescription = Attribute(rawValue: "AXHorizontalUnitDescription") + ///(NSString *) + public static let verticalUnitDescription = Attribute(rawValue: "AXVerticalUnitDescription") // Layout area parameterized attributes public static let layoutPointForScreenPointParameterized = "Attribute(rawValue: AXLayoutPointForScreenPointParameterized" //)(NSValue *) - (pointValue); param:(NSValue * - pointValue) - public static let layoutSizeForScreenSizeParameterized = Attribute(rawValue: "AXLayoutSizeForScreenSizeParameterized") //(NSValue *) - (sizeValue); param:(NSValue * - sizeValue) + ///(NSValue *) - (sizeValue); param:(NSValue * - sizeValue) + public static let layoutSizeForScreenSizeParameterized = Attribute(rawValue: "AXLayoutSizeForScreenSizeParameterized") public static let screenPointForLayoutPointParameterized = "Attribute(rawValue: AXScreenPointForLayoutPointParameterized" //)(NSValue *) - (pointValue); param:(NSValue * - pointValue) - public static let screenSizeForLayoutSizeParameterized = Attribute(rawValue: "AXScreenSizeForLayoutSizeParameterized") //(NSValue *) - (sizeValue); param:(NSValue * - sizeValue) + ///(NSValue *) - (sizeValue); param:(NSValue * - sizeValue) + public static let screenSizeForLayoutSizeParameterized = Attribute(rawValue: "AXScreenSizeForLayoutSizeParameterized") // Layout item attributes - public static let handles = Attribute(rawValue: "AXHandles") //(NSArray *) - UIElements for handles + ///(NSArray *) - UIElements for handles + public static let handles = Attribute(rawValue: "AXHandles") // Outline attributes - public static let disclosing = Attribute(rawValue: "AXDisclosing") //(NSNumber *) - (boolValue) is disclosing rows? - public static let disclosedRows = Attribute(rawValue: "AXDisclosedRows") //(NSArray *) - UIElements for disclosed rows - public static let disclosedByRow = Attribute(rawValue: "AXDisclosedByRow") //(id) - UIElement for disclosing row - public static let disclosureLevel = Attribute(rawValue: "AXDisclosureLevel") //(NSNumber *) - indentation level + ///(NSNumber *) - (boolValue) is disclosing rows? + public static let disclosing = Attribute(rawValue: "AXDisclosing") + ///(NSArray *) - UIElements for disclosed rows + public static let disclosedRows = Attribute(rawValue: "AXDisclosedRows") + ///(id) - UIElement for disclosing row + public static let disclosedByRow = Attribute(rawValue: "AXDisclosedByRow") + ///(NSNumber *) - indentation level + public static let disclosureLevel = Attribute(rawValue: "AXDisclosureLevel") // Slider attributes - public static let allowedValues = Attribute(rawValue: "AXAllowedValues") //(NSArray *) - array of allowed values - public static let labelUIElements = Attribute(rawValue: "AXLabelUIElements") //(NSArray *) - array of label UIElements - public static let labelValue = Attribute(rawValue: "AXLabelValue") //(NSNumber *) - value of a label UIElement + ///(NSArray *) - array of allowed values + public static let allowedValues = Attribute(rawValue: "AXAllowedValues") + ///(NSArray *) - array of label UIElements + public static let labelUIElements = Attribute(rawValue: "AXLabelUIElements") + ///(NSNumber *) - value of a label UIElement + public static let labelValue = Attribute(rawValue: "AXLabelValue") // Matte attributes // Attributes no longer supported - public static let matteHole = Attribute(rawValue: "AXMatteHole") //(NSValue *) - (rect value) bounds of matte hole in screen coords - public static let matteContentUIElement = Attribute(rawValue: "AXMatteContentUIElement") //(id) - UIElement clipped by the matte + ///(NSValue *) - (rect value) bounds of matte hole in screen coords + public static let matteHole = Attribute(rawValue: "AXMatteHole") + ///(id) - UIElement clipped by the matte + public static let matteContentUIElement = Attribute(rawValue: "AXMatteContentUIElement") // Ruler view attributes - public static let markerUIElements = Attribute(rawValue: "AXMarkerUIElements") //(NSArray *) - public static let markerValues = Attribute(rawValue: "AXMarkerValues") // - public static let markerGroupUIElement = Attribute(rawValue: "AXMarkerGroupUIElement") //(id) - public static let units = Attribute(rawValue: "AXUnits") //(NSString *) - see ruler unit values below - public static let unitDescription = Attribute(rawValue: "AXUnitDescription") //(NSString *) - public static let markerType = Attribute(rawValue: "AXMarkerType") //(NSString *) - see ruler marker type values below - public static let markerTypeDescription = Attribute(rawValue: "AXMarkerTypeDescription") //(NSString *) + ///(NSArray *) + public static let markerUIElements = Attribute(rawValue: "AXMarkerUIElements") + /// + public static let markerValues = Attribute(rawValue: "AXMarkerValues") + ///(id) + public static let markerGroupUIElement = Attribute(rawValue: "AXMarkerGroupUIElement") + ///(NSString *) - see ruler unit values below + public static let units = Attribute(rawValue: "AXUnits") + ///(NSString *) + public static let unitDescription = Attribute(rawValue: "AXUnitDescription") + ///(NSString *) - see ruler marker type values below + public static let markerType = Attribute(rawValue: "AXMarkerType") + ///(NSString *) + public static let markerTypeDescription = Attribute(rawValue: "AXMarkerTypeDescription") // UI element identification attributes - public static let identifier = Attribute(rawValue: "AXIdentifier") //(NSString *) + ///(NSString *) + public static let identifier = Attribute(rawValue: "AXIdentifier") // System-wide attributes public static let focusedApplication = Attribute(rawValue: "AXFocusedApplication")