Skip to content

fix(cua-driver-rs)(windows): overlay stops escaping into topmost band, foreground app renders above pin - #1688

Merged
f-trycua merged 1 commit into
mainfrom
overlay-z-order-not-topmost
May 24, 2026
Merged

fix(cua-driver-rs)(windows): overlay stops escaping into topmost band, foreground app renders above pin#1688
f-trycua merged 1 commit into
mainfrom
overlay-z-order-not-topmost

Conversation

@f-trycua

@f-trycua f-trycua commented May 24, 2026

Copy link
Copy Markdown
Collaborator

Summary

User report: agent cursor overlay pinned over Calculator. User brings their terminal in front of the Calculator. Overlay renders on top of the terminal too — should be above the Calculator (pinned target) but below the terminal (user's foreground).

Root cause

`reapply_z_order` used `HWND_TOPMOST` as a fallback when no pin was live:

```rust
let insert_after = if let Some(wid) = pinned_wid {
let target = HWND(wid as *mut _);
if IsWindow(target).as_bool() { target } else { HWND_TOPMOST }
} else {
HWND_TOPMOST // ← bug
};
SetWindowPos(overlay, insert_after, ...);
```

Once Windows promotes a window into the topmost band via `SetWindowPos(HWND_TOPMOST)`, `WS_EX_TOPMOST` gets set on the window. A later `SetWindowPos(overlay, target_hwnd, …)` with a normal target does not drop the overlay back out of the topmost band — it stays above every non-topmost window, including the user's foreground app.

This happens whenever no pin is live: at startup, between `PinAbove` commands, briefly when the pinned window is destroyed and recreated. Once it happens, the overlay is topmost-forever.

Fix — two-call shape

```rust
// 1. Drop out of topmost band (idempotent if already non-topmost).
SetWindowPos(overlay, HWND_NOTOPMOST, …);
// 2. Position relative to the live target (or HWND_TOP if no pin).
SetWindowPos(overlay, pinned_or_HWND_TOP, …);
```

Why two calls: `HWND_NOTOPMOST` is a band-transition pseudo-value (-2) that doesn't represent a positioning target. The second call positions relative to the actual pin (or the top of the non-topmost band when no pin).

Fallback when no pin is now `HWND_TOP` (top of non-topmost band) instead of `HWND_TOPMOST` — overlay still renders above other normal windows, but no longer hardcoded above the user's foreground.

Expected Z-order after fix

For the user's repro (terminal foreground, Calculator pinned):

```
top terminal ← user's foreground (non-topmost)
overlay ← just above Calculator, below terminal
calculator ← pinned target
...
bottom
```

Verification

  • Build clean (0 warnings)
  • 32/32 platform-windows tests pass
  • Reviewer: pin overlay above Calculator, bring a normal foreground app over the Calculator, verify overlay is hidden behind the foreground app
  • Reviewer: same but with the foreground app a topmost window (e.g. Task Manager). Overlay correctly stays behind (since it's now non-topmost) — and that's also the right behaviour, the topmost app should win

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Updated overlay window positioning on Windows to properly respect foreground window selection and prevent the overlay from remaining above user-focused windows.

Review Change Stack

…band, lets user's foreground render above the pin

Repro: agent cursor overlay pinned over Calculator. User brings their
terminal in front of the Calculator. The overlay renders on top of
the terminal too — even though it should be hovering above the
Calculator (pinned target) and BELOW the terminal (user's foreground).

Root cause: `reapply_z_order` used `HWND_TOPMOST` as a fallback when
the pin wasn't set (or had gone away). Once Windows promotes a window
into the topmost band via SetWindowPos(HWND_TOPMOST), the topmost
flag SETS on the window — a later SetWindowPos with a normal
target_hwnd does NOT drop it back out. The overlay was effectively
topmost-forever after the first frame where no pin was live (which
happens at startup, between pin commands, etc.).

Fix:
  1. Always issue SetWindowPos(overlay, HWND_NOTOPMOST, …) first to
     drop out of the topmost band if we landed there.
  2. Then SetWindowPos(overlay, target_hwnd OR HWND_TOP, …) to land
     just above the pin (or top of non-topmost band when no pin).

HWND_TOP (the no-pin fallback) means "top of non-topmost band", NOT
the topmost band. Overlay still renders above other normal windows
when no pin is set, but is no longer hardcoded above the user's
foreground app.

Two-call shape is necessary because HWND_NOTOPMOST itself is a
band-transition pseudo-value (-2) that doesn't represent a target;
the second call is what positions us relative to the pinned target.
@vercel

vercel Bot commented May 24, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Ignored Ignored May 24, 2026 2:50pm

Request Review

@coderabbitai

coderabbitai Bot commented May 24, 2026

Copy link
Copy Markdown
Contributor

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 5135fe13-b2bb-4b58-9bd5-7910bc0e5187

📥 Commits

Reviewing files that changed from the base of the PR and between 798fb30 and 83cc3e0.

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

📝 Walkthrough

Walkthrough

The overlay's reapply_z_order function now validates the pinned window target and falls back to HWND_TOP when no valid pin exists. An initial SetWindowPos call demotes the overlay from the topmost band before applying final positioning, addressing cases where prior topmost placement caused the overlay to incorrectly remain above user foreground windows.

Changes

Pinned-target Z-order Maintenance

Layer / File(s) Summary
Pinned-target z-order positioning
libs/cua-driver/rust/crates/platform-windows/src/overlay.rs
reapply_z_order validates the pinned window via IsWindow and uses it as the insertion point if valid; otherwise falls back to HWND_TOP instead of HWND_TOPMOST. An initial SetWindowPos with HWND_NOTOPMOST demotes the overlay from the topmost band before the final SetWindowPos applies the computed insertion point, ensuring proper z-order relative to foreground non-topmost windows.

Sequence Diagram

sequenceDiagram
  participant reapply_z_order
  participant IsWindow
  participant SetWindowPos
  reapply_z_order->>IsWindow: Check if pinned window is valid
  alt Pinned window exists
    IsWindow-->>reapply_z_order: true, use pinned_target
  else No valid pinned window
    IsWindow-->>reapply_z_order: false, fall back to HWND_TOP
  end
  reapply_z_order->>SetWindowPos: SetWindowPos with HWND_NOTOPMOST
  SetWindowPos-->>reapply_z_order: Demote from topmost band
  reapply_z_order->>SetWindowPos: SetWindowPos with computed insertion point
  SetWindowPos-->>reapply_z_order: Apply final z-order position
Loading

Estimated Code Review Effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

A window floats where it should not dwell,
So pinned targets guide the z-order spell.
Check if targets live, or topmost retreat,
Then demote and reposition—neat and sweet! 🐰✨

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch overlay-z-order-not-topmost

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.

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.

1 participant