Skip to content

[Windows] InputTransparent: Respect wrapper view hit testing - #37392

Merged
kubaflo merged 12 commits into
inflight/currentfrom
jfversluis-fix-inputtransparent-windows
Aug 18, 2026
Merged

kubaflo merged 12 commits into
inflight/currentfrom
jfversluis-fix-inputtransparent-windows

Conversation

@jfversluis

@jfversluis jfversluis commented Aug 13, 2026 •

Copy link
Copy Markdown
Member

Note

Are you waiting for the changes in this PR to be merged?
It would be very helpful if you could test the resulting artifacts from this PR and let us know in a comment if this change resolves your issue. Thank you!

Description of Change

On Windows, propagate InputTransparent to a view's WrapperView as well as its inner platform view. This allows pointer input to pass through wrapped controls, including the default-template Label with a transparent background overlaying a Button from #21384.

The fix preserves two important Windows behaviors:

  • ILayoutHandler continues using LayoutPanel's specialized background-based input transparency, so transparent layouts do not disable their interactive child tree.
  • Reusing a disconnected handler preserves the existing wrapper and its visual-tree position while replacing its stale child with the newly created platform view.

Framework reconnect creates and connects the replacement platform view unparented before mapper replay. The reconnect repair therefore only updates WrapperView.Child; it does not remove the platform view from arbitrary parent shapes or re-enter virtual SetupContainer() overrides that could duplicate subscriptions or one-time setup. Normal mapper replay restores Label/Image sizing and alignment after the child replacement.

Root Cause

The default template's implicit Label style supplies a transparent background, which causes LabelHandler to create a Windows WrapperView. The existing mapper disabled hit testing only on the inner TextBlock; the effective wrapper remained hit-testable and intercepted pointer input.

Tests

  • Windows Label device tests: 42 total, 40 passed, 0 failed, 2 skipped. Coverage includes initial state, runtime toggles, late wrapper creation, reconnect hit testing and mapped properties, the framework's unparented replacement-platform-view lifecycle, a wrapper moved to another attached Panel, and a detached wrapper.
  • Failure-first reconnect validation: temporarily removing the reconnect rebinding made all three reconnect-specific tests fail; restoring it made them pass.
  • Windows Layout device tests: 54/54 passed, covering both CascadeInputTransparent modes and confirming that the wrapper remains hit-testable for child interaction.
  • Windows Core tests: 1,980 passed, 0 failed, 111 skipped; the exact CI-reported Slider case and all 90 Slider tests passed locally.
  • Windows Appium test and HostApp builds completed with 0 warnings and 0 errors, and both Issue21384 tests are discovered. The reporter-faithful Label pointer test is skipped on MacCatalyst because InputTransparent has no effect on Windows #21384 and this fix are Windows-specific; the clipped transparent layout test remains cross-platform.
  • Local Appium execution remains blocked before interaction by WinAppDriver's invalid status response. The real Win32 SendInput harness below provides behavior-level evidence.

Empirical Windows Validation

Both recordings use the same AbsoluteLayout reproduction from #21384 and send five real Win32 mouse clicks to the overlaid button (SendInput, not UI Automation invoke).

Before — bug reproduced on parent commit f377ff1c5e: all five clicks are sent, but the click handler receives none and the visible counter remains at 0.

issue21384-before.mp4

After — fixed behavior: all five equivalent clicks reach the button and the visible counter advances from 0 to 5. The final production code was rerun with the same harness and again received 5/5 clicks.

issue21384-after.mp4

What NOT to Do

  • Do not update only the inner Windows platform view; a hit-testable WrapperView can still intercept input.
  • Do not disable the wrapper for ILayoutHandler; LayoutPanel intentionally preserves child interaction through its background-based mapper.
  • Do not re-enter virtual SetupContainer() during reconnect; derived handlers may repeat subscriptions or one-time side effects.
  • Do not add generalized parent-detachment logic for reconnect; the framework replacement platform view is unparented before mapper replay, and the surviving wrapper's parent must remain unchanged.

Issues Fixed

Fixes #21384

Reporter Validation

@owaits, once the build artifacts are available, could you please try them with your original reproduction and let us know whether this resolves the issue for you?

Propagate input transparency to Windows wrapper views while preserving layout child interaction and wrapper state during handler reconnects.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: efff66ab-5dc2-4538-a4ec-1f0c889bf739
Copilot AI lite review requested due to automatic review settings August 13, 2026 11:15
@github-actions

Copy link
Copy Markdown
Contributor

🚀 Dogfood this PR with:

⚠️ WARNING: Do not do this without first carefully reviewing the code of this PR to satisfy yourself it is safe.

curl -fsSL https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.sh | bash -s -- 37392

Or

  • Run remotely in PowerShell:
iex "& { $(irm https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.ps1) } 37392"

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).
There may be pipelines that require an authorized user to comment /azp run to run.

Copilot AI 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.

Pull request overview

This PR fixes a Windows-specific InputTransparent hit-testing gap by ensuring the Windows wrapper container (WrapperView) participates in input transparency updates, so wrapped controls (e.g., Label with transparent background) no longer intercept pointer input meant for underlying controls.

Changes:

  • Windows: propagate InputTransparent updates to the container wrapper (and handle reconnect scenarios by reassigning WrapperView.Child to the new platform view).
  • Add Windows device tests covering wrapper/container hit-testing behavior for Label and Windows layout behavior with CascadeInputTransparent.
  • Add an Appium regression test plus HostApp repro page for issue #21384.
Show a summary per file
File Description
src/Core/src/Handlers/View/ViewHandler.cs Updates container mapping + input-transparency propagation so Windows wrapper hit-testing tracks InputTransparent, while preserving layout handler behavior.
src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue21384.cs Adds an Appium regression test asserting the button click succeeds when overlaid by an InputTransparent label.
src/Controls/tests/TestCases.HostApp/Issues/Issue21384.cs Adds the HostApp repro page used by the Appium regression scenario.
src/Controls/tests/DeviceTests/Elements/Layout/LayoutTests.Windows.cs Adds a device test verifying layout container hit-testing and CascadeInputTransparent behavior remain correct on Windows.
src/Controls/tests/DeviceTests/Elements/Label/LabelTests.Windows.cs Adds device tests validating wrapper hit-testing tracks InputTransparent, including runtime changes and handler reconnect scenarios.

Review details

  • Files reviewed: 5/5 changed files
  • Comments generated: 1
  • Review effort level: Lite

Comment thread src/Controls/tests/TestCases.HostApp/Issues/Issue21384.cs Outdated
@kubaflo

This comment has been minimized.

@github-actions github-actions Bot added the s/agent-review-in-progress AI review is currently running for this PR label Aug 13, 2026

@MauiBot MauiBot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Expert Review — 2 findings

See inline comments for details.

Comment thread src/Core/src/Handlers/View/ViewHandler.cs Outdated
MauiBot

This comment was marked as outdated.

@MauiBot MauiBot added s/agent-changes-requested AI agent recommends changes - found a better alternative or issues s/agent-gate-passed AI verified tests catch the bug (fail without fix, pass with fix) s/agent-fix-win AI found a better alternative fix than the PR s/agent-reviewed PR was reviewed by AI agent workflow (full 4-phase review) and removed s/agent-review-in-progress AI review is currently running for this PR labels Aug 13, 2026
@kubaflo
kubaflo changed the base branch from main to inflight/current August 13, 2026 21:07

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

Could you please resolve conflicts?

### Description of Change
This pull request makes a minor update to the UI test pipeline
configuration

- Pipeline configuration simplification:
* Removed the **duplicate** code that set the `$deviceType` variable and
appended the `--skin` argument to the test command in
`eng/pipelines/common/ui-tests-steps.yml`.


