Skip to content

fix(overlay): apply click-through styles reliably — desktop/taskbar no longer blocked#15

Open
DysektAI wants to merge 1 commit into
masterfrom
fix/overlay-click-through
Open

fix(overlay): apply click-through styles reliably — desktop/taskbar no longer blocked#15
DysektAI wants to merge 1 commit into
masterfrom
fix/overlay-click-through

Conversation

@DysektAI

@DysektAI DysektAI commented Jul 24, 2026

Copy link
Copy Markdown
Member

Root cause

The passive scan overlay (BlazorOverlay) spans all screens, is topmost, and is shown for the whole app lifetime. Its click-through extended styles (WS_EX_TRANSPARENT/WS_EX_LAYERED/WS_EX_NOACTIVATE) were set with SetWindowLongPtr, but Windows caches extended styles — changes only take effect after SetWindowPos with SWP_FRAMECHANGED, which was never called. Depending on timing, the overlay therefore kept hit-testing normally and swallowed every click on the desktop and taskbar (#10, including the desktop/right-click follow-up).

Two secondary gaps made it worse:

  • WebView2 creates its own child input windows beneath the WPF host; hit-test transparency on the top-level window alone does not cover them.
  • SetSize() called SetWindowPos with uFlags = 0, which re-z-orders and can activate the overlay.

Fix

  • Commit every extended-style mutation with SetWindowPos(..., SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE) (both BlazorOverlay and BlazorInteractableOverlay).
  • Recursively apply the click-through styles to all descendant windows (WebView2 input windows), and re-apply after each overlay navigation in case the runtime recreates them.
  • SetSize now uses SWP_NOZORDER | SWP_NOACTIVATE (keeps the XAML-declared Topmost untouched, never activates).

Validation

  • dotnet build / dotnet test (205 passed) / csharpier clean.
  • Manual smoke recommended on the reporter's dual-monitor setup: with RatScanner open (before and after a scan), click taskbar icons, desktop icons, and right-click the desktop.

Fixes #10


Open in Devin Review

Summary by cubic

Make the overlay reliably click-through so desktop and taskbar clicks work again. Commits extended-style changes and covers WebView2 child input windows. Fixes #10.

  • Bug Fixes
    • After any extended-style update, call SetWindowPos with frame-changed + no move/size/z-order + no activate for both overlays.
    • Apply click-through styles to all descendant windows (WebView2 input windows) and re-apply after each navigation.
    • Use SWP_NOZORDER and SWP_NOACTIVATE in SetSize to prevent z-order changes and activation.

Written for commit cb1958c. Summary will update on new commits.

Review in cubic

Greptile Summary

This PR fixes a long-standing click-through regression where the BlazorOverlay passive scan overlay was blocking all mouse input to the desktop and taskbar. The root cause was that SetWindowLongPtr extended-style changes are cached by Windows and require a subsequent SetWindowPos(..., SWP_FRAMECHANGED) to take effect, which was never called.

  • Adds the SWP_FRAMECHANGED flush after every extended-style mutation in both BlazorOverlay and BlazorInteractableOverlay, which is the correct and necessary fix for the cached-style problem.
  • Recursively applies click-through styles to all WebView2 descendant child windows via EnumChildWindows, and re-applies on each navigation so late-created input windows are covered.
  • Fixes SetSize() in BlazorOverlay to use SWP_NOZORDER | SWP_NOACTIVATE, preventing accidental z-order changes and focus theft during resizes.

Confidence Score: 3/5

The core click-through fix is correct but two defects in the same changeset need resolution before merging.

The SetPosition() call in BlazorInteractableOverlay still passes uFlags = 0 to SetWindowPos, so the overlay can be activated and z-reordered on every ShowOverlay() call — the same focus-steal this PR explicitly sets out to prevent. Separately, ApplyStyleToDescendants calls itself recursively inside the EnumChildWindows callback despite EnumChildWindows already walking the full descendant tree, causing each child window to receive redundant WM_NCCALCSIZE messages on every navigation event.

Files Needing Attention: Both changed files need attention: BlazorInteractableOverlay.xaml.cs for the unfixed SetPosition() flags, and BlazorOverlay.xaml.cs for the redundant recursion in ApplyStyleToDescendants.

Important Files Changed

Filename Overview
src/App/View/BlazorOverlay.xaml.cs Adds SWP_FRAMECHANGED flush, EnumChildWindows descendant styling, and SWP_NOZORDER
src/App/View/BlazorInteractableOverlay.xaml.cs Adds null-handle guard and SWP_FRAMECHANGED commit for the tool-window style — correct and necessary — but SetPosition() still calls SetWindowPos with uFlags = 0, which can activate the window and steal focus from the game.

Sequence Diagram

sequenceDiagram
    participant WPF as WPF Host
    participant BO as BlazorOverlay
    participant WV as WebView2
    participant Win32 as Win32 (user32.dll)

    WPF->>BO: OnSourceInitialized
    BO->>Win32: "SetWindowLongPtr(WS_EX_TRANSPARENT | WS_EX_LAYERED | ...)"
    BO->>Win32: SetWindowPos(SWP_FRAMECHANGED) flushes cached style
    BO->>Win32: EnumChildWindows apply click-through to all children

    WPF->>BO: BlazorWebView_Initialized
    BO->>Win32: "SetWindowPos(left, top, w, h, SWP_NOZORDER | SWP_NOACTIVATE)"
    BO->>Win32: SetWindowLongPtr + SetWindowPos(SWP_FRAMECHANGED)
    BO->>Win32: EnumChildWindows apply to children

    WV->>BO: NavigationCompleted (WebView_Loaded)
    Note over BO,WV: WebView2 may recreate child input windows here
    BO->>Win32: SetWindowLongPtr + SetWindowPos(SWP_FRAMECHANGED)
    BO->>Win32: EnumChildWindows re-apply to any new child input windows
Loading

Comments Outside Diff (1)

  1. src/App/View/BlazorInteractableOverlay.xaml.cs, line 61 (link)

    P1 SetPosition() still passes uFlags = 0 to SetWindowPos, which allows Windows to re-z-order and activate the interactable overlay on every ShowOverlay() call. This is the same activation-steal bug that the PR fixes in BlazorOverlay.SetSize(), but was not applied here — activating the overlay steals focus from the game, which is the exact outcome WS_EX_NOACTIVATE is meant to prevent.

    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: src/App/View/BlazorInteractableOverlay.xaml.cs
    Line: 61
    
    Comment:
    `SetPosition()` still passes `uFlags = 0` to `SetWindowPos`, which allows Windows to re-z-order and activate the interactable overlay on every `ShowOverlay()` call. This is the same activation-steal bug that the PR fixes in `BlazorOverlay.SetSize()`, but was not applied here — activating the overlay steals focus from the game, which is the exact outcome `WS_EX_NOACTIVATE` is meant to prevent.
    
    
    
    How can I resolve this? If you propose a fix, please make it concise.
Prompt To Fix All With AI
Fix the following 3 code review issues. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 3
src/App/View/BlazorOverlay.xaml.cs:123-140
`EnumChildWindows` enumerates *all* descendants of a window (not just direct children) — it recurses into grandchildren automatically. The call to `ApplyStyleToDescendants(child, …)` inside the callback therefore re-enumerates and re-styles every already-visited subtree. For a 4-level-deep WebView2 tree `A→B→C→D`, node D has `SetWindowLongPtr`/`SetWindowPos` (and therefore `WM_NCCALCSIZE`) called on it 4 times per `SetWindowStyle()` invocation, which is triggered on every navigation. The recursive line should be removed so each child window is styled exactly once.

### Issue 2 of 3
src/App/View/BlazorInteractableOverlay.xaml.cs:61
`SetPosition()` still passes `uFlags = 0` to `SetWindowPos`, which allows Windows to re-z-order and activate the interactable overlay on every `ShowOverlay()` call. This is the same activation-steal bug that the PR fixes in `BlazorOverlay.SetSize()`, but was not applied here — activating the overlay steals focus from the game, which is the exact outcome `WS_EX_NOACTIVATE` is meant to prevent.

```suggestion
        const uint swpNoZOrder = 0x0004;
        const uint swpNoActivate = 0x0010;
        NativeMethods.SetWindowPos(handle, 0, b.Left, b.Top, b.Right - b.Left, b.Bottom - b.Top, swpNoZOrder | swpNoActivate);
```

### Issue 3 of 3
src/App/View/BlazorOverlay.xaml.cs:129-136
The recursive `ApplyStyleToDescendants(child, …)` call inside the `EnumChildWindows` callback is redundant: `EnumChildWindows` already walks the entire descendant tree on its own. Removing it makes each child's style applied exactly once and avoids exponentially many redundant `WM_NCCALCSIZE` messages to WebView2's internal windows on each navigation.

```suggestion
                NativeMethods.SetWindowLongPtr(
                    child,
                    gwlExStyle,
                    NativeMethods.GetWindowLongPtr(child, gwlExStyle) | styles
                );
                NativeMethods.SetWindowPos(child, 0, 0, 0, 0, 0, NativeMethods.SwpFrameChangedFlags);
                return true;
```

Reviews (1): Last reviewed commit: "fix(overlay): apply click-through styles..." | Re-trigger Greptile

Greptile also left 2 inline comments on this PR.

…ld input windows)

