Skip to content

fix(cua-driver/windows): glide session cursor for scroll#2103

Open
outdog-hwh wants to merge 1 commit into
trycua:mainfrom
outdog-hwh:fix/windows-scroll-session-cursor
Open

fix(cua-driver/windows): glide session cursor for scroll#2103
outdog-hwh wants to merge 1 commit into
trycua:mainfrom
outdog-hwh:fix/windows-scroll-session-cursor

Conversation

@outdog-hwh

@outdog-hwh outdog-hwh commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Summary

  • wire Windows scroll through the session cursor overlay for both desktop x,y wheel injection and pid/window-targeted scrolls
  • reuse a small window_screen_center helper so overlay targeting and foreground wheel targeting resolve the same center point
  • add regression coverage for the helper that resolves the scroll target window center

Testing

  • cargo test -p platform-windows window_screen_center_tests -- --nocapture
  • cargo test -p platform-windows

Closes #2080.

Summary by CodeRabbit

  • New Features
    • Scroll actions now include smoother cursor movement and a visual click pulse at the target location.
    • Desktop-level scrolls can now animate the cursor directly to the chosen screen point.
  • Bug Fixes
    • Improved cursor positioning for scroll actions within app windows, making the visual feedback more consistent.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@vercel

vercel Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

@outdog-hwh 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 Jul 3, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Adds a window_screen_center helper to Windows platform tools and wires cursor-visualization (glide + ClickPulse overlay) into ScrollTool::invoke for both the windowless screen-absolute scroll path and the window-scoped scroll path, plus unit tests for the helper.

Changes

Windows Scroll Cursor Visualization

Layer / File(s) Summary
Window center helper and tests
libs/cua-driver/rust/crates/platform-windows/src/tools/impl_.rs
Adds window_screen_center helper computing a window's screen center from a WindowInfo list, with unit tests for matching and missing hwnd.
Scroll cursor glide wiring
libs/cua-driver/rust/crates/platform-windows/src/tools/impl_.rs
Resolves cursor_key early in ScrollTool::invoke and uses it with window_screen_center to glide the agent cursor and emit ClickPulse overlays for both the windowless and window-scoped scroll paths, alongside existing wheel synthesis.

Estimated code review effort: 2 (Simple) | ~10 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Agent
  participant ScrollTool
  participant windowscreencenter as window_screen_center
  participant Overlay

  Agent->>ScrollTool: invoke(scroll params)
  ScrollTool->>ScrollTool: resolve cursor_key
  alt windowless desktop scroll (x,y)
    ScrollTool->>Overlay: glide cursor to (sx, sy)
    ScrollTool->>Overlay: emit ClickPulse at (sx, sy)
  else window-scoped scroll (pid/window_id)
    ScrollTool->>windowscreencenter: compute center for hwnd
    windowscreencenter-->>ScrollTool: Some((x, y)) or None
    ScrollTool->>Overlay: pin to hwnd, glide to center
    ScrollTool->>Overlay: emit ClickPulse at center
  end
  ScrollTool->>ScrollTool: synthesize wheel event
Loading

Possibly related PRs

  • trycua/cua#1801: Introduced resolve_cursor_key and per-session cursor overlay glide/ClickPulse threading in the same platform-windows/src/tools/impl_.rs file that this PR extends to scroll.

Poem

A rabbit scrolls, its cursor now aglow,
Gliding to the center, pulse aflow,
No more schema-only, silent session key,
Now every scroll dance, the eye can see,
Hop, click, pulse — thump-thump! 🐇✨

🚥 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 clearly matches the main change: adding cursor glide behavior to Windows scroll.
Linked Issues check ✅ Passed The changes implement the requested Windows scroll session-cursor glide and overlay pulse behavior described in #2080.
Out of Scope Changes check ✅ Passed The helper, cursor wiring, and regression tests all appear directly related to the scroll-cursor fix.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ 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.

@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.

🧹 Nitpick comments (1)
libs/cua-driver/rust/crates/platform-windows/src/tools/impl_.rs (1)

