Skip to content

owned_window_over: report the owned window's visible frame as region - #1739

Merged
abrichr merged 1 commit into
mainfrom
claude/owned-window-region
Nov 3, 2026
Merged

abrichr merged 1 commit into
mainfrom
claude/owned-window-region

Conversation

@abrichr

@abrichr abrichr commented Nov 3, 2026

Copy link
Copy Markdown
Member

Follow-up to #1735, as the coordinator asked, for agnostic-repair's covered-band repair.

Contract change. The owned_window_over answer gains region: [x, y, w, h]. It is the reported owned window's visible frame: DWM extended frame bounds, no shadow, in the same click pixels as the region argument. It is the whole frame, not its overlap with the query, so the caller can require the cover to span the band from the cut point to the right edge at full height. WindowsBackend.owned_window_over now requires the key and returns None when it is missing or malformed (not 4 ints, a bool, a float, zero or negative size). The caller treats its absence as doubt.

1x1 regions. agnostic-repair also asks owned_window_over((x, y, 1, 1), pinned_step_id=...) at the dismiss-click point and requires the same hwnd as the cover. The existing intersection test already handles a 1x1 box (right and bottom edges exclusive). New tests pin the behaviour:

  • with two owned windows, a point returns the topmost owned window there;
  • a point under a foreign window returns None;
  • a foreign window elsewhere does not decide a point it doesn't reach;
  • the exclusive edge returns None.

No other behaviour changes: which window is reported, and when the answer is None, are as in #1735. The one in-repo caller, repair/self_repair.py, reads hwnd and does not check the key set.

Tests: 3 new agent tests, 6 new backend refusal cases, 1 updated expected answer. test_win_agent_server.py, test_windows_backend.py, test_repair_covered_band.py and test_macos_sheets.py pass (237). The macOS sheet backend does not return region, so a caller that requires it will treat macOS as doubt until it does.

The answer gains region [x, y, w, h]: the owned window's DWM frame bounds
(no shadow) in the same click pixels as the query. agnostic-repair uses it
to require the cover to span the band from the cut point to the right edge
at full height, and asks with a 1x1 region at the dismiss-click point. The
backend treats a missing or malformed region as no answer.
@abrichr

abrichr commented Nov 3, 2026

Copy link
Copy Markdown
Member Author

Independent adversarial review (separate agent, read-only): approve, no blockers. 217 tests pass.

What it checked:

  • The frame belongs to the reported window: rect is read in the same iteration that sets owned.
  • A foreign window over the frame but outside the query: this doesn't fool the one caller, because it queries the full band and any foreign window touching the band returns None.
  • 1x1 queries: the half-open intersection gets the edges right. A child popup at the point reports the popup's hwnd, so the caller's same-hwnd check fails closed.
  • Minimized, cloaked and hung-app ghost windows: all handled.
  • Validation: negative x/y are accepted, correctly, for monitors left of or above the primary.
  • Other callers: no in-repo caller depends on the old key set.

Should-fix items, for follow-ups (the freeze rule allows only blocker fixes after approval):

  1. region is an upper bound on what the window paints. A layered or transparent WPF/Chromium dialog, or one shaped with SetWindowRgn, reports a frame larger than its painted area. Either document this, or return None for WS_EX_LAYERED and regioned owned windows. The replay probe still re-verifies identity.
  2. Multi-monitor coordinates. The screenshot is mss monitors[0] (virtual-desktop origin) and window rects are in screen coordinates. With a monitor left of or above the primary these differ. This predates the PR (the query region has the same issue), but narrow the "same click pixels" wording or confirm the translation.
  3. One answer shape across backends. macOS returns {kind, window_id, pid}. Add a shared TypedDict or Protocol, and document that callers must query the full band and not rely on region alone.

Nits: three docstring lines are over the line length; frame might be a clearer key name than region; add a test for a negative-coordinate frame.

@abrichr
abrichr merged commit 213f3d9 into main Nov 3, 2026
43 checks passed
@abrichr
abrichr deleted the claude/owned-window-region branch November 3, 2026 17:18
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