The passive overlay spans all screens topmost. Its WS_EX_TRANSPARENT /
WS_EX_LAYERED styles were set with SetWindowLongPtr but never committed:
extended-style changes are cached and only take effect after a
frame-changed SetWindowPos, so depending on timing the overlay kept
swallowing every click on the desktop and taskbar (issue #10).

- Call SetWindowPos with SWP_FRAMECHANGED (NOACTIVATE/NOMOVE/NOSIZE/
  NOZORDER) after every extended-style mutation, in both overlay windows.
- Apply click-through recursively to WebView2's child input windows;
  hit-test transparency on the top-level window does not cover them.
- Re-apply styles after each overlay navigation in case the runtime
  recreates input windows.
- SetSize now uses SWP_NOZORDER|SWP_NOACTIVATE instead of flags=0 so the
  resize can no longer re-z-order or activate the overlay.

Fixes #10
@coderabbitai

coderabbitai Bot commented Jul 24, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Changes

Overlay click-through handling

Layer / File(s) Summary
Apply click-through styles to overlay descendants
src/App/View/BlazorOverlay.xaml.cs
Overlay resizing avoids Z-order changes and activation; click-through styles are refreshed on the top-level window and descendant WebView2 windows, including after navigation.
Refresh interactable overlay frame
src/App/View/BlazorInteractableOverlay.xaml.cs
Invalid handles return early, and extended-style changes are immediately applied with a frame-refreshing SetWindowPos call.

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

Sequence Diagram(s)

sequenceDiagram
  participant WebView_Loaded
  participant SetWindowStyle
  participant EnumChildWindows
  WebView_Loaded->>SetWindowStyle: Reapply styles after navigation
  SetWindowStyle->>EnumChildWindows: Enumerate descendant windows
  EnumChildWindows-->>SetWindowStyle: Apply click-through styles
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The changes address issue #10 by preventing the overlay and WebView2 child windows from blocking taskbar and desktop interaction.
Out of Scope Changes check ✅ Passed The PR stays focused on overlay click-through behavior and related window-style fixes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Title check ✅ Passed The title accurately summarizes the main fix: making the overlay reliably click-through so desktop and taskbar input is no longer blocked.
Description check ✅ Passed The description directly matches the implemented changes and explains the click-through fix, WebView2 child-window handling, and size flag updates.
✨ 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 fix/overlay-click-through

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

@codeant-ai

codeant-ai Bot commented Jul 24, 2026

Copy link
Copy Markdown

🏁 CodeAnt Quality Gate Results

Commit: cb1958c3
Scan Time: 2026-07-24 23:53:27 UTC

✅ Overall Status: PASSED

Quality Gate Details

Quality Gate Status Details
Secrets ✅ PASSED 0 secrets found
Duplicate Code ✅ PASSED 2.5% duplicated
SAST ✅ PASSED No security issues
Bugs ✅ PASSED Rating S: No bugs
IAC ✅ PASSED No IAC issues

View Full Results

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Devin Review found 3 potential issues.

Open in Devin Review

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📝 Info: Interactable overlay SetPosition still uses uFlags=0

The PR fixes BlazorOverlay.SetSize to use SWP_NOZORDER | SWP_NOACTIVATE, but BlazorInteractableOverlay.SetPosition (src/App/View/BlazorInteractableOverlay.xaml.cs:61) still calls SetWindowPos(..., 0), which re-z-orders and can activate the window. This is likely acceptable because the interactable overlay is meant to be focusable/interactive (XAML Focusable="True", no click-through styles), unlike the passive overlay, so the activation concern that motivated the SetSize fix does not apply here. Noting it since the two files diverge on this point.

(Refers to line 61)

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment on lines +123 to 140
private static void ApplyStyleToDescendants(nint parent, int gwlExStyle, nint styles)
{
NativeMethods.EnumChildWindows(
parent,
(child, _) =>
{
NativeMethods.SetWindowLongPtr(
child,
gwlExStyle,
NativeMethods.GetWindowLongPtr(child, gwlExStyle) | styles
);
NativeMethods.SetWindowPos(child, 0, 0, 0, 0, 0, NativeMethods.SwpFrameChangedFlags);
ApplyStyleToDescendants(child, gwlExStyle, styles);
return true;
},
0
);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📝 Info: Redundant descendant enumeration (EnumChildWindows already recurses)

ApplyStyleToDescendants (src/App/View/BlazorOverlay.xaml.cs:123-140) manually recurses by calling itself for every child, but EnumChildWindows already visits ALL descendants of the parent (Windows enumerates a window's children AND their children). Combined, each descendant at depth d gets its extended styles set and SetWindowPos called multiple times. The operation is idempotent (bitwise OR of styles) so this is not a correctness bug, but it performs redundant work that grows with hierarchy depth. Since it re-runs on every NavigationCompleted via WebView_LoadedSetWindowStyle (src/App/View/BlazorOverlay.xaml.cs:142-152), the extra churn is small for WebView2's shallow window tree but is unnecessary.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment on lines +117 to +135
// WebView2 creates its own child input windows beneath the WPF host;
// hit-test transparency on the top-level window alone does not cover
// them. Apply click-through to every descendant as well.
ApplyStyleToDescendants(handle, gwlExStyle, clickThroughStyles);
}

private static void ApplyStyleToDescendants(nint parent, int gwlExStyle, nint styles)
{
NativeMethods.EnumChildWindows(
parent,
(child, _) =>
{
NativeMethods.SetWindowLongPtr(
child,
gwlExStyle,
NativeMethods.GetWindowLongPtr(child, gwlExStyle) | styles
);
NativeMethods.SetWindowPos(child, 0, 0, 0, 0, 0, NativeMethods.SwpFrameChangedFlags);
ApplyStyleToDescendants(child, gwlExStyle, styles);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔍 WS_EX_LAYERED committed on WebView2 child input windows

The click-through style bundle includes WS_EX_LAYERED and is now committed (via SWP_FRAMECHANGED) not only on the top-level window but on every descendant WebView2 window (src/App/View/BlazorOverlay.xaml.cs:101,120,129-134). For a top-level window this is safe because both overlays declare AllowsTransparency="True", so WPF already owns the layered attributes. For the WebView2 child windows, setting WS_EX_LAYERED without ever calling SetLayeredWindowAttributes/UpdateLayeredWindow can, on plain child HWNDs, suppress rendering. This should be benign here because WebView2CompositionControl renders through DirectComposition (the child HWNDs are input-only), but it is worth confirming on the reporter's dual-monitor setup that the passive scan tooltip still renders correctly after a scan, per the manual smoke test noted in the PR description.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment on lines +123 to 140
private static void ApplyStyleToDescendants(nint parent, int gwlExStyle, nint styles)
{
NativeMethods.EnumChildWindows(
parent,
(child, _) =>
{
NativeMethods.SetWindowLongPtr(
child,
gwlExStyle,
NativeMethods.GetWindowLongPtr(child, gwlExStyle) | styles
);
NativeMethods.SetWindowPos(child, 0, 0, 0, 0, 0, NativeMethods.SwpFrameChangedFlags);
ApplyStyleToDescendants(child, gwlExStyle, styles);
return true;
},
0
);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 EnumChildWindows enumerates all descendants of a window (not just direct children) — it recurses into grandchildren automatically. The call to ApplyStyleToDescendants(child, …) inside the callback therefore re-enumerates and re-styles every already-visited subtree. For a 4-level-deep WebView2 tree A→B→C→D, node D has SetWindowLongPtr/SetWindowPos (and therefore WM_NCCALCSIZE) called on it 4 times per SetWindowStyle() invocation, which is triggered on every navigation. The recursive line should be removed so each child window is styled exactly once.

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/App/View/BlazorOverlay.xaml.cs
Line: 123-140

Comment:
`EnumChildWindows` enumerates *all* descendants of a window (not just direct children) — it recurses into grandchildren automatically. The call to `ApplyStyleToDescendants(child, …)` inside the callback therefore re-enumerates and re-styles every already-visited subtree. For a 4-level-deep WebView2 tree `A→B→C→D`, node D has `SetWindowLongPtr`/`SetWindowPos` (and therefore `WM_NCCALCSIZE`) called on it 4 times per `SetWindowStyle()` invocation, which is triggered on every navigation. The recursive line should be removed so each child window is styled exactly once.

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines +129 to +136
NativeMethods.SetWindowLongPtr(
child,
gwlExStyle,
NativeMethods.GetWindowLongPtr(child, gwlExStyle) | styles
);
NativeMethods.SetWindowPos(child, 0, 0, 0, 0, 0, NativeMethods.SwpFrameChangedFlags);
ApplyStyleToDescendants(child, gwlExStyle, styles);
return true;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 The recursive ApplyStyleToDescendants(child, …) call inside the EnumChildWindows callback is redundant: EnumChildWindows already walks the entire descendant tree on its own. Removing it makes each child's style applied exactly once and avoids exponentially many redundant WM_NCCALCSIZE messages to WebView2's internal windows on each navigation.

Suggested change
NativeMethods.SetWindowLongPtr(
child,
gwlExStyle,
NativeMethods.GetWindowLongPtr(child, gwlExStyle) | styles
);
NativeMethods.SetWindowPos(child, 0, 0, 0, 0, 0, NativeMethods.SwpFrameChangedFlags);
ApplyStyleToDescendants(child, gwlExStyle, styles);
return true;
NativeMethods.SetWindowLongPtr(
child,
gwlExStyle,
NativeMethods.GetWindowLongPtr(child, gwlExStyle) | styles
);
NativeMethods.SetWindowPos(child, 0, 0, 0, 0, 0, NativeMethods.SwpFrameChangedFlags);
return true;
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/App/View/BlazorOverlay.xaml.cs
Line: 129-136

Comment:
The recursive `ApplyStyleToDescendants(child, …)` call inside the `EnumChildWindows` callback is redundant: `EnumChildWindows` already walks the entire descendant tree on its own. Removing it makes each child's style applied exactly once and avoids exponentially many redundant `WM_NCCALCSIZE` messages to WebView2's internal windows on each navigation.

```suggestion
                NativeMethods.SetWindowLongPtr(
                    child,
                    gwlExStyle,
                    NativeMethods.GetWindowLongPtr(child, gwlExStyle) | styles
                );
                NativeMethods.SetWindowPos(child, 0, 0, 0, 0, 0, NativeMethods.SwpFrameChangedFlags);
                return true;
```

How can I resolve this? If you propose a fix, please make it concise.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

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 `@src/App/View/BlazorOverlay.xaml.cs`:
- Around line 123-139: Remove the recursive ApplyStyleToDescendants call from
the EnumChildWindows callback within ApplyStyleToDescendants, since enumeration
already covers all descendants. Preserve the existing style update and
SetWindowPos behavior, then run dotnet tool restore, dotnet csharpier check .,
and dotnet build RatScanner.sln.
🪄 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: ASSERTIVE

Plan: Pro

Run ID: cf052c1b-0c40-496b-afb2-5ba830627b30

📥 Commits

Reviewing files that changed from the base of the PR and between 3b2c66c and cb1958c.

📒 Files selected for processing (2)
  • src/App/View/BlazorInteractableOverlay.xaml.cs
  • src/App/View/BlazorOverlay.xaml.cs

Comment on lines +123 to 139
private static void ApplyStyleToDescendants(nint parent, int gwlExStyle, nint styles)
{
NativeMethods.EnumChildWindows(
parent,
(child, _) =>
{
NativeMethods.SetWindowLongPtr(
child,
gwlExStyle,
NativeMethods.GetWindowLongPtr(child, gwlExStyle) | styles
);
NativeMethods.SetWindowPos(child, 0, 0, 0, 0, 0, NativeMethods.SwpFrameChangedFlags);
ApplyStyleToDescendants(child, gwlExStyle, styles);
return true;
},
0
);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Remove the redundant recursive enumeration.

EnumChildWindows already invokes its callback for every descendant; line 135 re-enumerates each subtree and repeatedly frame-refreshes deep WebView2 windows on every navigation. Remove the recursive call. (learn.microsoft.com)

Proposed fix
                 NativeMethods.SetWindowPos(child, 0, 0, 0, 0, 0, NativeMethods.SwpFrameChangedFlags);
-                ApplyStyleToDescendants(child, gwlExStyle, styles);
                 return true;

As per coding guidelines, run dotnet build RatScanner.sln before declaring this C# change complete.

dotnet tool restore
dotnet csharpier check .
dotnet build RatScanner.sln
🤖 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 `@src/App/View/BlazorOverlay.xaml.cs` around lines 123 - 139, Remove the
recursive ApplyStyleToDescendants call from the EnumChildWindows callback within
ApplyStyleToDescendants, since enumeration already covers all descendants.
Preserve the existing style update and SetWindowPos behavior, then run dotnet
tool restore, dotnet csharpier check ., and dotnet build RatScanner.sln.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

2 issues found across 2 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="src/App/View/BlazorOverlay.xaml.cs">

<violation number="1" location="src/App/View/BlazorOverlay.xaml.cs:135">
P2: Overlay initialization and every navigation can perform exponentially repeated `SetWindowLongPtr`/`SetWindowPos` calls because `EnumChildWindows` already traverses all descendants. Removing this explicit recursion still styles every descendant once.</violation>
</file>

<file name="src/App/View/BlazorInteractableOverlay.xaml.cs">

<violation number="1" location="src/App/View/BlazorInteractableOverlay.xaml.cs:99">
P3: SWP flag constants (`swpNoMove`, `swpNoSize`, `swpNoZOrder`, `swpNoActivate`, `swpFrameChanged`) are defined as local `const uint` inside `SetWindowStyle()`, while semantically identical constants already exist as `public const uint` fields in `BlazorOverlay.NativeMethods`. This creates a maintenance trap — if the combined flags ever need to change (e.g., adding/removing a flag for all SetWindowPos callers), one of the two sites will be missed.

Consider extracting the SWP constants to a shared location (e.g., a common `NativeMethods` file) so both overlays reference the same flags, or reference `BlazorOverlay.NativeMethods.SwpFrameChangedFlags` directly to eliminate the duplication.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Fix all with cubic | Re-trigger cubic

NativeMethods.GetWindowLongPtr(child, gwlExStyle) | styles
);
NativeMethods.SetWindowPos(child, 0, 0, 0, 0, 0, NativeMethods.SwpFrameChangedFlags);
ApplyStyleToDescendants(child, gwlExStyle, styles);

@cubic-dev-ai cubic-dev-ai Bot Jul 24, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2: Overlay initialization and every navigation can perform exponentially repeated SetWindowLongPtr/SetWindowPos calls because EnumChildWindows already traverses all descendants. Removing this explicit recursion still styles every descendant once.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/App/View/BlazorOverlay.xaml.cs, line 135:

<comment>Overlay initialization and every navigation can perform exponentially repeated `SetWindowLongPtr`/`SetWindowPos` calls because `EnumChildWindows` already traverses all descendants. Removing this explicit recursion still styles every descendant once.</comment>

<file context>
@@ -96,13 +107,45 @@ private void SetWindowStyle()
+                    NativeMethods.GetWindowLongPtr(child, gwlExStyle) | styles
+                );
+                NativeMethods.SetWindowPos(child, 0, 0, 0, 0, 0, NativeMethods.SwpFrameChangedFlags);
+                ApplyStyleToDescendants(child, gwlExStyle, styles);
+                return true;
+            },
</file context>
Fix with cubic

{
const int gwlExStyle = -20; // GWL_EXSTYLE
const uint wsExToolWindow = 0x00000080; // WS_EX_TOOLWINDOW
const uint swpNoMove = 0x0002;

@cubic-dev-ai cubic-dev-ai Bot Jul 24, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P3: SWP flag constants (swpNoMove, swpNoSize, swpNoZOrder, swpNoActivate, swpFrameChanged) are defined as local const uint inside SetWindowStyle(), while semantically identical constants already exist as public const uint fields in BlazorOverlay.NativeMethods. This creates a maintenance trap — if the combined flags ever need to change (e.g., adding/removing a flag for all SetWindowPos callers), one of the two sites will be missed.

Consider extracting the SWP constants to a shared location (e.g., a common NativeMethods file) so both overlays reference the same flags, or reference BlazorOverlay.NativeMethods.SwpFrameChangedFlags directly to eliminate the duplication.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/App/View/BlazorInteractableOverlay.xaml.cs, line 99:

<comment>SWP flag constants (`swpNoMove`, `swpNoSize`, `swpNoZOrder`, `swpNoActivate`, `swpFrameChanged`) are defined as local `const uint` inside `SetWindowStyle()`, while semantically identical constants already exist as `public const uint` fields in `BlazorOverlay.NativeMethods`. This creates a maintenance trap — if the combined flags ever need to change (e.g., adding/removing a flag for all SetWindowPos callers), one of the two sites will be missed.

Consider extracting the SWP constants to a shared location (e.g., a common `NativeMethods` file) so both overlays reference the same flags, or reference `BlazorOverlay.NativeMethods.SwpFrameChangedFlags` directly to eliminate the duplication.</comment>

<file context>
@@ -96,13 +96,32 @@ private void SetWindowStyle()
     {
         const int gwlExStyle = -20; // GWL_EXSTYLE
         const uint wsExToolWindow = 0x00000080; // WS_EX_TOOLWINDOW
+        const uint swpNoMove = 0x0002;
+        const uint swpNoSize = 0x0001;
+        const uint swpNoZOrder = 0x0004;
</file context>
Fix with cubic

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.

RatScanner blocks Windows taskbar

1 participant