Skip to content

feat(cua-driver-rs)(macos): expose get_window_state element bounds - #1820

Closed
cyq1017 wants to merge 2 commits into
trycua:mainfrom
cyq1017:codex/cua-1564-elements
Closed

feat(cua-driver-rs)(macos): expose get_window_state element bounds#1820
cyq1017 wants to merge 2 commits into
trycua:mainfrom
cyq1017:codex/cua-1564-elements

Conversation

@cyq1017

@cyq1017 cyq1017 commented Jun 3, 2026

Copy link
Copy Markdown

Refs #1564

Summary

  • carry AX screen rects for actionable macOS tree nodes
  • emit structured get_window_state.elements[] bounds in window-local screenshot pixels
  • keep tree_markdown unchanged and skip nodes without a stable element_index or geometry

Verification

  • DYLD_FALLBACK_LIBRARY_PATH=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift-5.5/macosx cargo test -p platform-macos --lib get_window_state::tests::build_structured_elements -- --nocapture
  • DYLD_FALLBACK_LIBRARY_PATH=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift-5.5/macosx cargo test -p platform-macos --lib -- --nocapture
  • DYLD_FALLBACK_LIBRARY_PATH=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift-5.5/macosx cargo check -p platform-macos
  • rustfmt --edition 2021 --check crates/platform-macos/src/ax/cache.rs crates/platform-macos/src/ax/tree.rs crates/platform-macos/src/tools/get_window_state.rs
  • git diff --check

Summary by CodeRabbit

  • New Features

    • Added screen rectangle tracking for UI elements, providing on-screen position information.
    • Enhanced window state tool to include structured element geometry data with pixel coordinates in response output.
  • Tests

    • Added tests for coordinate conversion and element geometry handling.

@vercel

vercel Bot commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

@cyq1017 is attempting to deploy a commit to the Cua Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai

coderabbitai Bot commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: a6562f4f-c9ef-4ffd-9abc-3a42a862a416

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR adds on-screen rectangle tracking to AX elements across the macOS accessibility layer. The AXNode struct gains a screen_rect field; the tree walker computes and populates it during traversal; and the window state tool exposes these coordinates in screenshot-local pixel space via a new structured elements helper.

Changes

Screen Rectangle Tracking Pipeline