4147-4169: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Redundant window enumeration for center resolution.

When hwnd_opt is None, list_windows(Some(pid)) is already fetched at Line 4150 to pick the first window. Then Line 4158-4160 unconditionally spawns a second blocking task that re-enumerates windows (EnumWindows + UIA per win32::windows::list_windows) just to compute the center — doubling window-enumeration cost on that path.

Worse, this second enumeration (and its spawn_blocking overhead) runs unconditionally for every scroll call — even for the default PostMessage (WM_VSCROLL/HSCROLL) delivery path where center is never read, and even when the overlay/session cursor is disabled (cursor_key == NO_CURSOR). spawn_blocking occupies a thread from the runtime's dedicated blocking pool for the call duration, so doing this unconditionally on a plausibly hot input path (scroll) adds avoidable overhead.

Consider computing the window list once, reusing it both for hwnd auto-resolution and center lookup, and deferring/skipping the center computation when it isn't needed (overlay disabled and delivery != Foreground).

♻️ Sketch: reuse a single window list fetch
-        let hwnd = match hwnd_opt {
-            Some(h) => h,
-            None => {
-                let windows = tokio::task::spawn_blocking(move || crate::win32::list_windows(Some(pid))).await.unwrap_or_default();
-                match windows.first() {
-                    Some(w) => w.hwnd,
-                    None => return ToolResult::error(format!("No windows found for pid {pid}. Provide window_id.")),
-                }
-            }
-        };
-
-        let center = tokio::task::spawn_blocking(move || {
-            window_screen_center(&crate::win32::list_windows(Some(pid)), hwnd)
-        }).await.ok().flatten();
+        let (hwnd, windows) = match hwnd_opt {
+            Some(h) => (h, tokio::task::spawn_blocking(move || crate::win32::list_windows(Some(pid))).await.unwrap_or_default()),
+            None => {
+                let windows = tokio::task::spawn_blocking(move || crate::win32::list_windows(Some(pid))).await.unwrap_or_default();
+                match windows.first() {
+                    Some(w) => { let h = w.hwnd; (h, windows) }
+                    None => return ToolResult::error(format!("No windows found for pid {pid}. Provide window_id.")),
+                }
+            }
+        };
+        let center = window_screen_center(&windows, hwnd);

Also applies to: 4199-4206

🤖 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-windows/src/tools/impl_.rs` around lines
4147 - 4169, The scroll path is redundantly enumerating windows and spawning
blocking work even when the center is unused. In the logic that resolves hwnd
and computes center, reuse the same window list fetched via
crate::win32::list_windows(Some(pid)) for both hwnd auto-selection and
window_screen_center instead of calling it again inside the second
tokio::task::spawn_blocking. Also gate the center/overlay work so it only runs
when needed (for example when cursor_key is not NO_CURSOR and the delivery path
actually uses the overlay), keeping pin_overlay_above and overlay_glide_to off
the hot default PostMessage path.
🤖 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.

Nitpick comments:
In `@libs/cua-driver/rust/crates/platform-windows/src/tools/impl_.rs`:
- Around line 4147-4169: The scroll path is redundantly enumerating windows and
spawning blocking work even when the center is unused. In the logic that
resolves hwnd and computes center, reuse the same window list fetched via
crate::win32::list_windows(Some(pid)) for both hwnd auto-selection and
window_screen_center instead of calling it again inside the second
tokio::task::spawn_blocking. Also gate the center/overlay work so it only runs
when needed (for example when cursor_key is not NO_CURSOR and the delivery path
actually uses the overlay), keeping pin_overlay_above and overlay_glide_to off
the hot default PostMessage path.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: af69f71e-cd46-41a6-9923-ccd9494631ae

📥 Commits

Reviewing files that changed from the base of the PR and between 73fe822 and d457581.

📒 Files selected for processing (1)
  • libs/cua-driver/rust/crates/platform-windows/src/tools/impl_.rs

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.

cua-driver: wire session cursor glide on Windows scroll (schema-accepted but not glided)

1 participant