The same code was already added at [line
133](https://github.com/dotnet/maui/blob/main/eng/pipelines/common/ui-tests-steps.yml#L133)
as part of [PR #33409](#33409).

The duplicate code was also added at [line
156](https://github.com/dotnet/maui/blob/main/eng/pipelines/common/ui-tests-steps.yml#L156)
as part of [PR #31631](#31631).
<!-- Please let the below note in for people that find this PR -->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

### Description of Change

This follow-up repairs the skill-evaluation failures exposed by #36799
and hardens the credentialed Vally evaluator so skill regressions,
infrastructure failures, incomplete trials, parser differences, and
reporting-side failures are classified accurately.

### Root Causes

- `try-fix-capabilities` could exceed its numeric threshold while
remaining red because Vally independently hard-fails execution errors
and incomplete trials. Aggregate score never overrides those vetoes.
- `pr-review-gh-auth` routed correctly, but its isolated fixture omitted
the phase-specific unauthenticated public-GitHub fallback required by
the grader.
- Later failures exposed evaluator defects rather than skill
regressions: PAT authentication did not prove model entitlement, model
discovery did not initially match Vally 0.12's effective execution plan,
matrix-only token offsets removed run-level rotation entropy, and
parallel legs amplified shared PAT contention.
- Run `31518503277` restored the synthetic target correctly, but one
agent deleted Vally's pre-existing untracked `try-fix/` input to force
an empty `git status`; Vally correctly treated that deletion as
workspace drift.
- Run `31524806025` completed every evaluation successfully, but a
transient GitHub API fetch failure occurred before the comment step
exported its already-computed verdict, making reporting red despite
green suites.
- Review found parser-semantic splits between Psych and Vally's pinned
`yaml@2.9.0`: duplicate keys could be first-wins in AST policy checks
but last-wins at runtime, while YAML merge keys/tags were interpreted
differently and could hide executable evaluator fields from trusted
validation.

### Changes

- Replaced unreliable operational probes with bounded fixtures while
preserving repeated trials, behavioral rubrics, strict thresholds, and
hard-veto semantics.
- Added the unauthenticated GitHub fallback fixture and deterministic
skill-invocation/tool-call graders.
- Upgraded to Vally 0.12 and made aggregation fail closed on execution
errors, incomplete/skipped stimuli, malformed output, invocation
failures, and missing mandatory coverage.
- Added trusted fixture preparation plus path, symlink, Git,
environment, executable, attachment, hook, settings, MCP, executor, and
repository-control isolation.
- Serialized matrix legs while retaining three trials per stimulus.
- Made model discovery use only executed `eval*.vally.yaml` specs and
Vally 0.12's effective executor and prompt-grader fields; implicit
prompt-grader fallbacks are rejected.
- Added model-aware PAT selection with run/rerun/matrix-distributed
rotation and exact sentinel probes through the pinned evaluator runtime;
reused it in the advisory soak.
- Clarified that `try-fix` must preserve every pre-existing untracked
path, including evaluator-loaded skill inputs. Trusted validation
enforces both the skill contract and restoration fixture instruction
while retaining `diff-empty` as the method-independent veto.
- Exported the authoritative evaluation verdict before PR-comment API
calls, added bounded API retries, and made comment publication advisory
so transient GitHub failures cannot erase or invert the commit status.
- Reduced soak workflow permissions to `contents: read` and made `/user`
transport failures explicit without exposing PATs.
- Made required-stimulus policy fail closed when a configured stimulus
is renamed or removed, and bound each fixture marker/ref to the YAML
stimulus that owns it so a correctly named decoy cannot satisfy the
policy.
- Parse each eval spec once and reject duplicate semantic mapping keys,
textual YAML merge keys, and normalized explicit merge tags recursively
before loading. This prevents Psych/Vally parser disagreement from
bypassing prompt, ref, repository-control, or executable-environment
validation.
- Limited frozen-worktree test detection to full immutable commit IDs;
ordinary explicit branch bases continue using authoritative PR file
metadata.
- Added deterministic regressions for model planning, PAT distribution
and transport errors, deleted evaluator controls, host-only XAML
invocation, evaluator-owned input preservation, required-stimulus
rename/decoy/parser bypasses, branch-versus-immutable test detection,
and reporting-side verdict preservation.

### Validation

Current head: `fd8f3d543e1a1eb90e8432a0cbae07a18b52dbdd`.

- Exact-head [Skill Validation run
31807806898](https://github.com/dotnet/maui/actions/runs/31807806898),
[`maui-pr` build
1553690](https://dev.azure.com/dnceng-public/public/_build/results?buildId=1553690),
Build Analysis, CLA, static checks, Pester, and the hermeticity gate are
green.
- All evaluated suites passed. Key suites: `try-fix-restore-protocol`
**1.00 / 1.00**, `try-fix-capabilities` **0.93 / 0.80**,
`pr-review-gh-auth` **1.00 / 0.80**, and
`verify-tests-fail-without-fix-capabilities` **0.94 / 0.87**.
- Local trusted evaluator/reporting harness: **70 tests, 306 assertions,
0 failures/errors/skips**.
- All **16** Vally specs pass strict lint with pinned
`@microsoft/vally-cli@0.12.0`.
- All **8** skill test directories pass trusted validation and resolve
the effective plan to `gpt-5.6-sol` plus `claude-opus-5`; non-eval
soak/hermeticity specs do not contaminate matrix selection.
- Ruby syntax, Bash syntax, ShellCheck, workflow YAML parsing, Pester
(**8 passed**), and `git diff --check` pass.
- Final whole-diff review found no high-confidence correctness or
security blockers; all review threads are resolved.
- `pull_request_target` executes trusted workflow/helper code from
default `main`; candidate selector/reporting helper behavior is
therefore covered deterministically here and becomes the credentialed
trusted path after merge.

### Issues Fixed

Follow-up to #36799.

---------

Co-authored-by: PureWeen <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Vally Fixture <vally-fixture@example.invalid>
Copilot-Session: b9f7de2c-86d7-47cd-8ac8-aeff57d0b0f3
Copilot-Session: 806beb89-5041-4c7b-bcbf-998d6fbab8dc
Keep reconnect rebinding scoped to the framework's fresh unparented platform view, cover moved and detached wrappers, and skip the Windows-specific pointer test on MacCatalyst.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: efff66ab-5dc2-4538-a4ec-1f0c889bf739
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: efff66ab-5dc2-4538-a4ec-1f0c889bf739
Copilot AI review requested due to automatic review settings August 18, 2026 14:55

Copilot AI 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.

Review details

  • Files reviewed: 6/6 changed files
  • Comments generated: 1
  • Review effort level: Lite

Comment thread src/Core/src/Handlers/View/ViewHandler.Windows.cs
@kubaflo

This comment has been minimized.

@github-actions github-actions Bot added the s/agent-review-in-progress AI review is currently running for this PR label Aug 18, 2026

@MauiBot MauiBot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Expert Review — 2 findings

See inline comments for details.

var inputTransparentLayout = new Grid
{
AutomationId = "InputTransparentLayout",
CascadeInputTransparent = true,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

🔍 AI-Generated Review (multi-model)

💡 [moderate] Regression Prevention and Test Coverage — The layout scenario in this repro uses CascadeInputTransparent = true with a non-interactive Label child, so the paired UI test InputTransparentClippedLayoutAllowsButtonClick cannot detect a regression of the new if (handler is ILayoutHandler) return; guard in MapInputTransparentToContainer. Removing that guard would set the layout wrapper's IsHitTestVisible to false, which only makes the overlay more transparent to input — the button underneath would still be clickable and the test would still pass. The scenario the guard actually protects is a layout with InputTransparent = true and CascadeInputTransparent = false containing an interactive child that must stay clickable; that is currently only asserted at the property level in LayoutTests.InputTransparentLayoutContainerRemainsHitTestVisible. Consider adding a second overlay here with CascadeInputTransparent = false and a Button child, plus a UI test that taps that inner button, so the guard has end-to-end coverage.

public void InputTransparentLabelAllowsButtonClick()
{
if (Device == TestDevice.Mac)
Assert.Ignore("Issue #21384 and its fix are Windows-specific.");

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

🔍 AI-Generated Review (multi-model)

💡 [minor] Cross-Platform Behavioral Consistency — This Mac skip is inconsistent with InputTransparentClippedLayoutAllowsButtonClick below, which runs on every device including Mac. If the stated rationale ("Issue #21384 and its fix are Windows-specific") holds, the layout test should be skipped on Mac too; if the label overlay scenario actually fails on MacCatalyst, that is a real behavioral divergence being masked by an unconditional Assert.Ignore with no linked follow-up issue. Please either drop the skip (the iOS/MacCatalyst container path already maps InputTransparent to the wrapper, so the scenario is expected to pass) or reference a tracking issue explaining the MacCatalyst failure.

@MauiBot MauiBot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

AI Review Summary

@jfversluis — new AI review results are available based on commit b283e44.

Gate Passed Confidence Unknown Platform Windows


🗂️ Review Sessions — click to expand
🚦 Gate — Test Before & After Fix

Gate Result: ✅ PASSED

Platform: WINDOWS · Base: main · Merge base: b28e21c0

✅ Fix verified — 2 test(s) reproduce the bug (FAIL without the fix → PASS with it). 1 test(s) pass in both states and are not bug-reproducing; under the "at least one test reproduces the bug and none regress" rule they don't block the gate.

Test Without Fix (expect FAIL) With Fix (expect PASS)
📱 LabelTests (ContainerHitTestingTracksInputTransparent, ContainerHitTestingUpdatesWhenInputTransparentChanges, ContainerCreatedAfterInputTransparentIsNotHitTestVisible, ContainerHitTestingIsRestoredWhenHandlerReconnects, ReconnectingContainerPreservesWrapperInDifferentPanel, ReconnectingContainerPreservesDetachedWrapper) Category=Label ✅ FAIL — 410s ✅ PASS — 320s
📱 LayoutTests (InputTransparentLayoutContainerRemainsHitTestVisible) Category=Layout ❌ PASS — 921s ✅ PASS — 309s
🖥️ Issue21384 Issue21384 ✅ FAIL — 542s ✅ PASS — 505s
🔴 Without fix — 📱 LabelTests (ContainerHitTestingTracksInputTransparent, ContainerHitTestingUpdatesWhenInputTransparentChanges, ContainerCreatedAfterInputTransparentIsNotHitTestVisible, ContainerHitTestingIsRestoredWhenHandlerReconnects, ReconnectingContainerPreservesWrapperInDifferentPanel, ReconnectingContainerPreservesDetachedWrapper): FAIL ✅ · 410s

(no coded error found; showing last 1200 chars)

ss the warning by specifying `x:SuppressXamlTrimWarnings=True` within the closest element. If not, the property path might be trimmed and will not be AOT compatible. [D:\a\1\s\src\Controls\src\Core\Controls.Core.csproj::TargetFramework=net10.0-windows10.0.19041.0]
Platform\Windows\TabbedPage\TabbedPageStyle.xaml(13,13): XamlCompiler warning WMC1510: Ensure the property path is trimming and AOT compatible by making use of 'Compiled Bindings (x:bind)' if possible or by specifying the 'x:DataType' directive with the respective binding data context and marking the type declaration with the 'WinRT.GeneratedBindableCustomProperty' attribute or the 'Microsoft.UI.Xaml.Data.Bindable' attribute. If you are unable to do either but can ensure the data type is attributed correctly, then you can also suppress the warning by specifying `x:SuppressXamlTrimWarnings=True` within the closest element. If not, the property path might be trimmed and will not be AOT compatible. [D:\a\1\s\src\Controls\src\Core\Controls.Core.csproj::TargetFramework=net10.0-windows10.0.19041.0]
    0 Error(s)
Time Elapsed 00:05:04.78
  Passed: 1
  Failed: 6
  Skipped: 0
  Total: 7
  Tests completed with exit code: 1
🟢 With fix — 📱 LabelTests (ContainerHitTestingTracksInputTransparent, ContainerHitTestingUpdatesWhenInputTransparentChanges, ContainerCreatedAfterInputTransparentIsNotHitTestVisible, ContainerHitTestingIsRestoredWhenHandlerReconnects, ReconnectingContainerPreservesWrapperInDifferentPanel, ReconnectingContainerPreservesDetachedWrapper): PASS ✅ · 320s

(no coded error found; showing last 1200 chars)

uppress the warning by specifying `x:SuppressXamlTrimWarnings=True` within the closest element. If not, the property path might be trimmed and will not be AOT compatible. [D:\a\1\s\src\Controls\src\Core\Controls.Core.csproj::TargetFramework=net10.0-windows10.0.19041.0]
Platform\Windows\TabbedPage\TabbedPageStyle.xaml(13,13): XamlCompiler warning WMC1510: Ensure the property path is trimming and AOT compatible by making use of 'Compiled Bindings (x:bind)' if possible or by specifying the 'x:DataType' directive with the respective binding data context and marking the type declaration with the 'WinRT.GeneratedBindableCustomProperty' attribute or the 'Microsoft.UI.Xaml.Data.Bindable' attribute. If you are unable to do either but can ensure the data type is attributed correctly, then you can also suppress the warning by specifying `x:SuppressXamlTrimWarnings=True` within the closest element. If not, the property path might be trimmed and will not be AOT compatible. [D:\a\1\s\src\Controls\src\Core\Controls.Core.csproj::TargetFramework=net10.0-windows10.0.19041.0]
    0 Error(s)
Time Elapsed 00:05:01.62
  Passed: 7
  Failed: 0
  Skipped: 0
  Total: 7
  Tests completed successfully
🔴 Without fix — 📱 LayoutTests (InputTransparentLayoutContainerRemainsHitTestVisible): PASS ❌ · 921s

(no coded error found; showing last 1200 chars)

uppress the warning by specifying `x:SuppressXamlTrimWarnings=True` within the closest element. If not, the property path might be trimmed and will not be AOT compatible. [D:\a\1\s\src\Controls\src\Core\Controls.Core.csproj::TargetFramework=net10.0-windows10.0.19041.0]
Platform\Windows\TabbedPage\TabbedPageStyle.xaml(13,13): XamlCompiler warning WMC1510: Ensure the property path is trimming and AOT compatible by making use of 'Compiled Bindings (x:bind)' if possible or by specifying the 'x:DataType' directive with the respective binding data context and marking the type declaration with the 'WinRT.GeneratedBindableCustomProperty' attribute or the 'Microsoft.UI.Xaml.Data.Bindable' attribute. If you are unable to do either but can ensure the data type is attributed correctly, then you can also suppress the warning by specifying `x:SuppressXamlTrimWarnings=True` within the closest element. If not, the property path might be trimmed and will not be AOT compatible. [D:\a\1\s\src\Controls\src\Core\Controls.Core.csproj::TargetFramework=net10.0-windows10.0.19041.0]
    0 Error(s)
Time Elapsed 00:04:48.83
  Passed: 2
  Failed: 0
  Skipped: 0
  Total: 2
  Tests completed successfully
🟢 With fix — 📱 LayoutTests (InputTransparentLayoutContainerRemainsHitTestVisible): PASS ✅ · 309s

(no coded error found; showing last 1200 chars)

uppress the warning by specifying `x:SuppressXamlTrimWarnings=True` within the closest element. If not, the property path might be trimmed and will not be AOT compatible. [D:\a\1\s\src\Controls\src\Core\Controls.Core.csproj::TargetFramework=net10.0-windows10.0.19041.0]
Platform\Windows\TabbedPage\TabbedPageStyle.xaml(13,13): XamlCompiler warning WMC1510: Ensure the property path is trimming and AOT compatible by making use of 'Compiled Bindings (x:bind)' if possible or by specifying the 'x:DataType' directive with the respective binding data context and marking the type declaration with the 'WinRT.GeneratedBindableCustomProperty' attribute or the 'Microsoft.UI.Xaml.Data.Bindable' attribute. If you are unable to do either but can ensure the data type is attributed correctly, then you can also suppress the warning by specifying `x:SuppressXamlTrimWarnings=True` within the closest element. If not, the property path might be trimmed and will not be AOT compatible. [D:\a\1\s\src\Controls\src\Core\Controls.Core.csproj::TargetFramework=net10.0-windows10.0.19041.0]
    0 Error(s)
Time Elapsed 00:04:52.68
  Passed: 2
  Failed: 0
  Skipped: 0
  Total: 2
  Tests completed successfully
🔴 Without fix — 🖥️ Issue21384: FAIL ✅ · 542s

Error-relevant lines (filtered from the build log):

     at Microsoft.Maui.TestCases.Tests.Issues.Issue21384.InputTransparentLabelAllowsButtonClick() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue21384.cs:line 25
🟢 With fix — 🖥️ Issue21384: PASS ✅ · 505s

(no coded error found; showing last 1200 chars)

\Controls.TestCases.WinUI.Tests\Debug\net10.0\Controls.TestCases.WinUI.Tests.dll
   NUnit3TestExecutor discovered 2 of 2 NUnit test cases using Current Discovery mode, Non-Explicit run
>>>>> 8/18/2026 4:55:44 PM FixtureSetup for Issue21384(Windows)
>>>>> 8/18/2026 4:55:52 PM InputTransparentClippedLayoutAllowsButtonClick Start
>>>>> 8/18/2026 4:55:54 PM InputTransparentClippedLayoutAllowsButtonClick Stop
  Passed InputTransparentClippedLayoutAllowsButtonClick [1 s]
>>>>> 8/18/2026 4:55:54 PM InputTransparentLabelAllowsButtonClick Start
>>>>> 8/18/2026 4:55:55 PM InputTransparentLabelAllowsButtonClick Stop
  Passed InputTransparentLabelAllowsButtonClick [1 s]
NUnit Adapter 4.5.0.0: Test execution complete
[xUnit.net 00:00:00.00] xUnit.net VSTest Adapter v2.8.2+699d445a1a (64-bit .NET 10.0.0)
[xUnit.net 00:00:00.10]   Discovering: Controls.TestCases.WinUI.Tests
[xUnit.net 00:00:00.36]   Discovered:  Controls.TestCases.WinUI.Tests
Results File: D:\a\1\s\CustomAgentLogsTmp\UITests\TestResults\Issue21384.trx
Test Run Successful.
Total tests: 2
     Passed: 2
 Total time: 22.2795 Seconds
>>> TRX_RESULT_FILE: D:\a\1\s\CustomAgentLogsTmp\UITests\TestResults\Issue21384.trx

⚠️ Failure Details

  • ❌ LayoutTests (InputTransparentLayoutContainerRemainsHitTestVisible) PASSED without fix (should fail) — tests don't catch the bug
📁 Fix files reverted (2 files)
  • src/Core/src/Handlers/View/ViewHandler.Windows.cs
  • src/Core/src/Handlers/View/ViewHandler.cs

📋 Pre-Flight — Context & Validation

PR #37392 Pre-Flight

Context

  • Title: [Windows] InputTransparent: Respect wrapper view hit testing
  • Issue: #21384, InputTransparent has no effect on Windows
  • Platform: Windows
  • Base: origin/main (b28e21c0cb)
  • Materialized PR commit: 017bc8dd96
  • Gate: Passed before STEP 5a; do not rerun failure-without-fix verification and do not modify gate/content.md.

The reported reproduction overlays an InputTransparent=true Label on a
Button. On Windows, a transparent background makes the label handler create a
WrapperView. Disabling hit testing only on the inner TextBlock leaves the
wrapper hit-testable, so it intercepts the pointer instead of allowing the
button underneath to receive it.

Existing PR Approach

The PR extends container input-transparency mapping to Windows. It updates the
WrapperView for non-layout handlers while preserving ILayoutHandler's
specialized LayoutPanel behavior so transparent layouts do not disable their
interactive descendants. It also adds ReconnectContainer() to rebind a
preserved wrapper to a replacement platform view when a disconnected handler is
reused.

Production files in the PR:

  • src/Core/src/Handlers/View/ViewHandler.cs
  • src/Core/src/Handlers/View/ViewHandler.Windows.cs

Test files in the PR:

  • src/Controls/tests/DeviceTests/Elements/Label/LabelTests.Windows.cs
  • src/Controls/tests/DeviceTests/Elements/Layout/LayoutTests.Windows.cs
  • src/Controls/tests/TestCases.HostApp/Issues/Issue21384.cs
  • src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue21384.cs

Alternative candidates must not merely restate the PR's mechanism: propagating
InputTransparent to every non-layout wrapper plus explicitly rebinding
WrapperView.Child during reconnect.

Bounded Verification

Use this single targeted command; do not run a full class, project, or repository
test suite:

pwsh .github/skills/run-device-tests/scripts/Run-DeviceTests.ps1 -Project Controls -Platform windows -IncludeClasses "Microsoft.Maui.DeviceTests.LabelTests,Microsoft.Maui.DeviceTests.LayoutTests" -IncludeMethods "ContainerHitTestingTracksInputTransparent,ContainerHitTestingUpdatesWhenInputTransparentChanges,ContainerCreatedAfterInputTransparentIsNotHitTestVisible,ContainerHitTestingIsRestoredWhenHandlerReconnects,ReconnectingContainerPreservesWrapperInDifferentPanel,ReconnectingContainerPreservesDetachedWrapper,InputTransparentLayoutContainerRemainsHitTestVisible"

The primary regression is
ContainerHitTestingTracksInputTransparent. The remaining listed methods are
the mandatory focused regressions for runtime updates, late wrapper creation,
handler reconnect, wrapper parent preservation, detached wrappers, and layout
child hit testing.

Each candidate gets one implementation/test pass and no more than one focused
correction/retest. The baseline script's RevertedFiles list is the strict edit
allow-list. Restore only with
pwsh .github/scripts/EstablishBrokenBaseline.ps1 -Restore.


🔬 Code Review — Deep Analysis

Expert PR Evaluation

Verdict: LGTM with two non-blocking test-coverage suggestions.

The submitted production fix is sound. It propagates InputTransparent to non-layout Windows wrappers, preserves ILayoutHandler's child-interaction semantics, and safely rebinds a retained WrapperView to the newly created unparented platform view during handler reuse. The reconnect ordering preserves the wrapper's visual-tree position and avoids re-entering derived SetupContainer() overrides. The Gate passed, including failure-first Label and Issue21384 coverage, and the regression-risk scan is clean.

The expert reviewer identified no production correctness, lifecycle, threading, API, or regression-blocking defects. It recommended strengthening end-to-end coverage for the ILayoutHandler carve-out with an interactive child under CascadeInputTransparent = false, and resolving the MacCatalyst-only skip inconsistency in the Label UI test. Both findings are suggestions rather than blockers and are recorded in inline-findings.json.


🛠️ Try-Fix — Analysis & Comparison

Try-Fix Aggregate — PR #37392

Candidates executed: 2 (candidate 1 — Blocked; candidate 2 — Blocked).


Candidate 1 — PR #37392 ([Windows] InputTransparent: Respect wrapper view hit testing)

Result: Blocked (environment blocker at try-fix Step 2 — broken baseline could not be established)

Artifacts: CustomAgentLogsTmp/PRState/37392/PRAgent/try-fix/attempt-1/
(baseline.log, approach.md, reviewer-findings.json, reviewer-findings.diff, result.txt, fix.diff,
test-output.log, analysis.md, restore.log).

1. Approach designed (not applied)

"Container mirrors its child" — two coordinated changes, both confined to the PR-owned production files
src/Core/src/Handlers/View/ViewHandler.cs and src/Core/src/Handlers/View/ViewHandler.Windows.cs:

  1. Hit-testing is mirrored, not re-derived.
    ViewHandler.Windows.cs gains
    static void UpdateContainerHitTesting(IViewHandler handler) →
    if (handler.ContainerView is WrapperView wrapper && handler.PlatformView is UIElement pv) wrapper.IsHitTestVisible = pv.IsHitTestVisible;
    It is invoked from MapInputTransparent (Windows branch, immediately after the platform view's own
    UpdateInputTransparent) and from MapContainerView (so a wrapper created later — e.g. the moment a transparent
    background first forces one — picks up the child's current state).

  2. The container re-adopts on platform-view identity change.
    ViewHandler.cs declares partial void ConnectedHandler(PlatformView platformView); and calls it from the sealed
    OnConnectHandler(object) after OnConnectHandler((PlatformView)platformView) returns.
    ViewHandler.Windows.cs implements it: if ContainerView is WrapperView wrapper and wrapper.Child is not the
    newly connected platform view, wrapper.Child = platformView.

2. Mechanism-level difference from the existing PR

The PR (017bc8dd96) treats the WrapperView as a second, independent InputTransparent policy target: it
extends MapInputTransparentToContainer to Windows so the wrapper re-derives IsHitTestVisible from
view.InputTransparent, which then forces an if (handler is ILayoutHandler) return; carve-out, because
LayoutPanel expresses input transparency through its background brush and must stay hit-test visible so its
children remain interactive. Separately, it repairs the stale reconnect binding from inside the ContainerView
property mapper via ReconnectContainer(), gated on the hasContainerOldValue heuristic.

This candidate starts from a different root-cause hypothesis: the wrapper is a passthrough decoration and must
have no input policy of its own — it must reflect whatever hit-testability its child ended up with.
The full
cause-to-effect chain:

  • ViewExtensions.UpdateInputTransparent(this FrameworkElement, IViewHandler, IView) already sets
    IsHitTestVisible = !view.InputTransparent on the platform view. For non-layout views this is exactly the
    desired container state, so mirroring reproduces it without re-reading view.InputTransparent.
  • LayoutHandler.Windows.MapInputTransparent replaces the IView.InputTransparent mapping for layouts and only
    calls UpdatePlatformViewBackground, so LayoutPanel.IsHitTestVisible is never set to false. Mirroring
    therefore yields wrapper.IsHitTestVisible == true for transparent layouts automatically — the
    ILayoutHandler type check disappears entirely, and any future handler with bespoke input semantics is correct by
    construction instead of needing a new exception.
  • The stale-child defect is attributed to platform-view identity change, not to container property mapping.
    ViewHandler<T,U>.SetupContainer() (Windows) early-returns when ContainerView is not null, so a reused handler's
    preserved wrapper keeps a dead Child. Adopting at connect completion means the wrapper hosts the live child
    before any mapper runs, so every subsequent mapper (visibility, opacity, clip, shadow, hit-testing) observes a
    consistent wrapper→child tree, and no hasContainerOldValue gate is needed. The insertion point is deliberately
    after OnConnectHandler(PlatformView) so a handler's own ConnectHandler still sees an unparented platform view
    (required by ContainerHitTestingIsRestoredWhenHandlerReconnects's ConnectedPlatformViewsWereUnparented
    assertion; adopting in the pre-existing ConnectingHandler partial would fail it).

This is a different mechanism, not a relocation: policy-mirroring replaces policy-duplication-plus-exception, and
lifecycle-driven adoption replaces mapper-driven repair.

3. Files changed

None. No file was modified. git status --porcelain --untracked-files=no -- src/ returns zero entries.

4. Captured diff

fix.diff and reviewer-findings.diff are both 0 bytes (empty diff) — captured before restoration, not
reconstructed afterwards.

(empty)

5. Test command and result

Command (never executed):

pwsh .github/skills/run-device-tests/scripts/Run-DeviceTests.ps1 -Project Controls -Platform windows -IncludeClasses "Microsoft.Maui.DeviceTests.LabelTests,Microsoft.Maui.DeviceTests.LayoutTests" -IncludeMethods "ContainerHitTestingTracksInputTransparent,ContainerHitTestingUpdatesWhenInputTransparentChanges,ContainerCreatedAfterInputTransparentIsNotHitTestVisible,ContainerHitTestingIsRestoredWhenHandlerReconnects,ReconnectingContainerPreservesWrapperInDifferentPanel,ReconnectingContainerPreservesDetachedWrapper,InputTransparentLayoutContainerRemainsHitTestVisible"

Result: not run — result.txt = Blocked. test-output.log records the command and the reason it was skipped.

6. Self-review

0 findings (reviewer-findings.json = []). There is no diff to review; the empty array is the correct output
and is consistent with the empty reviewer-findings.diff snapshot. The designed change was still walked against the
always-active dimensions (Logic and Correctness, Regression Prevention, Complexity Reduction) at design time — no
concrete failing scenario was identified for the design itself; the ordering hazard that was identified
(adoption must not run inside ConnectingHandler) is already resolved in the design.

7. Failure analysis (why Blocked)

pwsh .github/scripts/EstablishBrokenBaseline.ps1 aborted at its repo-wide fail-fast cleanliness check
(line 372, git status --porcelain --untracked-files=no). 44 tracked files under .github/ and eng/ were already
modified or deleted before this attempt began — pre-existing harness/user state that the invocation explicitly
forbids editing, restoring, staging, deleting, or otherwise altering; committing is prohibited too. The script offers
only -BaseBranch, -DryRun, and -Restore, so there is no scoping or override that avoids touching that state.

Because the script never ran, .github/.baseline-state.json was never created. Under the skill's baseline-file
boundary that means there is no RevertedFiles allow-list, so no file — including the two intended targets — was
editable. Editing them regardless would also have stacked the alternative on top of the PR fix still present at
HEAD (017bc8dd96) rather than replacing it, yielding a meaningless comparison, and could not have been undone
with the only permitted restore command.

Unblock options: (a) the owner commits or reverts the 44 harness .github/eng modifications before the
attempt, or (b) EstablishBrokenBaseline.ps1 scopes its cleanliness check to the detected fix files / src/, or
gains an ignore list for harness-owned paths.

8. Restoration

pwsh .github/scripts/EstablishBrokenBaseline.ps1 -Restore was run and reported
No baseline state found / Restored False — the accepted no-state outcome, since baseline state was never created
and no attempt edits were made. Verified afterwards: git status --porcelain --untracked-files=no -- src/ is empty.
Pre-existing untracked and harness-owned dirty paths were left exactly as found.


Candidate 2 — PR #37392 ([Windows] InputTransparent: Respect wrapper view hit testing)

Result: Blocked (environment blocker at try-fix Step 2 — broken baseline could not be established)

Artifacts: CustomAgentLogsTmp/PRState/37392/PRAgent/try-fix/attempt-2/ (baseline.log, approach.md, reviewer-findings.json, reviewer-findings.diff, result.txt, fix.diff, test-output.log, and analysis.md).

1. Approach designed (not applied)

“Remove the wrapper's hit-test surface and rebuild containers atomically.” The candidate attributes interception to the WinUI wrapper's transparent decoration surface, not to a missing second copy of InputTransparent. For pointer-transparent non-layout views it would remove the wrapper's hit-test-producing background/local decoration surface, leaving input policy on the inner platform view. For reconnects it would run the existing container state machine through a full remove/setup transition at the original visual-tree slot, allowing normal setup to establish the replacement platform view relationship rather than assigning WrapperView.Child directly.

The design was not applied because no baseline edit allow-list was created. It also records a validation risk: the mandatory tests assert WrapperView.IsHitTestVisible == false, same-wrapper identity, and a new platform-view identity. Those structural expectations may reject this non-propagation/reconstruction mechanism even if pointer pass-through works; that question could not be tested while baseline establishment was blocked.

2. Explicit distinction from the PR and candidate 1

The PR treats the wrapper as a second input-policy target: it propagates InputTransparent to non-layout wrappers, excludes ILayoutHandler, and explicitly rebinds WrapperView.Child during container mapping on reconnect. This candidate does not assign input transparency or IsHitTestVisible to the wrapper; it removes the native surface that participates in hit testing. It does not repair a preserved wrapper by assigning its child; it asks the normal remove/setup state machine to reconstruct a consistent container relationship.

Candidate 1 proposed mirroring PlatformView.IsHitTestVisible onto WrapperView.IsHitTestVisible and re-adopting the replacement platform view from a connect-completion partial hook. This candidate neither mirrors wrapper/child hit-test state nor introduces any connect-completion partial. Its cause-to-effect chain is different: without a wrapper decoration hit-test surface, the disabled inner platform view has no hit-testable outer surface that can swallow input; an atomic container state transition prevents stale native relationships by construction rather than correcting one after connection.

3. Files changed

None. Baseline creation failed before .github/.baseline-state.json existed, so neither target file was editable. After restoration, git status --porcelain --untracked-files=no -- src/Core/src/Handlers/View/ViewHandler.cs src/Core/src/Handlers/View/ViewHandler.Windows.cs produced no entries.

4. Exact saved diff

fix.diff and reviewer-findings.diff are both 0 bytes:

(empty)

5. Test command and result

The only permitted behavior-validation command was:

pwsh .github/skills/run-device-tests/scripts/Run-DeviceTests.ps1 -Project Controls -Platform windows -IncludeClasses "Microsoft.Maui.DeviceTests.LabelTests,Microsoft.Maui.DeviceTests.LayoutTests" -IncludeMethods "ContainerHitTestingTracksInputTransparent,ContainerHitTestingUpdatesWhenInputTransparentChanges,ContainerCreatedAfterInputTransparentIsNotHitTestVisible,ContainerHitTestingIsRestoredWhenHandlerReconnects,ReconnectingContainerPreservesWrapperInDifferentPanel,ReconnectingContainerPreservesDetachedWrapper,InputTransparentLayoutContainerRemainsHitTestVisible"

Not run. test-output.log records that validation was skipped because the baseline failed before implementation. result.txt contains Blocked.

6. Inline expert self-review

0 findings (reviewer-findings.json is []). With no code diff, reviewer-findings.diff is correctly empty. The no-diff review covered all eight overarching principles, routed handler dimensions, Windows platform scoping, and the always-active Logic and Correctness, Regression Prevention, and Complexity Reduction dimensions. The design/test-contract concern above was documented as analysis, not fabricated as a line-level finding without a changed line.

7. Failure analysis

pwsh .github/scripts/EstablishBrokenBaseline.ps1 failed its repository-wide cleanliness guard because pre-existing harness/user modifications and deletions remain under .github and eng. Those paths were not touched. The script did not create .github/.baseline-state.json; therefore the skill's RevertedFiles allow-list did not exist and editing either permitted candidate file would have violated the baseline boundary, stacked a candidate on the PR instead of the broken baseline, and left no script-restorable state.

No workaround, stash, alternate index, index flag, temporary commit, worktree, external search, build, or test was used. The gate content was not touched.

8. Restoration

The exact required command was run:

pwsh .github/scripts/EstablishBrokenBaseline.ps1 -Restore

It reported No baseline state found / Restored False, the expected no-state result because baseline creation failed and no production edit was made. Pre-existing harness/user state was preserved.


🏁 Report — Final Recommendation

⚠️ Final Recommendation: REQUEST CHANGES

Winner: pr-plus-reviewer

pr-plus-reviewer is the strongest candidate because it keeps the submitted production fix unchanged while closing both test-coverage gaps identified by the one expert review. Its required Windows regression validation passed all 9 selected cases from the mandated candidate worktree, and its patch passed git diff --check.

Candidate Comparison

Rank Candidate Implementation and evidence Assessment
1 pr-plus-reviewer Same production fix as the PR, plus end-to-end coverage for an interactive child under CascadeInputTransparent = false and consistent MacCatalyst execution of the Label UI test. Required targeted validation: 9 passed, 0 failed. Best coverage without increasing production risk. The bounded validation did not execute the changed Appium tests, so their runtime result remains an explicit uncertainty.
2 pr Gate passed: the Label and Issue21384 regressions fail without the fix and pass with it. Expert review found no blocking production, lifecycle, threading, API, or regression defect; regression-risk scan was clean. Production approach is sound and mergeable on its own, but two useful coverage gaps remain.
3 try-fix-1 Proposed mirroring the platform view's hit-test state to the wrapper and reconnecting from a new connect-completion hook. No diff was produced and no regression test ran because baseline establishment was blocked. Interesting design, but unimplemented and unvalidated; it cannot outrank passing candidates.
4 try-fix-2 Proposed removing the wrapper hit-test surface and rebuilding containers through the normal state machine. No diff was produced and no regression test ran because baseline establishment was blocked. Unimplemented and unvalidated, with acknowledged risk of violating required wrapper identity and reconnect behavior.

Expert Evaluation

The production change correctly:

  • propagates Windows InputTransparent state to non-layout WrapperView instances;
  • preserves ILayoutHandler's background-based child-interaction behavior;
  • rebinds a retained wrapper to a freshly created, unparented platform view during handler reuse;
  • preserves wrapper identity, visual-tree position, and derived-handler mapper replay without re-entering SetupContainer().

The expert reviewer reported only two suggestion-level findings, both addressed by pr-plus-reviewer. No candidate failed regression validation; the two try-fix alternatives were blocked before implementation and therefore rank below both passing PR-based candidates.

Required Change

Apply the pr-plus-reviewer test-only patch before merge. Because the winning changes are not present in the submitted PR HEAD, the recommendation is REQUEST CHANGES despite the raw production fix being sound.


📱 UI Tests — InputTransparent,ViewBaseTests

Detected UI test categories: InputTransparent,ViewBaseTests

[!WARNING]
No UI test results were produced for the detected categories. The PR build itself was
fine — the deep UI stage was skipped or interrupted on infrastructure (the
merge-for-testing step, emulator/simulator boot, or an Appium hang), not by this PR's code.
This is usually transient; the review re-runs on new commits (a maintainer can also re-run it).


🧭 Next Steps — reviewer patch required (pr-plus-reviewer)

The reviewer-enhanced candidate won, so the submitted PR still needs those changes.

Why: The candidate preserves the expert-approved production fix and adds end-to-end coverage for the ILayoutHandler guard while removing an inconsistent MacCatalyst skip. Its required Windows regression validation passed 9/9, whereas both try-fix alternatives were blocked without code or test evidence.

Apply PRAgent/pr-plus-reviewer/reviewer.patch from the CopilotLogs
artifact (or follow the report's Required submitted-PR change), push the update, and run
the review again.

@MauiBot MauiBot added s/agent-fix-win AI found a better alternative fix than the PR and removed s/agent-fix-pr-picked AI could not beat the PR fix - PR is the best among all candidates s/agent-review-in-progress AI review is currently running for this PR labels Aug 18, 2026
@kubaflo

kubaflo commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 3 pipeline(s).

@kubaflo
kubaflo changed the base branch from main to inflight/current August 18, 2026 22:42
Resolve the LabelTests.Windows.cs conflict by retaining both the InputTransparent reconnect coverage and the formatted-text regression test.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 590f6f02-a472-4961-b6a5-9b3d0839c4b3
@kubaflo
kubaflo merged commit e59cf97 into inflight/current Aug 18, 2026
8 of 17 checks passed
@kubaflo
kubaflo deleted the jfversluis-fix-inputtransparent-windows branch August 18, 2026 22:55
@github-actions github-actions Bot added this to the .NET 10 SR11 milestone Aug 18, 2026
kubaflo added a commit that referenced this pull request Aug 27, 2026
<!-- Please let the below note in for people that find this PR -->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

On Windows, propagate `InputTransparent` to a view's `WrapperView` as
well as its inner platform view. This allows pointer input to pass
through wrapped controls, including the default-template `Label` with a
transparent background overlaying a `Button` from #21384.

The fix preserves two important Windows behaviors:

- `ILayoutHandler` continues using `LayoutPanel`'s specialized
background-based input transparency, so transparent layouts do not
disable their interactive child tree.
- Reusing a disconnected handler preserves the existing wrapper and its
visual-tree position while replacing its stale child with the newly
created platform view.

Framework reconnect creates and connects the replacement platform view
unparented before mapper replay. The reconnect repair therefore only
updates `WrapperView.Child`; it does not remove the platform view from
arbitrary parent shapes or re-enter virtual `SetupContainer()` overrides
that could duplicate subscriptions or one-time setup. Normal mapper
replay restores Label/Image sizing and alignment after the child
replacement.

The default template's implicit `Label` style supplies a transparent
background, which causes `LabelHandler` to create a Windows
`WrapperView`. The existing mapper disabled hit testing only on the
inner `TextBlock`; the effective wrapper remained hit-testable and
intercepted pointer input.

- Windows Label device tests: **42 total, 40 passed, 0 failed, 2
skipped**. Coverage includes initial state, runtime toggles, late
wrapper creation, reconnect hit testing and mapped properties, the
framework's unparented replacement-platform-view lifecycle, a wrapper
moved to another attached `Panel`, and a detached wrapper.
- Failure-first reconnect validation: temporarily removing the reconnect
rebinding made all three reconnect-specific tests fail; restoring it
made them pass.
- Windows Layout device tests: **54/54 passed**, covering both
`CascadeInputTransparent` modes and confirming that the wrapper remains
hit-testable for child interaction.
- Windows Core tests: **1,980 passed, 0 failed, 111 skipped**; the exact
CI-reported Slider case and all 90 Slider tests passed locally.
- Windows Appium test and HostApp builds completed with **0 warnings and
0 errors**, and both Issue21384 tests are discovered. The
reporter-faithful Label pointer test is skipped on MacCatalyst because
test remains cross-platform.
- Local Appium execution remains blocked before interaction by
WinAppDriver's invalid status response. The real Win32 `SendInput`
harness below provides behavior-level evidence.

Both recordings use the same `AbsoluteLayout` reproduction from #21384
and send five real Win32 mouse clicks to the overlaid button
(`SendInput`, not UI Automation invoke).

**Before — bug reproduced on parent commit `f377ff1c5e`:** all five
clicks are sent, but the click handler receives none and the visible
counter remains at 0.

https://github.com/user-attachments/assets/d59d3346-355c-434f-b1ac-01c76c361ab1

**After — fixed behavior:** all five equivalent clicks reach the button
and the visible counter advances from 0 to 5. The final production code
was rerun with the same harness and again received **5/5** clicks.

https://github.com/user-attachments/assets/610856db-c094-4657-b4ea-0985b96221dd

- Do not update only the inner Windows platform view; a hit-testable
`WrapperView` can still intercept input.
- Do not disable the wrapper for `ILayoutHandler`; `LayoutPanel`
intentionally preserves child interaction through its background-based
mapper.
- Do not re-enter virtual `SetupContainer()` during reconnect; derived
handlers may repeat subscriptions or one-time side effects.
- Do not add generalized parent-detachment logic for reconnect; the
framework replacement platform view is unparented before mapper replay,
and the surviving wrapper's parent must remain unchanged.

Fixes #21384

@owaits, once the build artifacts are available, could you please try
them with your original reproduction and let us know whether this
resolves the issue for you?

---------

Co-authored-by: Jakub Florkowski <42434498+kubaflo@users.noreply.github.com>
kubaflo added a commit that referenced this pull request Sep 2, 2026
<!-- Please let the below note in for people that find this PR -->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

On Windows, propagate `InputTransparent` to a view's `WrapperView` as
well as its inner platform view. This allows pointer input to pass
through wrapped controls, including the default-template `Label` with a
transparent background overlaying a `Button` from #21384.

The fix preserves two important Windows behaviors:

- `ILayoutHandler` continues using `LayoutPanel`'s specialized
background-based input transparency, so transparent layouts do not
disable their interactive child tree.
- Reusing a disconnected handler preserves the existing wrapper and its
visual-tree position while replacing its stale child with the newly
created platform view.

Framework reconnect creates and connects the replacement platform view
unparented before mapper replay. The reconnect repair therefore only
updates `WrapperView.Child`; it does not remove the platform view from
arbitrary parent shapes or re-enter virtual `SetupContainer()` overrides
that could duplicate subscriptions or one-time setup. Normal mapper
replay restores Label/Image sizing and alignment after the child
replacement.

The default template's implicit `Label` style supplies a transparent
background, which causes `LabelHandler` to create a Windows
`WrapperView`. The existing mapper disabled hit testing only on the
inner `TextBlock`; the effective wrapper remained hit-testable and
intercepted pointer input.

- Windows Label device tests: **42 total, 40 passed, 0 failed, 2
skipped**. Coverage includes initial state, runtime toggles, late
wrapper creation, reconnect hit testing and mapped properties, the
framework's unparented replacement-platform-view lifecycle, a wrapper
moved to another attached `Panel`, and a detached wrapper.
- Failure-first reconnect validation: temporarily removing the reconnect
rebinding made all three reconnect-specific tests fail; restoring it
made them pass.
- Windows Layout device tests: **54/54 passed**, covering both
`CascadeInputTransparent` modes and confirming that the wrapper remains
hit-testable for child interaction.
- Windows Core tests: **1,980 passed, 0 failed, 111 skipped**; the exact
CI-reported Slider case and all 90 Slider tests passed locally.
- Windows Appium test and HostApp builds completed with **0 warnings and
0 errors**, and both Issue21384 tests are discovered. The
reporter-faithful Label pointer test is skipped on MacCatalyst because
test remains cross-platform.
- Local Appium execution remains blocked before interaction by
WinAppDriver's invalid status response. The real Win32 `SendInput`
harness below provides behavior-level evidence.

Both recordings use the same `AbsoluteLayout` reproduction from #21384
and send five real Win32 mouse clicks to the overlaid button
(`SendInput`, not UI Automation invoke).

**Before — bug reproduced on parent commit `f377ff1c5e`:** all five
clicks are sent, but the click handler receives none and the visible
counter remains at 0.

https://github.com/user-attachments/assets/d59d3346-355c-434f-b1ac-01c76c361ab1

**After — fixed behavior:** all five equivalent clicks reach the button
and the visible counter advances from 0 to 5. The final production code
was rerun with the same harness and again received **5/5** clicks.

https://github.com/user-attachments/assets/610856db-c094-4657-b4ea-0985b96221dd

- Do not update only the inner Windows platform view; a hit-testable
`WrapperView` can still intercept input.
- Do not disable the wrapper for `ILayoutHandler`; `LayoutPanel`
intentionally preserves child interaction through its background-based
mapper.
- Do not re-enter virtual `SetupContainer()` during reconnect; derived
handlers may repeat subscriptions or one-time side effects.
- Do not add generalized parent-detachment logic for reconnect; the
framework replacement platform view is unparented before mapper replay,
and the surviving wrapper's parent must remain unchanged.

Fixes #21384

@owaits, once the build artifacts are available, could you please try
them with your original reproduction and let us know whether this
resolves the issue for you?

---------

Co-authored-by: Jakub Florkowski <42434498+kubaflo@users.noreply.github.com>
kubaflo added a commit that referenced this pull request Sep 3, 2026
<!-- Please let the below note in for people that find this PR -->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

On Windows, propagate `InputTransparent` to a view's `WrapperView` as
well as its inner platform view. This allows pointer input to pass
through wrapped controls, including the default-template `Label` with a
transparent background overlaying a `Button` from #21384.

The fix preserves two important Windows behaviors:

- `ILayoutHandler` continues using `LayoutPanel`'s specialized
background-based input transparency, so transparent layouts do not
disable their interactive child tree.
- Reusing a disconnected handler preserves the existing wrapper and its
visual-tree position while replacing its stale child with the newly
created platform view.

Framework reconnect creates and connects the replacement platform view
unparented before mapper replay. The reconnect repair therefore only
updates `WrapperView.Child`; it does not remove the platform view from
arbitrary parent shapes or re-enter virtual `SetupContainer()` overrides
that could duplicate subscriptions or one-time setup. Normal mapper
replay restores Label/Image sizing and alignment after the child
replacement.

The default template's implicit `Label` style supplies a transparent
background, which causes `LabelHandler` to create a Windows
`WrapperView`. The existing mapper disabled hit testing only on the
inner `TextBlock`; the effective wrapper remained hit-testable and
intercepted pointer input.

- Windows Label device tests: **42 total, 40 passed, 0 failed, 2
skipped**. Coverage includes initial state, runtime toggles, late
wrapper creation, reconnect hit testing and mapped properties, the
framework's unparented replacement-platform-view lifecycle, a wrapper
moved to another attached `Panel`, and a detached wrapper.
- Failure-first reconnect validation: temporarily removing the reconnect
rebinding made all three reconnect-specific tests fail; restoring it
made them pass.
- Windows Layout device tests: **54/54 passed**, covering both
`CascadeInputTransparent` modes and confirming that the wrapper remains
hit-testable for child interaction.
- Windows Core tests: **1,980 passed, 0 failed, 111 skipped**; the exact
CI-reported Slider case and all 90 Slider tests passed locally.
- Windows Appium test and HostApp builds completed with **0 warnings and
0 errors**, and both Issue21384 tests are discovered. The
reporter-faithful Label pointer test is skipped on MacCatalyst because
test remains cross-platform.
- Local Appium execution remains blocked before interaction by
WinAppDriver's invalid status response. The real Win32 `SendInput`
harness below provides behavior-level evidence.

Both recordings use the same `AbsoluteLayout` reproduction from #21384
and send five real Win32 mouse clicks to the overlaid button
(`SendInput`, not UI Automation invoke).

**Before — bug reproduced on parent commit `f377ff1c5e`:** all five
clicks are sent, but the click handler receives none and the visible
counter remains at 0.

https://github.com/user-attachments/assets/d59d3346-355c-434f-b1ac-01c76c361ab1

**After — fixed behavior:** all five equivalent clicks reach the button
and the visible counter advances from 0 to 5. The final production code
was rerun with the same harness and again received **5/5** clicks.

https://github.com/user-attachments/assets/610856db-c094-4657-b4ea-0985b96221dd

- Do not update only the inner Windows platform view; a hit-testable
`WrapperView` can still intercept input.
- Do not disable the wrapper for `ILayoutHandler`; `LayoutPanel`
intentionally preserves child interaction through its background-based
mapper.
- Do not re-enter virtual `SetupContainer()` during reconnect; derived
handlers may repeat subscriptions or one-time side effects.
- Do not add generalized parent-detachment logic for reconnect; the
framework replacement platform view is unparented before mapper replay,
and the surviving wrapper's parent must remain unchanged.

Fixes #21384

@owaits, once the build artifacts are available, could you please try
them with your original reproduction and let us know whether this
resolves the issue for you?

---------

Co-authored-by: Jakub Florkowski <42434498+kubaflo@users.noreply.github.com>
kubaflo added a commit that referenced this pull request Sep 6, 2026
<!-- Please let the below note in for people that find this PR -->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

On Windows, propagate `InputTransparent` to a view's `WrapperView` as
well as its inner platform view. This allows pointer input to pass
through wrapped controls, including the default-template `Label` with a
transparent background overlaying a `Button` from #21384.

The fix preserves two important Windows behaviors:

- `ILayoutHandler` continues using `LayoutPanel`'s specialized
background-based input transparency, so transparent layouts do not
disable their interactive child tree.
- Reusing a disconnected handler preserves the existing wrapper and its
visual-tree position while replacing its stale child with the newly
created platform view.

Framework reconnect creates and connects the replacement platform view
unparented before mapper replay. The reconnect repair therefore only
updates `WrapperView.Child`; it does not remove the platform view from
arbitrary parent shapes or re-enter virtual `SetupContainer()` overrides
that could duplicate subscriptions or one-time setup. Normal mapper
replay restores Label/Image sizing and alignment after the child
replacement.

The default template's implicit `Label` style supplies a transparent
background, which causes `LabelHandler` to create a Windows
`WrapperView`. The existing mapper disabled hit testing only on the
inner `TextBlock`; the effective wrapper remained hit-testable and
intercepted pointer input.

- Windows Label device tests: **42 total, 40 passed, 0 failed, 2
skipped**. Coverage includes initial state, runtime toggles, late
wrapper creation, reconnect hit testing and mapped properties, the
framework's unparented replacement-platform-view lifecycle, a wrapper
moved to another attached `Panel`, and a detached wrapper.
- Failure-first reconnect validation: temporarily removing the reconnect
rebinding made all three reconnect-specific tests fail; restoring it
made them pass.
- Windows Layout device tests: **54/54 passed**, covering both
`CascadeInputTransparent` modes and confirming that the wrapper remains
hit-testable for child interaction.
- Windows Core tests: **1,980 passed, 0 failed, 111 skipped**; the exact
CI-reported Slider case and all 90 Slider tests passed locally.
- Windows Appium test and HostApp builds completed with **0 warnings and
0 errors**, and both Issue21384 tests are discovered. The
reporter-faithful Label pointer test is skipped on MacCatalyst because
test remains cross-platform.
- Local Appium execution remains blocked before interaction by
WinAppDriver's invalid status response. The real Win32 `SendInput`
harness below provides behavior-level evidence.

Both recordings use the same `AbsoluteLayout` reproduction from #21384
and send five real Win32 mouse clicks to the overlaid button
(`SendInput`, not UI Automation invoke).

**Before — bug reproduced on parent commit `f377ff1c5e`:** all five
clicks are sent, but the click handler receives none and the visible
counter remains at 0.

https://github.com/user-attachments/assets/d59d3346-355c-434f-b1ac-01c76c361ab1

**After — fixed behavior:** all five equivalent clicks reach the button
and the visible counter advances from 0 to 5. The final production code
was rerun with the same harness and again received **5/5** clicks.

https://github.com/user-attachments/assets/610856db-c094-4657-b4ea-0985b96221dd

- Do not update only the inner Windows platform view; a hit-testable
`WrapperView` can still intercept input.
- Do not disable the wrapper for `ILayoutHandler`; `LayoutPanel`
intentionally preserves child interaction through its background-based
mapper.
- Do not re-enter virtual `SetupContainer()` during reconnect; derived
handlers may repeat subscriptions or one-time side effects.
- Do not add generalized parent-detachment logic for reconnect; the
framework replacement platform view is unparented before mapper replay,
and the surviving wrapper's parent must remain unchanged.

Fixes #21384

@owaits, once the build artifacts are available, could you please try
them with your original reproduction and let us know whether this
resolves the issue for you?

---------

Co-authored-by: Jakub Florkowski <42434498+kubaflo@users.noreply.github.com>
kubaflo added a commit that referenced this pull request Sep 7, 2026
<!-- Please let the below note in for people that find this PR -->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

On Windows, propagate `InputTransparent` to a view's `WrapperView` as
well as its inner platform view. This allows pointer input to pass
through wrapped controls, including the default-template `Label` with a
transparent background overlaying a `Button` from #21384.

The fix preserves two important Windows behaviors:

- `ILayoutHandler` continues using `LayoutPanel`'s specialized
background-based input transparency, so transparent layouts do not
disable their interactive child tree.
- Reusing a disconnected handler preserves the existing wrapper and its
visual-tree position while replacing its stale child with the newly
created platform view.

Framework reconnect creates and connects the replacement platform view
unparented before mapper replay. The reconnect repair therefore only
updates `WrapperView.Child`; it does not remove the platform view from
arbitrary parent shapes or re-enter virtual `SetupContainer()` overrides
that could duplicate subscriptions or one-time setup. Normal mapper
replay restores Label/Image sizing and alignment after the child
replacement.

The default template's implicit `Label` style supplies a transparent
background, which causes `LabelHandler` to create a Windows
`WrapperView`. The existing mapper disabled hit testing only on the
inner `TextBlock`; the effective wrapper remained hit-testable and
intercepted pointer input.

- Windows Label device tests: **42 total, 40 passed, 0 failed, 2
skipped**. Coverage includes initial state, runtime toggles, late
wrapper creation, reconnect hit testing and mapped properties, the
framework's unparented replacement-platform-view lifecycle, a wrapper
moved to another attached `Panel`, and a detached wrapper.
- Failure-first reconnect validation: temporarily removing the reconnect
rebinding made all three reconnect-specific tests fail; restoring it
made them pass.
- Windows Layout device tests: **54/54 passed**, covering both
`CascadeInputTransparent` modes and confirming that the wrapper remains
hit-testable for child interaction.
- Windows Core tests: **1,980 passed, 0 failed, 111 skipped**; the exact
CI-reported Slider case and all 90 Slider tests passed locally.
- Windows Appium test and HostApp builds completed with **0 warnings and
0 errors**, and both Issue21384 tests are discovered. The
reporter-faithful Label pointer test is skipped on MacCatalyst because
test remains cross-platform.
- Local Appium execution remains blocked before interaction by
WinAppDriver's invalid status response. The real Win32 `SendInput`
harness below provides behavior-level evidence.

Both recordings use the same `AbsoluteLayout` reproduction from #21384
and send five real Win32 mouse clicks to the overlaid button
(`SendInput`, not UI Automation invoke).

**Before — bug reproduced on parent commit `f377ff1c5e`:** all five
clicks are sent, but the click handler receives none and the visible
counter remains at 0.

https://github.com/user-attachments/assets/d59d3346-355c-434f-b1ac-01c76c361ab1

**After — fixed behavior:** all five equivalent clicks reach the button
and the visible counter advances from 0 to 5. The final production code
was rerun with the same harness and again received **5/5** clicks.

https://github.com/user-attachments/assets/610856db-c094-4657-b4ea-0985b96221dd

- Do not update only the inner Windows platform view; a hit-testable
`WrapperView` can still intercept input.
- Do not disable the wrapper for `ILayoutHandler`; `LayoutPanel`
intentionally preserves child interaction through its background-based
mapper.
- Do not re-enter virtual `SetupContainer()` during reconnect; derived
handlers may repeat subscriptions or one-time side effects.
- Do not add generalized parent-detachment logic for reconnect; the
framework replacement platform view is unparented before mapper replay,
and the surviving wrapper's parent must remain unchanged.

Fixes #21384

@owaits, once the build artifacts are available, could you please try
them with your original reproduction and let us know whether this
resolves the issue for you?

---------

Co-authored-by: Jakub Florkowski <42434498+kubaflo@users.noreply.github.com>
kubaflo added a commit that referenced this pull request Sep 8, 2026
<!-- Please let the below note in for people that find this PR -->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

On Windows, propagate `InputTransparent` to a view's `WrapperView` as
well as its inner platform view. This allows pointer input to pass
through wrapped controls, including the default-template `Label` with a
transparent background overlaying a `Button` from #21384.

The fix preserves two important Windows behaviors:

- `ILayoutHandler` continues using `LayoutPanel`'s specialized
background-based input transparency, so transparent layouts do not
disable their interactive child tree.
- Reusing a disconnected handler preserves the existing wrapper and its
visual-tree position while replacing its stale child with the newly
created platform view.

Framework reconnect creates and connects the replacement platform view
unparented before mapper replay. The reconnect repair therefore only
updates `WrapperView.Child`; it does not remove the platform view from
arbitrary parent shapes or re-enter virtual `SetupContainer()` overrides
that could duplicate subscriptions or one-time setup. Normal mapper
replay restores Label/Image sizing and alignment after the child
replacement.

The default template's implicit `Label` style supplies a transparent
background, which causes `LabelHandler` to create a Windows
`WrapperView`. The existing mapper disabled hit testing only on the
inner `TextBlock`; the effective wrapper remained hit-testable and
intercepted pointer input.

- Windows Label device tests: **42 total, 40 passed, 0 failed, 2
skipped**. Coverage includes initial state, runtime toggles, late
wrapper creation, reconnect hit testing and mapped properties, the
framework's unparented replacement-platform-view lifecycle, a wrapper
moved to another attached `Panel`, and a detached wrapper.
- Failure-first reconnect validation: temporarily removing the reconnect
rebinding made all three reconnect-specific tests fail; restoring it
made them pass.
- Windows Layout device tests: **54/54 passed**, covering both
`CascadeInputTransparent` modes and confirming that the wrapper remains
hit-testable for child interaction.
- Windows Core tests: **1,980 passed, 0 failed, 111 skipped**; the exact
CI-reported Slider case and all 90 Slider tests passed locally.
- Windows Appium test and HostApp builds completed with **0 warnings and
0 errors**, and both Issue21384 tests are discovered. The
reporter-faithful Label pointer test is skipped on MacCatalyst because
test remains cross-platform.
- Local Appium execution remains blocked before interaction by
WinAppDriver's invalid status response. The real Win32 `SendInput`
harness below provides behavior-level evidence.

Both recordings use the same `AbsoluteLayout` reproduction from #21384
and send five real Win32 mouse clicks to the overlaid button
(`SendInput`, not UI Automation invoke).

**Before — bug reproduced on parent commit `f377ff1c5e`:** all five
clicks are sent, but the click handler receives none and the visible
counter remains at 0.

https://github.com/user-attachments/assets/d59d3346-355c-434f-b1ac-01c76c361ab1

**After — fixed behavior:** all five equivalent clicks reach the button
and the visible counter advances from 0 to 5. The final production code
was rerun with the same harness and again received **5/5** clicks.

https://github.com/user-attachments/assets/610856db-c094-4657-b4ea-0985b96221dd

- Do not update only the inner Windows platform view; a hit-testable
`WrapperView` can still intercept input.
- Do not disable the wrapper for `ILayoutHandler`; `LayoutPanel`
intentionally preserves child interaction through its background-based
mapper.
- Do not re-enter virtual `SetupContainer()` during reconnect; derived
handlers may repeat subscriptions or one-time side effects.
- Do not add generalized parent-detachment logic for reconnect; the
framework replacement platform view is unparented before mapper replay,
and the surviving wrapper's parent must remain unchanged.

Fixes #21384

@owaits, once the build artifacts are available, could you please try
them with your original reproduction and let us know whether this
resolves the issue for you?

---------

Co-authored-by: Jakub Florkowski <42434498+kubaflo@users.noreply.github.com>
kubaflo added a commit that referenced this pull request Sep 9, 2026
<!-- Please let the below note in for people that find this PR -->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

On Windows, propagate `InputTransparent` to a view's `WrapperView` as
well as its inner platform view. This allows pointer input to pass
through wrapped controls, including the default-template `Label` with a
transparent background overlaying a `Button` from #21384.

The fix preserves two important Windows behaviors:

- `ILayoutHandler` continues using `LayoutPanel`'s specialized
background-based input transparency, so transparent layouts do not
disable their interactive child tree.
- Reusing a disconnected handler preserves the existing wrapper and its
visual-tree position while replacing its stale child with the newly
created platform view.

Framework reconnect creates and connects the replacement platform view
unparented before mapper replay. The reconnect repair therefore only
updates `WrapperView.Child`; it does not remove the platform view from
arbitrary parent shapes or re-enter virtual `SetupContainer()` overrides
that could duplicate subscriptions or one-time setup. Normal mapper
replay restores Label/Image sizing and alignment after the child
replacement.

The default template's implicit `Label` style supplies a transparent
background, which causes `LabelHandler` to create a Windows
`WrapperView`. The existing mapper disabled hit testing only on the
inner `TextBlock`; the effective wrapper remained hit-testable and
intercepted pointer input.

- Windows Label device tests: **42 total, 40 passed, 0 failed, 2
skipped**. Coverage includes initial state, runtime toggles, late
wrapper creation, reconnect hit testing and mapped properties, the
framework's unparented replacement-platform-view lifecycle, a wrapper
moved to another attached `Panel`, and a detached wrapper.
- Failure-first reconnect validation: temporarily removing the reconnect
rebinding made all three reconnect-specific tests fail; restoring it
made them pass.
- Windows Layout device tests: **54/54 passed**, covering both
`CascadeInputTransparent` modes and confirming that the wrapper remains
hit-testable for child interaction.
- Windows Core tests: **1,980 passed, 0 failed, 111 skipped**; the exact
CI-reported Slider case and all 90 Slider tests passed locally.
- Windows Appium test and HostApp builds completed with **0 warnings and
0 errors**, and both Issue21384 tests are discovered. The
reporter-faithful Label pointer test is skipped on MacCatalyst because
test remains cross-platform.
- Local Appium execution remains blocked before interaction by
WinAppDriver's invalid status response. The real Win32 `SendInput`
harness below provides behavior-level evidence.

Both recordings use the same `AbsoluteLayout` reproduction from #21384
and send five real Win32 mouse clicks to the overlaid button
(`SendInput`, not UI Automation invoke).

**Before — bug reproduced on parent commit `f377ff1c5e`:** all five
clicks are sent, but the click handler receives none and the visible
counter remains at 0.

https://github.com/user-attachments/assets/d59d3346-355c-434f-b1ac-01c76c361ab1

**After — fixed behavior:** all five equivalent clicks reach the button
and the visible counter advances from 0 to 5. The final production code
was rerun with the same harness and again received **5/5** clicks.

https://github.com/user-attachments/assets/610856db-c094-4657-b4ea-0985b96221dd

- Do not update only the inner Windows platform view; a hit-testable
`WrapperView` can still intercept input.
- Do not disable the wrapper for `ILayoutHandler`; `LayoutPanel`
intentionally preserves child interaction through its background-based
mapper.
- Do not re-enter virtual `SetupContainer()` during reconnect; derived
handlers may repeat subscriptions or one-time side effects.
- Do not add generalized parent-detachment logic for reconnect; the
framework replacement platform view is unparented before mapper replay,
and the surviving wrapper's parent must remain unchanged.

Fixes #21384

@owaits, once the build artifacts are available, could you please try
them with your original reproduction and let us know whether this
resolves the issue for you?

---------

Co-authored-by: Jakub Florkowski <42434498+kubaflo@users.noreply.github.com>
kubaflo added a commit that referenced this pull request Sep 11, 2026
<!-- Please let the below note in for people that find this PR -->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

On Windows, propagate `InputTransparent` to a view's `WrapperView` as
well as its inner platform view. This allows pointer input to pass
through wrapped controls, including the default-template `Label` with a
transparent background overlaying a `Button` from #21384.

The fix preserves two important Windows behaviors:

- `ILayoutHandler` continues using `LayoutPanel`'s specialized
background-based input transparency, so transparent layouts do not
disable their interactive child tree.
- Reusing a disconnected handler preserves the existing wrapper and its
visual-tree position while replacing its stale child with the newly
created platform view.

Framework reconnect creates and connects the replacement platform view
unparented before mapper replay. The reconnect repair therefore only
updates `WrapperView.Child`; it does not remove the platform view from
arbitrary parent shapes or re-enter virtual `SetupContainer()` overrides
that could duplicate subscriptions or one-time setup. Normal mapper
replay restores Label/Image sizing and alignment after the child
replacement.

The default template's implicit `Label` style supplies a transparent
background, which causes `LabelHandler` to create a Windows
`WrapperView`. The existing mapper disabled hit testing only on the
inner `TextBlock`; the effective wrapper remained hit-testable and
intercepted pointer input.

- Windows Label device tests: **42 total, 40 passed, 0 failed, 2
skipped**. Coverage includes initial state, runtime toggles, late
wrapper creation, reconnect hit testing and mapped properties, the
framework's unparented replacement-platform-view lifecycle, a wrapper
moved to another attached `Panel`, and a detached wrapper.
- Failure-first reconnect validation: temporarily removing the reconnect
rebinding made all three reconnect-specific tests fail; restoring it
made them pass.
- Windows Layout device tests: **54/54 passed**, covering both
`CascadeInputTransparent` modes and confirming that the wrapper remains
hit-testable for child interaction.
- Windows Core tests: **1,980 passed, 0 failed, 111 skipped**; the exact
CI-reported Slider case and all 90 Slider tests passed locally.
- Windows Appium test and HostApp builds completed with **0 warnings and
0 errors**, and both Issue21384 tests are discovered. The
reporter-faithful Label pointer test is skipped on MacCatalyst because
test remains cross-platform.
- Local Appium execution remains blocked before interaction by
WinAppDriver's invalid status response. The real Win32 `SendInput`
harness below provides behavior-level evidence.

Both recordings use the same `AbsoluteLayout` reproduction from #21384
and send five real Win32 mouse clicks to the overlaid button
(`SendInput`, not UI Automation invoke).

**Before — bug reproduced on parent commit `f377ff1c5e`:** all five
clicks are sent, but the click handler receives none and the visible
counter remains at 0.

https://github.com/user-attachments/assets/d59d3346-355c-434f-b1ac-01c76c361ab1

**After — fixed behavior:** all five equivalent clicks reach the button
and the visible counter advances from 0 to 5. The final production code
was rerun with the same harness and again received **5/5** clicks.

https://github.com/user-attachments/assets/610856db-c094-4657-b4ea-0985b96221dd

- Do not update only the inner Windows platform view; a hit-testable
`WrapperView` can still intercept input.
- Do not disable the wrapper for `ILayoutHandler`; `LayoutPanel`
intentionally preserves child interaction through its background-based
mapper.
- Do not re-enter virtual `SetupContainer()` during reconnect; derived
handlers may repeat subscriptions or one-time side effects.
- Do not add generalized parent-detachment logic for reconnect; the
framework replacement platform view is unparented before mapper replay,
and the surviving wrapper's parent must remain unchanged.

Fixes #21384

@owaits, once the build artifacts are available, could you please try
them with your original reproduction and let us know whether this
resolves the issue for you?

---------

Co-authored-by: Jakub Florkowski <42434498+kubaflo@users.noreply.github.com>
kubaflo added a commit that referenced this pull request Sep 15, 2026
<!-- Please let the below note in for people that find this PR -->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

On Windows, propagate `InputTransparent` to a view's `WrapperView` as
well as its inner platform view. This allows pointer input to pass
through wrapped controls, including the default-template `Label` with a
transparent background overlaying a `Button` from #21384.

The fix preserves two important Windows behaviors:

- `ILayoutHandler` continues using `LayoutPanel`'s specialized
background-based input transparency, so transparent layouts do not
disable their interactive child tree.
- Reusing a disconnected handler preserves the existing wrapper and its
visual-tree position while replacing its stale child with the newly
created platform view.

Framework reconnect creates and connects the replacement platform view
unparented before mapper replay. The reconnect repair therefore only
updates `WrapperView.Child`; it does not remove the platform view from
arbitrary parent shapes or re-enter virtual `SetupContainer()` overrides
that could duplicate subscriptions or one-time setup. Normal mapper
replay restores Label/Image sizing and alignment after the child
replacement.

The default template's implicit `Label` style supplies a transparent
background, which causes `LabelHandler` to create a Windows
`WrapperView`. The existing mapper disabled hit testing only on the
inner `TextBlock`; the effective wrapper remained hit-testable and
intercepted pointer input.

- Windows Label device tests: **42 total, 40 passed, 0 failed, 2
skipped**. Coverage includes initial state, runtime toggles, late
wrapper creation, reconnect hit testing and mapped properties, the
framework's unparented replacement-platform-view lifecycle, a wrapper
moved to another attached `Panel`, and a detached wrapper.
- Failure-first reconnect validation: temporarily removing the reconnect
rebinding made all three reconnect-specific tests fail; restoring it
made them pass.
- Windows Layout device tests: **54/54 passed**, covering both
`CascadeInputTransparent` modes and confirming that the wrapper remains
hit-testable for child interaction.
- Windows Core tests: **1,980 passed, 0 failed, 111 skipped**; the exact
CI-reported Slider case and all 90 Slider tests passed locally.
- Windows Appium test and HostApp builds completed with **0 warnings and
0 errors**, and both Issue21384 tests are discovered. The
reporter-faithful Label pointer test is skipped on MacCatalyst because
test remains cross-platform.
- Local Appium execution remains blocked before interaction by
WinAppDriver's invalid status response. The real Win32 `SendInput`
harness below provides behavior-level evidence.

Both recordings use the same `AbsoluteLayout` reproduction from #21384
and send five real Win32 mouse clicks to the overlaid button
(`SendInput`, not UI Automation invoke).

**Before — bug reproduced on parent commit `f377ff1c5e`:** all five
clicks are sent, but the click handler receives none and the visible
counter remains at 0.

https://github.com/user-attachments/assets/d59d3346-355c-434f-b1ac-01c76c361ab1

**After — fixed behavior:** all five equivalent clicks reach the button
and the visible counter advances from 0 to 5. The final production code
was rerun with the same harness and again received **5/5** clicks.

https://github.com/user-attachments/assets/610856db-c094-4657-b4ea-0985b96221dd

- Do not update only the inner Windows platform view; a hit-testable
`WrapperView` can still intercept input.
- Do not disable the wrapper for `ILayoutHandler`; `LayoutPanel`
intentionally preserves child interaction through its background-based
mapper.
- Do not re-enter virtual `SetupContainer()` during reconnect; derived
handlers may repeat subscriptions or one-time side effects.
- Do not add generalized parent-detachment logic for reconnect; the
framework replacement platform view is unparented before mapper replay,
and the surviving wrapper's parent must remain unchanged.

Fixes #21384

@owaits, once the build artifacts are available, could you please try
them with your original reproduction and let us know whether this
resolves the issue for you?

---------

Co-authored-by: Jakub Florkowski <42434498+kubaflo@users.noreply.github.com>
@github-actions github-actions Bot locked and limited conversation to collaborators Sep 18, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

s/agent-changes-requested AI agent recommends changes - found a better alternative or issues s/agent-fix-win AI found a better alternative fix than the PR s/agent-gate-passed AI verified tests catch the bug (fail without fix, pass with fix) s/agent-reviewed PR was reviewed by AI agent workflow (full 4-phase review)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

InputTransparent has no effect on Windows

7 participants