Layer / File(s) Summary
AXNode structure with screen_rect field
libs/cua-driver/rust/crates/platform-macos/src/ax/tree.rs
Adds public screen_rect: Option<[f64; 4]> field to cache element on-screen rectangles.
AX tree walker screen rectangle computation
libs/cua-driver/rust/crates/platform-macos/src/ax/tree.rs
Tree walker now computes screen_rect for all created AXNode instances via element_screen_rect() during DFS traversal; refactors window filtering, recursion control flow, and return formatting.
Cache layer and test infrastructure
libs/cua-driver/rust/crates/platform-macos/src/ax/cache.rs
Updates ElementCache::new(), ElementCache::update(), and test helper node_with_ptr to initialize screen_rect field; reformats retain-count assertions in concurrent snapshot test.
Structured elements helper and window state integration
libs/cua-driver/rust/crates/platform-macos/src/tools/get_window_state.rs
Adds build_structured_elements helper to scale AXNode screen rectangles into screenshot-local coordinates; integrates into GetWindowStateTool invoke path to output elements array when both AX tree and screenshot dimensions are available; includes unit tests for coordinate scaling, node filtering, and boundary handling.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 The tree now remembers where each element lives,
From window bounds to pixels, the coordinates give.
Screen rects are scaled and packaged with care,
A screenshot-local map of UI everywhere! ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat(cua-driver-rs)(macos): expose get_window_state element bounds' clearly and specifically describes the main change: exposing element bounds in the get_window_state tool for macOS, which aligns with the PR's primary objective of emitting structured element bounds.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@cyq1017
cyq1017 marked this pull request as ready for review June 3, 2026 16:59

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@libs/cua-driver/rust/crates/platform-macos/src/tools/get_window_state.rs`:
- Around line 77-90: The node serialization in get_window_state (the
nodes.iter() filter_map using node.screen_rect, bounds, scale_x, scale_y) must
skip nodes that do not intersect the captured window and clip those that
partially overlap: compute the intersection between node.screen_rect
[x,y,width,height] and bounds, skip if intersection width or height <= 0,
otherwise use the intersection rect (left = max(x,bounds.x), top =
max(y,bounds.y), inter_w = min(x+width, bounds.x+bounds.width)-left, inter_h =
min(y+height, bounds.y+bounds.height)-top) and then convert to window-local
pixels using ((left - bounds.x) * scale_x).round() etc for x/y and (inter_w *
scale_x).round() etc for width/height before serializing; update the filter_map
around node.element_index and node.screen_rect accordingly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 455a218a-553d-45a6-8f9e-42b259ea1766

📥 Commits

Reviewing files that changed from the base of the PR and between 02fdd98 and d1e98cc.

📒 Files selected for processing (3)
  • libs/cua-driver/rust/crates/platform-macos/src/ax/cache.rs
  • libs/cua-driver/rust/crates/platform-macos/src/ax/tree.rs
  • libs/cua-driver/rust/crates/platform-macos/src/tools/get_window_state.rs

Comment on lines +77 to +90
nodes
.iter()
.filter_map(|node| {
let idx = node.element_index?;
let [x, y, width, height] = node.screen_rect?;
Some(serde_json::json!({
"element_index": idx,
"x": ((x - bounds.x) * scale_x).round() as i64,
"y": ((y - bounds.y) * scale_y).round() as i64,
"width": (width * scale_x).round() as i64,
"height": (height * scale_y).round() as i64,
}))
})
.collect()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Skip or clip nodes that fall outside the captured window.

walk_tree still includes non-window children when window_id is set (libs/cua-driver/rust/crates/platform-macos/src/ax/tree.rs Lines 147-160), so not every actionable AXNode belongs to the screenshot. This helper currently serializes those nodes anyway, which can produce negative/off-image elements[] coordinates and violate the “window-local screenshot pixels” contract. Filter to rects that intersect the window bounds and clip partial overlaps before scaling.

Suggested fix
 fn build_structured_elements(
     nodes: &[AXNode],
     bounds: &WindowBounds,
     screenshot_width: u32,
     screenshot_height: u32,
 ) -> Vec<Value> {
     if bounds.width <= 0.0 || bounds.height <= 0.0 {
         return Vec::new();
     }

     let scale_x = screenshot_width as f64 / bounds.width;
     let scale_y = screenshot_height as f64 / bounds.height;
+    let window_left = bounds.x;
+    let window_top = bounds.y;
+    let window_right = bounds.x + bounds.width;
+    let window_bottom = bounds.y + bounds.height;

     nodes
         .iter()
         .filter_map(|node| {
             let idx = node.element_index?;
             let [x, y, width, height] = node.screen_rect?;
+            let left = x.max(window_left);
+            let top = y.max(window_top);
+            let right = (x + width).min(window_right);
+            let bottom = (y + height).min(window_bottom);
+
+            if right <= left || bottom <= top {
+                return None;
+            }
+
             Some(serde_json::json!({
                 "element_index": idx,
-                "x": ((x - bounds.x) * scale_x).round() as i64,
-                "y": ((y - bounds.y) * scale_y).round() as i64,
-                "width": (width * scale_x).round() as i64,
-                "height": (height * scale_y).round() as i64,
+                "x": ((left - window_left) * scale_x).round() as i64,
+                "y": ((top - window_top) * scale_y).round() as i64,
+                "width": ((right - left) * scale_x).round() as i64,
+                "height": ((bottom - top) * scale_y).round() as i64,
             }))
         })
         .collect()
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@libs/cua-driver/rust/crates/platform-macos/src/tools/get_window_state.rs`
around lines 77 - 90, The node serialization in get_window_state (the
nodes.iter() filter_map using node.screen_rect, bounds, scale_x, scale_y) must
skip nodes that do not intersect the captured window and clip those that
partially overlap: compute the intersection between node.screen_rect
[x,y,width,height] and bounds, skip if intersection width or height <= 0,
otherwise use the intersection rect (left = max(x,bounds.x), top =
max(y,bounds.y), inter_w = min(x+width, bounds.x+bounds.width)-left, inter_h =
min(y+height, bounds.y+bounds.height)-top) and then convert to window-local
pixels using ((left - bounds.x) * scale_x).round() etc for x/y and (inter_w *
scale_x).round() etc for width/height before serializing; update the filter_map
around node.element_index and node.screen_rect accordingly.

@injaneity

Copy link
Copy Markdown
Collaborator

closing as superseded by #1961

@injaneity injaneity closed this Aug 10, 2026
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

Successfully merging this pull request may close these issues.

2 participants