Skip to content

fix(capture): keep the overlay out of scan captures; release idle HDR sessions - #78

Merged
DysektAI merged 5 commits into
masterfrom
fix/capture-self-exclusion
Oct 22, 2026
Merged

DysektAI merged 5 commits into
masterfrom
fix/capture-self-exclusion

Conversation

@DysektAI

@DysektAI DysektAI commented Oct 19, 2026 •

Copy link
Copy Markdown
Member

Why

  • Self-capture (affects every user): a probe on Windows 11 shows GDI CopyFromScreen(SourceCopy) returns the pixels of a topmost WS_EX_LAYERED window. A tooltip still showing from the previous scan (1.5 s) is therefore read back into the next icon/name capture, drawn over the item being re-scanned or its neighbours. Plausible contributor to "inconsistent icon scans".
  • HDR (opt-in) idle GPU: desktop-duplication sessions were kept forever after the first HDR scan; an active duplication makes DWM copy every presented frame.

Related: #34 (repeated icon scans returning the same item at 0.94 while different items were clicked is consistent with the previous tooltip being captured; EFT's own hover tooltip is a separate cause).

What

  • The overlay window sets SetWindowDisplayAffinity(WDA_EXCLUDEFROMCAPTURE) (Win10 2004+; failure is logged and leaves today's behaviour). ToolTip.ExcludeFromCapture (default on) is a Settings → General switch, "Hide tooltips from screenshots and recordings", in all 7 locales. Changing it takes effect the next time a tooltip appears.
  • IdleRelease helper; HDR sessions are released after 30 s without an HDR capture and recreated on the next one.

Validation

  • Probe: layered red window → captured as R253 G1 B2; same window with 0x11 affinity → background pixels captured.
  • Running app: "RatScanner Overlay" reports affinity 0x11, main window unchanged; clean exit.
  • IdleReleaseTests (release after idle, countdown restarts on use, no release before use/after cancel), config default/disable test.
  • Debug and Release build; dotnet test 412/412 on this branch.
  • Settings toggle (5ab84b6): Tooltip_capture_exclusion_can_be_turned_off_and_back_on_from_settings checks that turning the setting off and back on updates the runtime value and saves it each time. The WebView2 smoke test checks that the switch is visible. All 7 locale files have the same 385 keys.
  • 5ab84b6 compiles on Linux (EnableWindowsTargeting) for the app, unit test, and UI test projects with 0 errors, and CSharpier is clean. Tests were not run there because Linux has no WindowsDesktop runtime.
  • Local CodeRabbit (head 5ab84b6) reported one minor finding: an already-queued IdleRelease timer callback can still release sessions just after a Touch(). The only cost is one extra session rebuild on the next HDR capture.

Decision for review

  • With the default on, tooltips no longer appear in screenshots or OBS display/window capture (OBS game capture never included them). Streamers can turn the new Settings switch off; the default stays on so scans stay accurate.

Not done (needs in-game evidence)

  • Main window (AlwaysOnTop default true, layered) over a fullscreen game: its cost lands in DWM/the game's flip model, which the idle benchmark cannot see. No change without a measurement.

https://claude.ai/code/session_01QFKiA2aswHyp8SnpraLxE2
https://claude.ai/code/session_01AJBRm45o94V3UvbN5ZbLUD

… sessions

- Screen captures include layered windows (verified: GDI CopyFromScreen
  returns a topmost WS_EX_LAYERED window's pixels), so a tooltip still
  showing from the previous scan was read back into the next capture,
  drawn over the very item being re-scanned or its neighbours. The
  overlay window now uses WDA_EXCLUDEFROMCAPTURE (verified: the same
  probe then reads the pixels underneath; the running overlay reports
  affinity 0x11). ToolTip.ExcludeFromCapture in config.cfg (default on)
  turns this off for users who want tooltips in screenshots/streams.
- Opt-in HDR capture kept its desktop-duplication sessions forever after
  the first scan; an active duplication makes DWM copy every frame.
  Sessions are now released after 30 s without an HDR capture.

Claude-Session: https://claude.ai/code/session_01QFKiA2aswHyp8SnpraLxE2
@coderabbitai

coderabbitai Bot commented Oct 19, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Warning

Review limit reached

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

Next included review available in 16 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available. Your 68 included PR review attempts over the past 7 days set your current allowance at 1 review per hour.

Learn how review limits work.

Review configuration:

⚙️ Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: ASSERTIVE
  • Plan: Essentials
  • Run ID: 3f7b69c2-f39e-4284-9fca-de3cb0eb86c0
📥 Commits

Reviewing files that changed from the base of the PR and between 5ab84b6 and 6397081.

📒 Files selected for processing: 20
  • src/App/Display/HdrScreenCapture.cs
  • src/App/Display/IdleRelease.cs
  • src/App/Pages/App/Settings/SettingsGeneral.razor
  • src/App/RatConfig.cs
  • src/App/View/BlazorOverlay.xaml.cs
  • src/App/View/OverlayCaptureExclusion.cs
  • src/App/View/OverlayNativeMethods.cs
  • src/App/ViewModel/SettingsVM.cs
  • src/App/i18n/en.json
  • src/App/i18n/es.json
  • src/App/i18n/fr.json
  • src/App/i18n/pl.json
  • src/App/i18n/pt.json
  • src/App/i18n/ru.json
  • src/App/i18n/zh.json
  • tests/RatScanner.Tests/ApplicationBoundaryTests.cs
  • tests/RatScanner.Tests/ConfigurationMigrationTests.cs
  • tests/RatScanner.Tests/IdleReleaseTests.cs
  • tests/RatScanner.Tests/OverlayCaptureExclusionTests.cs
  • tests/RatScanner.UiTests/WebViewSmokeTests.cs
📝 Summary

Summary by CodeRabbit

  • New Features
    • Added a setting to hide tooltips from screenshots and recordings. It’s enabled by default and can be changed in General Settings.
  • Improvements
    • Idle capture sessions are now released after 30 seconds without activity.

The changes add idle cleanup for HDR capture sessions and a setting that excludes tooltips from screenshots and recordings. The setting is persisted, localized, and applied by the overlay through Windows display affinity.

Changes: HDR capture session cleanup

Layer / File(s) Summary
Idle release timer
src/App/Display/IdleRelease.cs, tests/RatScanner.Tests/IdleReleaseTests.cs
The timer starts on first use, restarts after each touch, and supports cancellation. Tests cover its timing behavior.
HDR session cleanup
src/App/Display/HdrScreenCapture.cs
Capture activity touches the timer. When it expires, the code resets sessions if any exist.

Tooltip capture exclusion

Layer / File(s) Summary
Setting and UI wiring
src/App/RatConfig.cs, src/App/Pages/App/Settings/SettingsGeneral.razor, src/App/ViewModel/SettingsVM.cs, src/App/i18n/*, tests/RatScanner.Tests/ApplicationBoundaryTests.cs, tests/RatScanner.Tests/ConfigurationMigrationTests.cs, tests/RatScanner.UiTests/WebViewSmokeTests.cs
The configuration gains a setting that defaults to enabled and is loaded and saved. The settings page exposes the option, with translations and tests for persistence, configuration loading, and UI visibility.
Overlay display affinity
src/App/View/OverlayNativeMethods.cs, src/App/View/BlazorOverlay.xaml.cs
The overlay applies the configured Windows display affinity and logs a warning if the native call fails. Before showing a tooltip, it reapplies the setting when the tracked value differs from configuration.

Priority: ➖ Normal

Estimated code review effort: 3 (Moderate) | ~25 minutes

Change: Bug fix

Sequence Diagram(s)

sequenceDiagram
  participant SettingsGeneral
  participant SettingsVM
  participant RatConfig
  participant BlazorOverlay
  participant SetWindowDisplayAffinity
  SettingsGeneral->>SettingsVM: Save exclusion setting
  SettingsVM->>RatConfig: Update and persist setting
  BlazorOverlay->>RatConfig: Read setting before showing tooltip
  BlazorOverlay->>SetWindowDisplayAffinity: Apply configured display affinity
Loading
Merge Risk: 🔵 Low · up to 5ab84

HDR sessions may be recreated sooner than intended, and tooltip capture exclusion may remain off after a recoverable affinity failure. These bounded risks warrant owner follow-up before or shortly after merge.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 18.75% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 32 functions across 10 files. (8 skipped:… Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Title check Passed The title clearly summarizes both primary changes: excluding the overlay from capture and releasing idle HDR sessions.
Description check Passed The description directly explains the capture issue, HDR session changes, settings behavior, validation, and known limitations.
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.
Full details: Docstring Coverage

Explanation

Docstring coverage is 18.75% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 32 functions across 10 files. (8 skipped: 8 unsupported.)

Resolution

Write docstrings for the functions missing them to satisfy the coverage threshold.

✨ Finishing Touches: 💡 1
📝 Generate docstrings: 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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

ExcludeFromCapture keeps the overlay out of scans, but it also hides
tooltips from OBS and screenshots, and it could only be changed by editing
the config file. Add a General settings switch (all locales), and make the
overlay re-apply the display affinity on the next tooltip when the setting
changes.

Claude-Session: https://claude.ai/code/session_01AJBRm45o94V3UvbN5ZbLUD
coderabbitai[bot]

This comment was marked as resolved.

…ases

- IdleRelease checks the deadline under the caller's lock, so a timer callback
  queued behind a capture re-arms instead of tearing down the session just used.
- A failed SetWindowDisplayAffinity is no longer recorded as applied; the next
  tooltip retries and the warning is logged once per failure streak.
- Tests cover the countdown restart, the queued-callback race, cancel, and the
  capture exclusion success, failure, and unsupported-OS paths.

Claude-Session: https://claude.ai/code/session_01AJBRm45o94V3UvbN5ZbLUD
@DysektAI DysektAI self-assigned this Oct 22, 2026
@DysektAI
DysektAI merged commit 208f4ec into master Oct 22, 2026
9 checks passed
@DysektAI
DysektAI deleted the fix/capture-self-exclusion branch October 22, 2026 12:07
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