Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
GanZhiXiong opened this issue Jul 1, 2023 · 0 comments

Comments

@GanZhiXiong
Copy link

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)
  }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant