Skip to content

How to monitor the size and position changes of an AXUIElement in the window? #42

@GanZhiXiong

Description

@GanZhiXiong

For example, I want to monitor the size and position of the text box of the TextEdit window:

  1. Open the TextEdit app.
  2. Press Command + N to create a new text editing window.
  3. Press Command + Shift + . to enlarge the text box.
  4. The size of the text box is enlarged, but the change of the size and position of the text cannot be monitored through .moved and .resized.

my code is invalid:

  var observer: Observer!

   public func applicationDidFinishLaunching(_ aNotification: Notification) {
//    let app = Application.allForBundleID("com.apple.finder").first!
    let app = Application.allForBundleID("com.apple.TextEdit").first!

    do {
      try startWatcher(app)
    } catch let error {
      NSLog("Error: Could not watch app [\(app)]: \(error)")
      abort()
    }
  }

  func startWatcher(_ app: AXSwift.Application) throws {
    var updated = false
    observer = app.createObserver { (observer: Observer, element: UIElement, event: AXNotification, info: [String: AnyObject]?) in
      var elementDesc: String!
      if let role = try? element.role()!, role == .window {
        elementDesc = "\(element) \"\(try! (element.attribute(.title) as String?)!)\""
      } else {
        elementDesc = "\(element)"
      }
      print("\(event) on \(String(describing: elementDesc)); info: \(info ?? [:])")

      // Watch events on new windows
      if event == .windowCreated {
        do {
          try observer.addNotification(.uiElementDestroyed, forElement: element)
          try observer.addNotification(.moved, forElement: element)
          try observer.addNotification(.resized, forElement: element)
          try observer.addNotification(.created, forElement: element)
        } catch let error {
          NSLog("Error: Could not watch [\(element)]: \(error)")
        }
      }
      if event == .created || event == .focusedUIElementChanged {
        do {
          try observer.addNotification(.moved, forElement: element)
          try observer.addNotification(.resized, forElement: element)
        } catch let error {
          NSLog("Error: Could not watch [\(element)]: \(error)")
        }
      }

      // Group simultaneous events together with --- lines
      if !updated {
        updated = true
        // Set this code to run after the current run loop, which is dispatching all notifications.
        DispatchQueue.main.async {
          print("---")
          updated = false
        }
      }
    }

    try observer.addNotification(.windowCreated, forElement: app)
    try observer.addNotification(.mainWindowChanged, forElement: app)
    try observer.addNotification(.created, forElement: app)
    try observer.addNotification(.focusedUIElementChanged, forElement: app)
  }

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions