[Windows] Fix SearchHandler does not focus when ShowSoftInputAsync is called#35079
Conversation
|
🚀 Dogfood this PR with:
curl -fsSL https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.sh | bash -s -- 35079Or
iex "& { $(irm https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.ps1) } 35079" |
There was a problem hiding this comment.
Pull request overview
Adds Windows support for SearchHandler.ShowSoftInputAsync() / HideSoftInputAsync() by wiring the corresponding internal events in the Windows ShellItemHandler, and introduces a UI test + HostApp repro page to validate focus behavior.
Changes:
- Subscribe/unsubscribe to
ShowSoftInputRequested/HideSoftInputRequestedinShellItemHandler.Windows.csand implement focus/unfocus behavior via theAutoSuggestBox. - Add HostApp issue page
Issue34930with buttons and labels to exercise/observe focus behavior. - Add Appium/NUnit UI test
Issue34930to validate focus occurs after invokingShowSoftInputAsync().
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 8 comments.
| File | Description |
|---|---|
| src/Controls/src/Core/Handlers/Shell/ShellItemHandler.Windows.cs | Wires ShowSoftInputRequested/HideSoftInputRequested to focus/unfocus the underlying AutoSuggestBox on Windows. |
| src/Controls/tests/TestCases.HostApp/Issues/Issue34930.cs | Adds a HostApp repro page that triggers Show/Hide soft-input requests and displays focus state. |
| src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue34930.cs | Adds a UI test which taps the button and asserts focus state/event indicators. |
kubaflo
left a comment
There was a problem hiding this comment.
Could you please review the ai's summary and verify the failing tests?
kubaflo
left a comment
There was a problem hiding this comment.
Could you please check the ai's summary?
|
/azp run maui-pr-uitests , maui-pr-devicetests |
|
Azure Pipelines successfully started running 2 pipeline(s). |
kubaflo
left a comment
There was a problem hiding this comment.
Android tests are failing - could you please check?
|
/review -b feature/regression-check -p windows |
1 similar comment
|
/review -b feature/regression-check -p windows |
🤖 AI Summary
📊 Review Session —
|
| Test | Without Fix (expect FAIL) | With Fix (expect PASS) |
|---|---|---|
🖥️ Issue34930 Issue34930 |
✅ FAIL — 620s | ✅ PASS — 475s |
🔴 Without fix — 🖥️ Issue34930: FAIL ✅ · 620s
Determining projects to restore...
Restored D:\a\1\s\src\Graphics\src\Graphics\Graphics.csproj (in 23.84 sec).
Restored D:\a\1\s\src\Graphics\src\Graphics.Win2D\Graphics.Win2D.csproj (in 24.28 sec).
Restored D:\a\1\s\src\Essentials\src\Essentials.csproj (in 8.22 sec).
Restored D:\a\1\s\src\Core\src\Core.csproj (in 15.1 sec).
Restored D:\a\1\s\src\Controls\tests\TestCases.HostApp\Controls.TestCases.HostApp.csproj (in 6.56 sec).
Restored D:\a\1\s\src\Core\maps\src\Maps.csproj (in 13.99 sec).
Restored D:\a\1\s\src\Controls\src\Xaml\Controls.Xaml.csproj (in 36 ms).
Restored D:\a\1\s\src\Controls\src\Core\Controls.Core.csproj (in 21 ms).
Restored D:\a\1\s\src\Controls\Maps\src\Controls.Maps.csproj (in 15 ms).
Restored D:\a\1\s\src\Controls\Foldable\src\Controls.Foldable.csproj (in 11 ms).
Restored D:\a\1\s\src\BlazorWebView\src\Maui\Microsoft.AspNetCore.Components.WebView.Maui.csproj (in 78 ms).
3 of 14 projects are up-to-date for restore.
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14158622
Graphics -> D:\a\1\s\artifacts\bin\Graphics\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Graphics.dll
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14158622
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14158622
Essentials -> D:\a\1\s\artifacts\bin\Essentials\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Essentials.dll
Graphics.Win2D -> D:\a\1\s\artifacts\bin\Graphics.Win2D\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Graphics.Win2D.WinUI.Desktop.dll
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14158622
Core -> D:\a\1\s\artifacts\bin\Core\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.dll
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14158622
Maps -> D:\a\1\s\artifacts\bin\Maps\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Maps.dll
Controls.BindingSourceGen -> D:\a\1\s\artifacts\bin\Controls.BindingSourceGen\Debug\netstandard2.0\Microsoft.Maui.Controls.BindingSourceGen.dll
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14158622
Controls.Core -> D:\a\1\s\artifacts\bin\Controls.Core\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Controls.dll
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14158622
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14158622
Controls.Maps -> D:\a\1\s\artifacts\bin\Controls.Maps\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Controls.Maps.dll
Microsoft.AspNetCore.Components.WebView.Maui -> D:\a\1\s\artifacts\bin\Microsoft.AspNetCore.Components.WebView.Maui\Debug\net10.0-windows10.0.19041.0\Microsoft.AspNetCore.Components.WebView.Maui.dll
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14158622
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14158622
Controls.Xaml -> D:\a\1\s\artifacts\bin\Controls.Xaml\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Controls.Xaml.dll
Controls.Foldable -> D:\a\1\s\artifacts\bin\Controls.Foldable\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Controls.Foldable.dll
Controls.TestCases.HostApp -> D:\a\1\s\artifacts\bin\Controls.TestCases.HostApp\Debug\net10.0-windows10.0.19041.0\win-x64\Controls.TestCases.HostApp.dll
Build succeeded.
0 Warning(s)
0 Error(s)
Time Elapsed 00:06:03.95
Determining projects to restore...
Restored D:\a\1\s\src\TestUtils\src\VisualTestUtils\VisualTestUtils.csproj (in 1.01 sec).
Restored D:\a\1\s\src\TestUtils\src\UITest.NUnit\UITest.NUnit.csproj (in 2.5 sec).
Restored D:\a\1\s\src\TestUtils\src\UITest.Core\UITest.Core.csproj (in 3 ms).
Restored D:\a\1\s\src\TestUtils\src\VisualTestUtils.MagickNet\VisualTestUtils.MagickNet.csproj (in 4.65 sec).
Restored D:\a\1\s\src\TestUtils\src\UITest.Appium\UITest.Appium.csproj (in 1.96 sec).
Restored D:\a\1\s\src\Controls\tests\TestCases.WinUI.Tests\Controls.TestCases.WinUI.Tests.csproj (in 6.11 sec).
Restored D:\a\1\s\src\Controls\tests\CustomAttributes\Controls.CustomAttributes.csproj (in 21 ms).
Restored D:\a\1\s\src\TestUtils\src\UITest.Analyzers\UITest.Analyzers.csproj (in 10.14 sec).
7 of 15 projects are up-to-date for restore.
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14158622
Graphics -> D:\a\1\s\artifacts\bin\Graphics\Debug\net10.0\Microsoft.Maui.Graphics.dll
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14158622
Essentials -> D:\a\1\s\artifacts\bin\Essentials\Debug\net10.0\Microsoft.Maui.Essentials.dll
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14158622
Controls.CustomAttributes -> D:\a\1\s\artifacts\bin\Controls.CustomAttributes\Debug\net10.0\Controls.CustomAttributes.dll
Core -> D:\a\1\s\artifacts\bin\Core\Debug\net10.0\Microsoft.Maui.dll
Controls.Core.Design -> D:\a\1\s\artifacts\bin\Controls.Core.Design\Debug\net472\Microsoft.Maui.Controls.DesignTools.dll
Controls.BindingSourceGen -> D:\a\1\s\artifacts\bin\Controls.BindingSourceGen\Debug\netstandard2.0\Microsoft.Maui.Controls.BindingSourceGen.dll
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14158622
Controls.Core -> D:\a\1\s\artifacts\bin\Controls.Core\Debug\net10.0\Microsoft.Maui.Controls.dll
UITest.Core -> D:\a\1\s\artifacts\bin\UITest.Core\Debug\net10.0\UITest.Core.dll
UITest.Appium -> D:\a\1\s\artifacts\bin\UITest.Appium\Debug\net10.0\UITest.Appium.dll
UITest.NUnit -> D:\a\1\s\artifacts\bin\UITest.NUnit\Debug\net10.0\UITest.NUnit.dll
VisualTestUtils -> D:\a\1\s\artifacts\bin\VisualTestUtils\Debug\netstandard2.0\VisualTestUtils.dll
VisualTestUtils.MagickNet -> D:\a\1\s\artifacts\bin\VisualTestUtils.MagickNet\Debug\netstandard2.0\VisualTestUtils.MagickNet.dll
UITest.Analyzers -> D:\a\1\s\artifacts\bin\UITest.Analyzers\Debug\netstandard2.0\UITest.Analyzers.dll
Controls.TestCases.WinUI.Tests -> D:\a\1\s\artifacts\bin\Controls.TestCases.WinUI.Tests\Debug\net10.0\Controls.TestCases.WinUI.Tests.dll
Test run for D:\a\1\s\artifacts\bin\Controls.TestCases.WinUI.Tests\Debug\net10.0\Controls.TestCases.WinUI.Tests.dll (.NETCoreApp,Version=v10.0)
VSTest version 18.0.1 (x64)
Starting test execution, please wait...
A total of 1 test files matched the specified pattern.
D:\a\1\s\artifacts\bin\Controls.TestCases.WinUI.Tests\Debug\net10.0\Controls.TestCases.WinUI.Tests.dll
NUnit Adapter 4.5.0.0: Test execution started
Running selected tests in D:\a\1\s\artifacts\bin\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
>>>>> 5/21/2026 11:10:57 AM FixtureSetup for Issue34930(Windows)
>>>>> 5/21/2026 11:11:07 AM SearchHandlerHideSoftInputShouldUnfocusSearchHandlerOnWindows Start
>>>>> 5/21/2026 11:11:25 AM SearchHandlerHideSoftInputShouldUnfocusSearchHandlerOnWindows Stop
Passed SearchHandlerHideSoftInputShouldUnfocusSearchHandlerOnWindows [18 s]
>>>>> 5/21/2026 11:11:25 AM SearchHandlerShowSoftInputShouldFocusSearchHandlerOnWindows Start
>>>>> 5/21/2026 11:11:42 AM SearchHandlerShowSoftInputShouldFocusSearchHandlerOnWindows Stop
>>>>> 5/21/2026 11:11:43 AM Log types:
Failed SearchHandlerShowSoftInputShouldFocusSearchHandlerOnWindows [18 s]
Error Message:
Assert.That(isFocused, Is.EqualTo("IsFocused: True"))
Expected string length 15 but was 16. Strings differ at index 11.
Expected: "IsFocused: True"
But was: "IsFocused: False"
----------------------^
Stack Trace:
at Microsoft.Maui.TestCases.Tests.Issues.Issue34930.SearchHandlerShowSoftInputShouldFocusSearchHandlerOnWindows() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue34930.cs:line 24
1) at Microsoft.Maui.TestCases.Tests.Issues.Issue34930.SearchHandlerShowSoftInputShouldFocusSearchHandlerOnWindows() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue34930.cs:line 24
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.11] Discovering: Controls.TestCases.WinUI.Tests
[xUnit.net 00:00:00.33] Discovered: Controls.TestCases.WinUI.Tests
Total tests: 2
Passed: 1
Failed: 1
Test Run Failed.
Total time: 1.3320 Minutes
🟢 With fix — 🖥️ Issue34930: PASS ✅ · 475s
Determining projects to restore...
All projects are up-to-date for restore.
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14158622
Graphics -> D:\a\1\s\artifacts\bin\Graphics\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Graphics.dll
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14158622
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14158622
Essentials -> D:\a\1\s\artifacts\bin\Essentials\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Essentials.dll
Graphics.Win2D -> D:\a\1\s\artifacts\bin\Graphics.Win2D\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Graphics.Win2D.WinUI.Desktop.dll
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14158622
Core -> D:\a\1\s\artifacts\bin\Core\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.dll
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14158622
Maps -> D:\a\1\s\artifacts\bin\Maps\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Maps.dll
Controls.BindingSourceGen -> D:\a\1\s\artifacts\bin\Controls.BindingSourceGen\Debug\netstandard2.0\Microsoft.Maui.Controls.BindingSourceGen.dll
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14158622
Controls.Core -> D:\a\1\s\artifacts\bin\Controls.Core\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Controls.dll
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14158622
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14158622
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14158622
Controls.Xaml -> D:\a\1\s\artifacts\bin\Controls.Xaml\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Controls.Xaml.dll
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14158622
Controls.Foldable -> D:\a\1\s\artifacts\bin\Controls.Foldable\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Controls.Foldable.dll
Microsoft.AspNetCore.Components.WebView.Maui -> D:\a\1\s\artifacts\bin\Microsoft.AspNetCore.Components.WebView.Maui\Debug\net10.0-windows10.0.19041.0\Microsoft.AspNetCore.Components.WebView.Maui.dll
Controls.Maps -> D:\a\1\s\artifacts\bin\Controls.Maps\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Controls.Maps.dll
Controls.TestCases.HostApp -> D:\a\1\s\artifacts\bin\Controls.TestCases.HostApp\Debug\net10.0-windows10.0.19041.0\win-x64\Controls.TestCases.HostApp.dll
Build succeeded.
0 Warning(s)
0 Error(s)
Time Elapsed 00:05:54.38
Determining projects to restore...
All projects are up-to-date for restore.
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14158622
Controls.CustomAttributes -> D:\a\1\s\artifacts\bin\Controls.CustomAttributes\Debug\net10.0\Controls.CustomAttributes.dll
Graphics -> D:\a\1\s\artifacts\bin\Graphics\Debug\net10.0\Microsoft.Maui.Graphics.dll
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14158622
Essentials -> D:\a\1\s\artifacts\bin\Essentials\Debug\net10.0\Microsoft.Maui.Essentials.dll
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14158622
Core -> D:\a\1\s\artifacts\bin\Core\Debug\net10.0\Microsoft.Maui.dll
Controls.Core.Design -> D:\a\1\s\artifacts\bin\Controls.Core.Design\Debug\net472\Microsoft.Maui.Controls.DesignTools.dll
Controls.BindingSourceGen -> D:\a\1\s\artifacts\bin\Controls.BindingSourceGen\Debug\netstandard2.0\Microsoft.Maui.Controls.BindingSourceGen.dll
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14158622
Controls.Core -> D:\a\1\s\artifacts\bin\Controls.Core\Debug\net10.0\Microsoft.Maui.Controls.dll
VisualTestUtils -> D:\a\1\s\artifacts\bin\VisualTestUtils\Debug\netstandard2.0\VisualTestUtils.dll
VisualTestUtils.MagickNet -> D:\a\1\s\artifacts\bin\VisualTestUtils.MagickNet\Debug\netstandard2.0\VisualTestUtils.MagickNet.dll
UITest.Core -> D:\a\1\s\artifacts\bin\UITest.Core\Debug\net10.0\UITest.Core.dll
UITest.NUnit -> D:\a\1\s\artifacts\bin\UITest.NUnit\Debug\net10.0\UITest.NUnit.dll
UITest.Appium -> D:\a\1\s\artifacts\bin\UITest.Appium\Debug\net10.0\UITest.Appium.dll
UITest.Analyzers -> D:\a\1\s\artifacts\bin\UITest.Analyzers\Debug\netstandard2.0\UITest.Analyzers.dll
Controls.TestCases.WinUI.Tests -> D:\a\1\s\artifacts\bin\Controls.TestCases.WinUI.Tests\Debug\net10.0\Controls.TestCases.WinUI.Tests.dll
Test run for D:\a\1\s\artifacts\bin\Controls.TestCases.WinUI.Tests\Debug\net10.0\Controls.TestCases.WinUI.Tests.dll (.NETCoreApp,Version=v10.0)
VSTest version 18.0.1 (x64)
Starting test execution, please wait...
A total of 1 test files matched the specified pattern.
D:\a\1\s\artifacts\bin\Controls.TestCases.WinUI.Tests\Debug\net10.0\Controls.TestCases.WinUI.Tests.dll
NUnit Adapter 4.5.0.0: Test execution started
Running selected tests in D:\a\1\s\artifacts\bin\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
>>>>> 5/21/2026 11:19:25 AM FixtureSetup for Issue34930(Windows)
>>>>> 5/21/2026 11:19:34 AM SearchHandlerHideSoftInputShouldUnfocusSearchHandlerOnWindows Start
>>>>> 5/21/2026 11:19:37 AM SearchHandlerHideSoftInputShouldUnfocusSearchHandlerOnWindows Stop
Passed SearchHandlerHideSoftInputShouldUnfocusSearchHandlerOnWindows [3 s]
>>>>> 5/21/2026 11:19:37 AM SearchHandlerShowSoftInputShouldFocusSearchHandlerOnWindows Start
>>>>> 5/21/2026 11:19:40 AM SearchHandlerShowSoftInputShouldFocusSearchHandlerOnWindows Stop
Passed SearchHandlerShowSoftInputShouldFocusSearchHandlerOnWindows [2 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.11] Discovering: Controls.TestCases.WinUI.Tests
[xUnit.net 00:00:00.35] Discovered: Controls.TestCases.WinUI.Tests
Test Run Successful.
Total tests: 2
Passed: 2
Total time: 29.5017 Seconds
📁 Fix files reverted (1 files)
src/Controls/src/Core/Handlers/Shell/ShellItemHandler.Windows.cs
🧪 UI Tests — Shell,SoftInput
Detected UI test categories: Shell,SoftInput
🧪 UI Test Execution Results
⏭️ SKIPPED — 0 passed, 0 failed, 2 skipped (platform: windows)
| Category | Result | Tests | Duration | Notes |
|---|---|---|---|---|
Shell |
⏭️ SKIPPED | — | 0s | Runner threw an exception |
SoftInput |
⏭️ SKIPPED | — | 0s | Runner threw an exception |
Failures here are informational only — they do not block the gate or affect try-fix candidate scoring.
🔍 Pre-Flight — Context & Validation
Issue: #34930 - [Windows] SearchHandler.ShowSoftInputAsync() does not focus the SearchHandler
PR: #35079 - [Windows] Fix SearchHandler does not focus when ShowSoftInputAsync is called
Platforms Affected: Windows
Files Changed: 1 implementation, 2 test (HostApp + Shared.Tests UI test)
Key Findings
- The
SearchHandler.ShowSoftInputAsync()/HideSoftInputAsync()APIs raise the internal eventsShowSoftInputRequested/HideSoftInputRequested(seesrc/Controls/src/Core/Shell/SearchHandler.cs). On Android and iOS these events are wired in the respectiveSearchHandlerAppearanceTracker. On Windows,ShellItemHandler.Windows.csowns theAutoSuggestBoxlifecycle but never subscribed — so the calls were no-ops, the AutoSuggestBox never got focus, andIsFocusednever flipped totrue. - The PR subscribes to both events in
UpdateSearchHandlerwhenever a newSearchHandleris assigned, mirrors the unsubscription inDisconnectHandler, and adds inline platform code:- Show:
autoSuggestBox.Focus(FocusState.Programmatic)— programmatic focus on the WinUI AutoSuggestBox. This drivesOnSearchBoxGotFocus, which calls_currentSearchHandler.SetIsFocused(true)and raises theFocusedevent. - Hide: inline duplicate of the
IsTabStop/IsEnabledtoggle pattern (matchingMicrosoft.Maui.Platform.ViewExtensions.UnfocusControl) with a guardif (!autoSuggestBox.IsEnabled) return;.
- Show:
- The fix delivers correct functional behavior (gate verified — without fix FAILS, with fix PASSES). However, the
UnfocusControlhelper inViewExtensions.csalready implements the exactIsTabStop/IsEnabledtoggle that the PR inlines — re-implementing it inline is duplication that could drift from the canonical helper. - Windows has no on-screen software keyboard for desktop typing input — the soft input pane only appears in tablet mode. Therefore "focus the search box" is the correct semantic, matching how Android/iOS implementations achieve "show the keyboard."
- Subscription is keyed off the
_currentSearchHandleridentity (handler-replacement path). PropertyChanged subscriptions and the new soft-input subscriptions follow the same lifecycle, which is consistent.
Code Review Summary
Verdict: NEEDS_DISCUSSION (advisory)
Confidence: medium
Errors: 0 | Warnings: 1 | Suggestions: 1
Key code review findings:
⚠️ ShellItemHandler.Windows.cs:409-413— Hide path inlines theIsTabStop/IsEnabledtoggle instead of calling the existingMicrosoft.Maui.Platform.ViewExtensions.UnfocusControl(control)helper (src/Core/src/Platform/Windows/ViewExtensions.cs:394). Risk of drift if the unfocus pattern is later changed centrally.- 💡
ShellItemHandler.Windows.cs:393-398— The Show path uses rawFocus(FocusState.Programmatic)rather than delegating to existing patterns. There is no centralized "focus a Windows control" helper (ViewExtensions.Focusis async onIViewrequest), so duplicatingFocus(FocusState.Programmatic)here is acceptable, but a small helper could be considered if more handlers adopt the pattern. - 💡 Consider also calling
FrameworkElementExtensions.ShowSoftInput(autoSuggestBox)for parity with Entry/Editor on tablet-mode Windows where an actual InputPane exists.
Fix Candidates
| # | Source | Approach | Test Result | Files Changed | Notes |
|---|---|---|---|---|---|
| PR | PR #35079 | Subscribe to Show/Hide events; Focus(FocusState.Programmatic) on show; inline IsTabStop/IsEnabled toggle on hide |
✅ PASSED (Gate) | ShellItemHandler.Windows.cs |
Original PR — duplicates UnfocusControl logic |
🔧 Fix — Analysis & Comparison
Try-Fix Summary — PR #35079
Both candidates were generated with maui-expert-reviewer guidance (via the try-fix skill's inline Step 6 self-review against .github/agents/maui-expert-reviewer.md) and tested empirically on Windows with BuildAndRunHostApp.ps1 -Platform windows -TestFilter "FullyQualifiedName~Issue34930".
Fix Candidates
| # | Source | Approach | Test Result | Files Changed | Notes |
|---|---|---|---|---|---|
| PR | PR #35079 | Subscribe to Show/Hide events; Focus(FocusState.Programmatic) on show; inline IsTabStop/IsEnabled toggle on hide. |
✅ PASSED (Gate) | 1 impl + 2 test | Works; duplicates UnfocusControl logic inline. |
| 1 | try-fix-1 | Same wiring; same show. Hide replaced by Microsoft.Maui.Platform.ViewExtensions.UnfocusControl(autoSuggestBox) — reuse existing helper. |
✅ PASS | 1 impl (ShellItemHandler.Windows.cs) |
Cleanest; ~12 fewer lines than PR; clean self-review; single source of truth for the unfocus pattern. |
| 2 | try-fix-2 | Candidate 1 + also call FrameworkElementExtensions.ShowSoftInput / HideSoftInput to surface the WinUI InputPane, matching Android/iOS semantics. |
✅ PASS | 1 impl (ShellItemHandler.Windows.cs) |
+6 lines vs #1; clean self-review; broader behavioral parity with Entry.ShowSoftInputAsync() on Windows. |
Cross-Pollination
| Round | New Idea Explored? | Outcome |
|---|---|---|
| 1 | ✅ Reuse UnfocusControl helper (#1) |
PASS — clearly better than PR |
| 2 | ✅ Add OS InputPane parity (#2) | PASS — meaningfully different semantic; somewhat broader scope |
| 3 | — | Further variations would be trivial (e.g., extracting OnShowSoftInputRequested/OnHideSoftInputRequested into a separate SearchHandlerAppearanceTracker.Windows.cs to mirror Android/iOS architecture). Architectural refactor → larger blast radius and not demonstrably better for fixing only this bug. Skipped. |
Exhausted
Yes — two meaningfully different approaches explored. Remaining options (full architectural refactor into a SearchHandlerAppearanceTracker.Windows tracker) exceed the bug's scope and would introduce a parallel subscription path that duplicates ShellItemHandler ownership of AutoSuggestBox — not net-better for this fix.
Selected Fix
Candidate 1 — Reuse Microsoft.Maui.Platform.ViewExtensions.UnfocusControl(autoSuggestBox).
Why over the PR's fix:
- Removes ~12 lines of duplicated platform code (the inline
IsTabStop/IsEnabledtoggle is exactly whatUnfocusControlalready does, including theif (!control.IsEnabled) returnguard). - Single source of truth for the "unfocus a WinUI Control" pattern — future changes to that helper propagate.
- Same external behavior (gate test still passes), clean self-review.
- Scope strictly limited to fixing the bug — no behavioral additions.
Why over candidate 2:
- Candidate 2 is also viable and arguably more user-aligned (it matches the literal API name on tablet-mode Windows). However:
- The bug being fixed ([Windows] SearchHandler.ShowSoftInputAsync() does not focus the SearchHandler #34930) is specifically about
IsFocused/ focus state — candidate 1 fully solves that. - Candidate 2 adds InputPane behavior that has no existing test coverage on Windows; expanding scope without a regression test for the new behavior risks silent breakage later.
- The InputPane addition is a follow-up enhancement that could land in a separate PR with its own test (touch/tablet harness).
- The bug being fixed ([Windows] SearchHandler.ShowSoftInputAsync() does not focus the SearchHandler #34930) is specifically about
Recommendation for PR Author
Apply the candidate 1 diff to the PR (the only functional change is in OnHideSoftInputRequested):
void OnHideSoftInputRequested(object? sender, EventArgs e)
{
if (PlatformView is not NavigationView mauiNavView || mauiNavView.AutoSuggestBox is not { } autoSuggestBox)
return;
Microsoft.Maui.Platform.ViewExtensions.UnfocusControl(autoSuggestBox);
}The rest of the PR (event subscriptions, OnShowSoftInputRequested, lifecycle cleanup, host app + UI test) is correct and should be kept as-is.
Artifacts
- Per-candidate narrative:
try-fix-1/content.mdtry-fix-2/content.md
- Per-attempt evidence (baseline, diff, test logs, self-review):
try-fix/attempt-1/try-fix/attempt-2/
📋 Report — Final Recommendation
Comparative Report — PR #35079 candidates
Issue: #34930 — Windows SearchHandler.ShowSoftInputAsync() does not focus.
Platform: Windows.
Gate (test fails without fix, passes with fix): ✅ PASSED — not re-run.
1. Candidate matrix
| Candidate | Approach (hide path) | Approach (show path) | Lines vs. PR | Regression tests | Self-review |
|---|---|---|---|---|---|
pr |
Inline IsTabStop/IsEnabled toggle with if (!IsEnabled) return guard |
autoSuggestBox.Focus(FocusState.Programmatic) |
baseline | ✅ PASS (gate) | 1 warning (F1: duplication) + 1 suggestion (F2: InputPane parity) |
pr-plus-reviewer |
Microsoft.Maui.Platform.ViewExtensions.UnfocusControl(autoSuggestBox) |
Same as PR | −12 | ✅ PASS (via try-fix-1 — diff-identical) | 0 findings |
try-fix-1 |
UnfocusControl(autoSuggestBox) |
Same as PR | −12 | ✅ PASS (empirical) | 0 findings |
try-fix-2 |
UnfocusControl(autoSuggestBox) + FrameworkElementExtensions.HideSoftInput(autoSuggestBox) |
PR's focus + FrameworkElementExtensions.ShowSoftInput(autoSuggestBox) |
−6 | ✅ PASS (empirical) | 0 findings; but new behavior (InputPane) with no test coverage |
Note: pr-plus-reviewer and try-fix-1 are diff-identical — they arrive at the same code via different routes (expert review of the PR vs. independent re-derivation). For ranking purposes, pr-plus-reviewer carries the additional context of being "PR-baseline + reviewer feedback applied," which is the preferred framing for landing on the existing PR.
2. Ranking
All candidates passed the regression tests, so no candidate is demoted on that basis.
- 🥇
pr-plus-reviewer— Diff-identical totry-fix-1, framed as the PR plus reviewer-driven cleanup. Strictly better thanpr(removes duplication, same behavior, same passing tests). Single source of truth for the Windows "unfocus a Control" pattern via the canonicalUnfocusControlhelper. - 🥈
try-fix-1— Equivalent in code to [Draft] Readme WIP #1; ranked second only because it's framed as an independent rewrite rather than as feedback layered onto the open PR. Functionally tied with the winner. - 🥉
pr— Works correctly and passes the gate. Sole issue is the inlined duplication of theUnfocusControlpattern (drift risk if the canonical helper is later updated, e.g., for future WinUI workarounds). try-fix-2— Also passes tests and addresses F2 (OSInputPaneparity). Ranked lower because it expands behavior beyond the bug's scope (touch/tablet keyboard surfacing) without adding test coverage for the new behavior. The InputPane integration is correct and arguably more user-aligned, but is better landed as a separate, dedicated PR with tablet-mode test coverage.
3. Winner
pr-plus-reviewer
Rationale
- Resolves the only warning-severity reviewer finding (F1) on the PR with a one-line change.
- Behaviorally identical to the merged PR — same gate-passing test results, no risk of new regressions.
- Removes ~12 lines of duplicated platform code; aligns with the canonical
Microsoft.Maui.Platform.ViewExtensions.UnfocusControlhelper used elsewhere by handlers. - Strictly conservative — scope remains the bug only, with no behavioral expansion (unlike try-fix-2's untested InputPane work).
- Frames the outcome as "land the PR after applying reviewer feedback," which is the right shape for this workflow.
Disposition of suggestions not applied
- F2 (InputPane parity / try-fix-2 approach): Defer to a follow-up PR with tablet-mode test coverage. Tracked as a recommendation in the PR review comments. Not a blocker for [Windows] Fix SearchHandler does not focus when ShowSoftInputAsync is called #35079.
- F3 (
Focus(FocusState.Programmatic)style): Informational only; no change recommended.
4. Recommendation to PR author
Apply this single edit to src/Controls/src/Core/Handlers/Shell/ShellItemHandler.Windows.cs (OnHideSoftInputRequested):
void OnHideSoftInputRequested(object? sender, EventArgs e)
{
if (PlatformView is not NavigationView mauiNavView || mauiNavView.AutoSuggestBox is not { } autoSuggestBox)
return;
- if (!autoSuggestBox.IsEnabled)
- return;
-
- var isTabStop = autoSuggestBox.IsTabStop;
- autoSuggestBox.IsTabStop = false;
- autoSuggestBox.IsEnabled = false;
- autoSuggestBox.IsEnabled = true;
- autoSuggestBox.IsTabStop = isTabStop;
+ Microsoft.Maui.Platform.ViewExtensions.UnfocusControl(autoSuggestBox);
}Keep everything else from PR #35079 as-is (event subscriptions, OnShowSoftInputRequested, host app entry, and the two new Issue34930 UI tests).
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!
Root Cause
PR #29600 added
ShowSoftInputRequestedandHideSoftInputRequestedevent handling for Android and iOS via their respectiveSearchHandlerAppearanceTrackerimplementations.However, Windows uses
ShellItemHandler.Windows.cs, which was not updated to handle these events. As a result, although the events are raised bySearchHandler.ShowSoftInputAsync(), there are no subscribers on Windows, leading to no action.Description of Change
Extended support for
ShowSoftInputAsync()/HideSoftInputAsync()to Windows by wiring the corresponding events inShellItemHandler.Windows.cs.Event subscriptions are handled in
UpdateSearchHandlerwhen a handler is assigned, and are properly cleaned up when the handler is replaced or duringDisconnectHandler.Since Windows does not use an on-screen keyboard, the implementation focuses on focus management. Focus is applied using
autoSuggestBox.Focus(FocusState.Programmatic), aligning with standard WinUI behavior. Unfocus is handled using the existingIsEnabledtoggle pattern (consistent withViewExtensions.UnfocusControl), with proper preservation ofIsTabStop.A safety guard is included to ensure that disabled controls are not unintentionally re-enabled during the unfocus process.
Issues Fixed
Fixes #34930
Tested the behaviour in the following platforms
Screenshots