Fix Shell.Title binding in TitleView - #35800
Conversation
Synchronize the effective Shell page title to Shell.Title so TitleView bindings can resolve the current page title without duplicating the rendered toolbar title. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
🚀 Dogfood this PR with:
curl -fsSL https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.sh | bash -s -- 35800Or
iex "& { $(irm https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.ps1) } 35800" |
|
/review -b feature/enhanced-reviewer |
MauiBot
left a comment
There was a problem hiding this comment.
Expert Review — 1 findings
See inline comments for details.
|
|
||
| var title = GetCurrentTitle(); | ||
| if (!IsShellTitleSetByUser()) | ||
| _shell.SetValueFromRenderer(Shell.TitleProperty, title); |
There was a problem hiding this comment.
[major] Logic and Correctness — This still treats an explicit TwoWay binding on Shell.Title as handler-owned state and overwrites it with the current page title. BindableObject.SetBinding stores TwoWay bindings with SetterSpecificity.FromHandler, so IsShellTitleSetByUser() returns false for <Shell Title="{Binding AppTitle, Mode=TwoWay}">; when a TitleView is applied or the page title changes, this line pushes the page title into Shell.Title and back into the view model instead of preserving the app's binding. Please distinguish an actual binding in the property context from renderer-generated title values before calling SetValueFromRenderer.
kubaflo
left a comment
There was a problem hiding this comment.
Could you please check the ai's suggestions?
|
/review |
MauiBot
left a comment
There was a problem hiding this comment.
Expert Review — 1 findings
See inline comments for details.
| return false; | ||
|
|
||
| var specificity = titleContext.Values.GetSpecificity(); | ||
| return specificity != SetterSpecificity.DefaultValue && specificity != SetterSpecificity.FromHandler; |
There was a problem hiding this comment.
❌ [major] Navigation & Shell — This treats SetterSpecificity.FromHandler as toolbar-owned, but explicit TwoWay bindings on Shell.Title are also registered with FromHandler (BindableObject.SetBinding). When a user binds Shell.Title TwoWay and a TitleView is active, UpdateTitle() can overwrite the bound view-model value with the current page title. Please treat an existing binding on Shell.TitleProperty as user intent before falling back to the specificity check.
kubaflo
left a comment
There was a problem hiding this comment.
Could you apply the ai's suggestions please?
This comment was marked as outdated.
This comment was marked as outdated.
Treat existing Shell.Title bindings as user-owned state before synchronizing the current page title for TitleView bindings. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
/review -b feature/enhanced-reviewer -p android |
|
/review -b feature/enhanced-reviewer -p android |
MauiBot
left a comment
There was a problem hiding this comment.
AI Review Summary
@jfversluis — new AI review results are available based on this last commit:
d3c47ac.
Preserve bound Shell titles To request a fresh review after new comments or commits, comment/review rerun.
Review Sessions — click to expand
Gate — Test Before & After Fix
Gate Result: ✅ PASSED
Platform: ANDROID · Base: main · Merge base: dd5b6d2e
| Test | Without Fix (expect FAIL) | With Fix (expect PASS) |
|---|---|---|
🧪 ShellToolbarTests ShellToolbarTests |
✅ FAIL — 108s | ✅ PASS — 73s |
🔴 Without fix — 🧪 ShellToolbarTests: FAIL ✅ · 108s
Determining projects to restore...
Restored /home/vsts/work/1/s/src/Graphics/src/Graphics/Graphics.csproj (in 843 ms).
Restored /home/vsts/work/1/s/src/TestUtils/src/TestUtils/TestUtils.csproj (in 2.35 sec).
Restored /home/vsts/work/1/s/src/Essentials/src/Essentials.csproj (in 4.27 sec).
Restored /home/vsts/work/1/s/src/Core/src/Core.csproj (in 5.37 sec).
Restored /home/vsts/work/1/s/src/Core/maps/src/Maps.csproj (in 2.63 sec).
Restored /home/vsts/work/1/s/src/Controls/src/Xaml/Controls.Xaml.csproj (in 58 ms).
Restored /home/vsts/work/1/s/src/Controls/src/Core/Controls.Core.csproj (in 36 ms).
Restored /home/vsts/work/1/s/src/Controls/Maps/src/Controls.Maps.csproj (in 37 ms).
Restored /home/vsts/work/1/s/src/Controls/tests/Core.UnitTests/Controls.Core.UnitTests.csproj (in 1.34 sec).
1 of 10 projects are up-to-date for restore.
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14353578
Graphics -> /home/vsts/work/1/s/artifacts/bin/Graphics/Debug/net10.0/Microsoft.Maui.Graphics.dll
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14353578
Essentials -> /home/vsts/work/1/s/artifacts/bin/Essentials/Debug/net10.0/Microsoft.Maui.Essentials.dll
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14353578
Core -> /home/vsts/work/1/s/artifacts/bin/Core/Debug/net10.0/Microsoft.Maui.dll
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14353578
Maps -> /home/vsts/work/1/s/artifacts/bin/Maps/Debug/net10.0/Microsoft.Maui.Maps.dll
Controls.BindingSourceGen -> /home/vsts/work/1/s/artifacts/bin/Controls.BindingSourceGen/Debug/netstandard2.0/Microsoft.Maui.Controls.BindingSourceGen.dll
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14353578
Controls.Core -> /home/vsts/work/1/s/artifacts/bin/Controls.Core/Debug/net10.0/Microsoft.Maui.Controls.dll
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14353578
Controls.Xaml -> /home/vsts/work/1/s/artifacts/bin/Controls.Xaml/Debug/net10.0/Microsoft.Maui.Controls.Xaml.dll
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14353578
Controls.Maps -> /home/vsts/work/1/s/artifacts/bin/Controls.Maps/Debug/net10.0/Microsoft.Maui.Controls.Maps.dll
TestUtils -> /home/vsts/work/1/s/artifacts/bin/TestUtils/Debug/netstandard2.0/Microsoft.Maui.TestUtils.dll
Controls.Core.UnitTests -> /home/vsts/work/1/s/artifacts/bin/Controls.Core.UnitTests/Debug/net10.0/Microsoft.Maui.Controls.Core.UnitTests.dll
Test run for /home/vsts/work/1/s/artifacts/bin/Controls.Core.UnitTests/Debug/net10.0/Microsoft.Maui.Controls.Core.UnitTests.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.
[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.19] Discovering: Microsoft.Maui.Controls.Core.UnitTests
[xUnit.net 00:00:01.39] Discovered: Microsoft.Maui.Controls.Core.UnitTests
[xUnit.net 00:00:01.40] Starting: Microsoft.Maui.Controls.Core.UnitTests
[xUnit.net 00:00:01.59] ShellTitleReflectsCurrentPageTitleForTitleViewBindings [FAIL]
[xUnit.net 00:00:01.59] Assert.Equal() Failure: Strings differ
[xUnit.net 00:00:01.59] Expected: "Test Title"
[xUnit.net 00:00:01.59] Actual: null
[xUnit.net 00:00:01.60] Stack Trace:
[xUnit.net 00:00:01.60] /_/src/Controls/tests/Core.UnitTests/ShellToolbarTests.cs(296,0): at Microsoft.Maui.Controls.Core.UnitTests.ShellToolbarTests.ShellTitleReflectsCurrentPageTitleForTitleViewBindings()
[xUnit.net 00:00:01.60] at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
[xUnit.net 00:00:01.60] at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)
Failed ShellTitleReflectsCurrentPageTitleForTitleViewBindings [129 ms]
Error Message:
Assert.Equal() Failure: Strings differ
Expected: "Test Title"
Actual: null
Stack Trace:
at Microsoft.Maui.Controls.Core.UnitTests.ShellToolbarTests.ShellTitleReflectsCurrentPageTitleForTitleViewBindings() in /_/src/Controls/tests/Core.UnitTests/ShellToolbarTests.cs:line 296
at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)
Passed BackButtonExecutesCommand [28 ms]
Passed BackButtonUpdatesWhenSetToNewCommand [3 ms]
Passed ShellTitleBindingIsNotOverwrittenByCurrentPageTitle [3 ms]
Passed ToolBarShouldBeVisibleWithEmptyTitleAndFlyoutBehaviorSetToFlyout [1 ms]
Passed TitleAndTitleViewAreMutuallyExclusive [4 ms]
Passed BackButtonBehaviorCommandFromPoppedPageIsCorrectlyUnsubscribedFrom [7 ms]
Passed BackButtonBehaviorBindingContextPropagationWithExistingBindingContext [3 ms]
Passed ShellToolbarUpdatesFromNewBackButtonBehavior [1 ms]
[xUnit.net 00:00:01.68] Finished: Microsoft.Maui.Controls.Core.UnitTests
Passed BackButtonBehaviorSet [< 1 ms]
Passed NavBarIsVisibleUpdates [3 ms]
Passed ContentPageColorsPropagateToShellToolbar [3 ms]
Passed ShellToolbarItemsMergeWithPage [11 ms]
Passed BackButtonDisabledWhenCommandDisabled [2 ms]
Passed ShellToolbarUpdatesFromPropertyChanged [1 ms]
Passed BackButtonBehaviorBindingContextPropagation [< 1 ms]
Test Run Failed.
Total tests: 16
Passed: 15
Failed: 1
Total time: 2.2175 Seconds
🟢 With fix — 🧪 ShellToolbarTests: PASS ✅ · 73s
Determining projects to restore...
All projects are up-to-date for restore.
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14353578
Graphics -> /home/vsts/work/1/s/artifacts/bin/Graphics/Debug/net10.0/Microsoft.Maui.Graphics.dll
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14353578
Essentials -> /home/vsts/work/1/s/artifacts/bin/Essentials/Debug/net10.0/Microsoft.Maui.Essentials.dll
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14353578
Core -> /home/vsts/work/1/s/artifacts/bin/Core/Debug/net10.0/Microsoft.Maui.dll
Controls.BindingSourceGen -> /home/vsts/work/1/s/artifacts/bin/Controls.BindingSourceGen/Debug/netstandard2.0/Microsoft.Maui.Controls.BindingSourceGen.dll
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14353578
Maps -> /home/vsts/work/1/s/artifacts/bin/Maps/Debug/net10.0/Microsoft.Maui.Maps.dll
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14353578
Controls.Core -> /home/vsts/work/1/s/artifacts/bin/Controls.Core/Debug/net10.0/Microsoft.Maui.Controls.dll
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14353578
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14353578
Controls.Maps -> /home/vsts/work/1/s/artifacts/bin/Controls.Maps/Debug/net10.0/Microsoft.Maui.Controls.Maps.dll
Controls.Xaml -> /home/vsts/work/1/s/artifacts/bin/Controls.Xaml/Debug/net10.0/Microsoft.Maui.Controls.Xaml.dll
TestUtils -> /home/vsts/work/1/s/artifacts/bin/TestUtils/Debug/netstandard2.0/Microsoft.Maui.TestUtils.dll
Controls.Core.UnitTests -> /home/vsts/work/1/s/artifacts/bin/Controls.Core.UnitTests/Debug/net10.0/Microsoft.Maui.Controls.Core.UnitTests.dll
Test run for /home/vsts/work/1/s/artifacts/bin/Controls.Core.UnitTests/Debug/net10.0/Microsoft.Maui.Controls.Core.UnitTests.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.
[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.41] Discovering: Microsoft.Maui.Controls.Core.UnitTests
[xUnit.net 00:00:02.82] Discovered: Microsoft.Maui.Controls.Core.UnitTests
[xUnit.net 00:00:02.85] Starting: Microsoft.Maui.Controls.Core.UnitTests
Passed ShellTitleReflectsCurrentPageTitleForTitleViewBindings [215 ms]
Passed BackButtonExecutesCommand [35 ms]
Passed BackButtonUpdatesWhenSetToNewCommand [6 ms]
Passed ShellTitleBindingIsNotOverwrittenByCurrentPageTitle [2 ms]
Passed ToolBarShouldBeVisibleWithEmptyTitleAndFlyoutBehaviorSetToFlyout [1 ms]
Passed TitleAndTitleViewAreMutuallyExclusive [5 ms]
Passed BackButtonBehaviorCommandFromPoppedPageIsCorrectlyUnsubscribedFrom [9 ms]
Passed BackButtonBehaviorBindingContextPropagationWithExistingBindingContext [3 ms]
Passed ShellToolbarUpdatesFromNewBackButtonBehavior [1 ms]
[xUnit.net 00:00:03.28] Finished: Microsoft.Maui.Controls.Core.UnitTests
Passed BackButtonBehaviorSet [< 1 ms]
Passed NavBarIsVisibleUpdates [7 ms]
Passed ContentPageColorsPropagateToShellToolbar [5 ms]
Passed ShellToolbarItemsMergeWithPage [24 ms]
Passed BackButtonDisabledWhenCommandDisabled [4 ms]
Passed ShellToolbarUpdatesFromPropertyChanged [3 ms]
Passed BackButtonBehaviorBindingContextPropagation [< 1 ms]
Test Run Successful.
Total tests: 16
Passed: 16
Total time: 4.6506 Seconds
📁 Fix files reverted (2 files)
eng/pipelines/ci-copilot.ymlsrc/Controls/src/Core/ShellToolbar.cs
UI Tests — Shell
Detected UI test categories: Shell
❌ Deep UI tests — 0 passed; 1 category setup failure (307 impacted tests marked failed by TRX) across 1 category on platform-pool agent (replaces in-process counts above).
🧪 UI Test Execution Results (deep, platform pool)
| Category | Tests | Snapshot diffs |
|---|---|---|
Shell |
0/307 (setup failed; 307 marked failed) | — |
⚠️ Shell — fixture setup failed for 307 tests
NUnit reported a OneTimeSetUp/fixture setup failure before test bodies ran; the TRX marked each affected test failed.
Multiple setup failure signatures were present; showing the first one. See the TRX artifact for all details.
OneTimeSetUp: System.TimeoutException : Timed out waiting for Go To Test button to appear
at UITest.Appium.HelperExtensions.Wait(Func`1 query, Func`2 satisfactory, String timeoutMessage, Nullable`1 timeout, Nullable`1 retryFrequency) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 2757
at UITest.Appium.HelperExtensions.WaitForAtLeastOne(Func`1 query, String timeoutMessage, Nullable`1 timeout, Nullable`1 retryFrequency) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 2784
at UITest.Appium.HelperExtensions.WaitForElement(IApp app, String marked, String timeoutMessage, Nullable`1 timeout, Nullable`1 retryFrequency, Nullable`1 postTimeout) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 793
at Microsoft.Maui.TestCases.Tests.UtilExtensions.NavigateToGallery(IApp app, String page) in /_/src/Controls/tests/TestCases.Shared.Tests/UtilExtensions.cs:line 37
at Microsoft.Maui.TestCases.Tests._GalleryUITest.FixtureSetup() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/_GalleryUITest.cs:line 57
at UITest.Appium.NUnit.UITestBase.OneTimeSetup() in /_/src/TestUtils/src/UITest.NUnit/UITestBase.cs:line 221
at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)
📎 Download drop-deep-uitests artifact (TRX + snapshot diffs)
Pre-Flight — Context & Validation
Issue: #35800 - unavailable (GitHub CLI authentication unavailable)
PR: #35800 - unavailable (local branch pr-review-35800)
Platforms Affected: android requested for testing; product change is shared Shell/Controls logic
Files Changed: 7 implementation/infrastructure, 2 test (local diff against origin/main)
Key Findings
- GitHub CLI was unauthenticated, so PR body, linked issue text, PR comments, inline review comments, and CI checks could not be fetched. Context was gathered from the checked-out PR branch and local diff only.
- The functional product fix is isolated to
src/Controls/src/Core/ShellToolbar.cs; the regression tests are insrc/Controls/tests/Core.UnitTests/ShellToolbarTests.cs. - The PR changes
ShellToolbar.UpdateTitle()soShell.Titlemirrors the effective current page/content title viaSetValueFromRendererunlessShell.Titleis already user-set or bound, while keepingToolbar.Titleempty whenTitleViewis present. - The reported scenario appears to be TitleView content binding to
Shell.Title: when a TitleView is used, the native toolbar title is intentionally empty, but logical shell title bindings still need the current page title.
Code Review Summary
Verdict: LGTM
Confidence: medium
Errors: 0 | Warnings: 1 | Suggestions: 3
Key code review findings:
⚠️ The current PR updatesShell.Titleon every title update, even when noTitleViewis present. This may be acceptable and internally consistent, but it is broader than the TitleView-specific regression.- 💡 Add adjacent tests for manually-set
Shell.Title, navigation/push/pop title changes, ShellContent fallback, and source binding updates after TitleView is applied. - 💡 Consider an equality guard before
SetValueFromRendererto avoid a reentrant no-opUpdateTitle()pass after the framework-owned title write. - 💡 A Shell-owned helper would be architecturally cleaner if effective-title ownership needs to grow, but is more invasive than the current PR.
Fix Candidates
| # | Source | Approach | Test Result | Files Changed | Notes |
|---|---|---|---|---|---|
| PR | PR #35800 | ShellToolbar.UpdateTitle() computes effective current title, writes it to Shell.Title with framework specificity unless user-owned, and keeps native toolbar title empty with TitleView |
✅ PASSED (Gate) | src/Controls/src/Core/ShellToolbar.cs, src/Controls/tests/Core.UnitTests/ShellToolbarTests.cs |
Original PR; gate result supplied by caller |
Code Review — Deep Analysis
Code Review — PR #35800
Independent Assessment
What this changes: ShellToolbar.UpdateTitle() now computes the current effective page/content title even when a TitleView is present. It mirrors that title into Shell.Title using SetValueFromRenderer(Shell.TitleProperty, title) unless Shell.Title is already user-set or bound. The toolbar's native Toolbar.Title remains empty when TitleView exists.
Inferred motivation: TitleView content can bind to Shell.Title; previously, the early return for TitleView left the logical shell title stale or empty even though the current page had a title.
Reconciliation with PR Narrative
Author claims: GitHub PR narrative was unavailable because gh is not authenticated in this environment.
Agreement/disagreement: Local code and tests indicate the PR fixes logical Shell title propagation for TitleView bindings while preserving explicit/bound app-level Shell titles.
Findings
⚠️ Warning — Broader Shell.Title synchronization than TitleView-only scenario
The PR updates Shell.Title from the current page/content title on every UpdateTitle() call, even when no TitleView exists. That may be desirable consistency, but it is broader than the TitleView-specific failure mode and could affect app code observing Shell.Title.
💡 Suggestion — Add adjacent regression tests
The added tests cover the core TitleView binding scenario and a bound Shell.Title preservation case. Adjacent coverage would be stronger for manually-set Shell.Title, navigation/push/pop title transitions, ShellContent title fallback, and source binding updates after TitleView is applied.
💡 Suggestion — Avoid reentrant no-op title updates
SetValueFromRenderer(Shell.TitleProperty, title) may raise Shell.Title changed, which the ShellToolbar constructor handles by calling UpdateTitle() again. This should terminate because the second write is the same value, but an equality guard would avoid the extra pass.
Devil's Advocate
The current PR's use of SetValueFromRenderer is consistent with MAUI's specificity model and the added IsShellTitleSetByUser() guard prevents overwriting user or binding-owned shell titles. The main concern is behavioral scope, not a concrete correctness failure. Narrower alternatives reduce blast radius but risk inconsistent Shell.Title semantics depending on whether a TitleView is currently applied.
Verdict: LGTM
Confidence: medium
Summary: The current PR is a reasonable targeted fix with correct preservation of user-owned Shell.Title. Alternatives should be compared mainly on blast radius, abstraction ownership, and test coverage; no blocking defect was found in the PR product change from local review.
Fix — Analysis & Comparison
Fix Candidates
| # | Source | Approach | Test Result | Files Changed | Notes |
|---|---|---|---|---|---|
| 1 | try-fix | Shell-owned effective title helper | ✅ PASS | 2 files | Moves Shell.Title ownership/specificity guard into Shell; cleaner abstraction but more invasive than PR. |
| 2 | try-fix | TitleView-only Shell.Title synchronization | ✅ PASS | 1 file | Reduces blast radius but makes Shell.Title tracking depend on TitleView presence. |
| 3 | try-fix | Handler-specific binding from current Page.Title | ✅ PASS / |
1 file | Uses binding infrastructure but misses ShellContent.Title fallback when Page.Title is unset. |
| PR | PR #35800 | Compute effective title in ShellToolbar, write framework-owned Shell.Title unless user-owned, keep Toolbar.Title empty with TitleView | ✅ PASSED (Gate) | 2 files | Original PR; gate result supplied by caller. |
Cross-Pollination
| Model | Round | New Ideas? | Details |
|---|---|---|---|
| maui-expert-reviewer | 2 | No | NO NEW IDEAS — remaining distinct options such as an internal effective-title property/coercion model or binding proxy are more invasive and not likely better than the PR. |
Exhausted: Yes
Selected Fix: PR #35800 — It passes the supplied gate, preserves effective title fallback semantics, protects explicit/bound Shell.Title values, and is simpler/more consistent than the passing alternatives. Candidate #1 is viable but more invasive; Candidate #2 is narrower but semantically inconsistent; Candidate #3 is not robust because it drops ShellContent fallback.
Attempt Details
try-fix-1/content.md— Shell-owned helper candidate, passed focused ShellToolbar tests.try-fix-2/content.md— TitleView-only synchronization candidate, passed focused ShellToolbar tests.try-fix-3/content.md— Binding-driven candidate, passed focused ShellToolbar tests but has a major self-review finding.
Report — Final Recommendation
Comparative Fix Report
Candidates
| Rank | Candidate | Regression status | Assessment |
|---|---|---|---|
| 1 | pr |
PASS | Best choice. It fixes the TitleView/Shell.Title binding regression, preserves ShellContent fallback semantics, protects explicit or bound Shell.Title values, and keeps the change localized to the existing toolbar title update path. |
| 1 | pr-plus-reviewer |
PASS | Equivalent to pr; the expert reviewer found no actionable changes to apply. It is not selected separately because it has no behavioral or code delta over the submitted PR. |
| 3 | try-fix-1 |
PASS | Viable Shell-owned helper approach with a clean ownership boundary and equality guard, but it is more invasive because it adds new internal Shell surface for a targeted toolbar synchronization issue. |
| 4 | try-fix-2 |
PASS | Lower blast radius than the PR because it synchronizes Shell.Title only when a TitleView is active, but that makes logical Shell title semantics depend on TitleView presence. |
| 5 | try-fix-3 |
PASS / self-review issue | Ranked lowest among passing candidates. Its binding-driven approach misses the existing ShellContent.Title fallback when Page.Title is unset, and its recorded attempt included trim/compile concerns before correction. |
No candidate with a failed regression result outranks a passing candidate. All viable candidates passed the focused regression signal recorded in STEP 5a, while try-fix-3 carries a correctness gap despite its eventual focused test pass.
Winning candidate
Winner: pr
The submitted PR fix is the best candidate because it is localized, passes the supplied gate, preserves the existing effective-title fallback behavior, and correctly avoids overwriting user-owned or bound Shell.Title values. pr-plus-reviewer is equivalent because the expert reviewer produced no actionable changes; the other try-fix candidates are either more invasive, semantically narrower, or less complete.
Future Action — review latest findings
No alternative fix was selected for this run. Review the session findings and CI results before merging.
<!-- 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 `Shell.TitleView` content can bind to the Shell instance, but `Shell.Title` was not updated from the active page title. This meant bindings such as `{Binding Title, Source={x:Reference Shell}}` resolved to `null` even when the current `ContentPage.Title` was set. This change mirrors the effective current page or ShellContent title into `Shell.Title` when Shell does not already have a user-set title. The rendered toolbar title still remains empty while a custom TitleView is active, and explicit Shell titles continue to work for Window title fallback. A core unit test covers the TitleView binding scenario and verifies updates when the current page title changes. ### Issues Fixed Fixes #35761 --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
<!-- 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 `Shell.TitleView` content can bind to the Shell instance, but `Shell.Title` was not updated from the active page title. This meant bindings such as `{Binding Title, Source={x:Reference Shell}}` resolved to `null` even when the current `ContentPage.Title` was set. This change mirrors the effective current page or ShellContent title into `Shell.Title` when Shell does not already have a user-set title. The rendered toolbar title still remains empty while a custom TitleView is active, and explicit Shell titles continue to work for Window title fallback. A core unit test covers the TitleView binding scenario and verifies updates when the current page title changes. ### Issues Fixed Fixes #35761 --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
<!-- 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 `Shell.TitleView` content can bind to the Shell instance, but `Shell.Title` was not updated from the active page title. This meant bindings such as `{Binding Title, Source={x:Reference Shell}}` resolved to `null` even when the current `ContentPage.Title` was set. This change mirrors the effective current page or ShellContent title into `Shell.Title` when Shell does not already have a user-set title. The rendered toolbar title still remains empty while a custom TitleView is active, and explicit Shell titles continue to work for Window title fallback. A core unit test covers the TitleView binding scenario and verifies updates when the current page title changes. ### Issues Fixed Fixes #35761 --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
<!-- 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 `Shell.TitleView` content can bind to the Shell instance, but `Shell.Title` was not updated from the active page title. This meant bindings such as `{Binding Title, Source={x:Reference Shell}}` resolved to `null` even when the current `ContentPage.Title` was set. This change mirrors the effective current page or ShellContent title into `Shell.Title` when Shell does not already have a user-set title. The rendered toolbar title still remains empty while a custom TitleView is active, and explicit Shell titles continue to work for Window title fallback. A core unit test covers the TitleView binding scenario and verifies updates when the current page title changes. ### Issues Fixed Fixes #35761 --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
<!-- 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 `Shell.TitleView` content can bind to the Shell instance, but `Shell.Title` was not updated from the active page title. This meant bindings such as `{Binding Title, Source={x:Reference Shell}}` resolved to `null` even when the current `ContentPage.Title` was set. This change mirrors the effective current page or ShellContent title into `Shell.Title` when Shell does not already have a user-set title. The rendered toolbar title still remains empty while a custom TitleView is active, and explicit Shell titles continue to work for Window title fallback. A core unit test covers the TitleView binding scenario and verifies updates when the current page title changes. ### Issues Fixed Fixes #35761 --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
<!-- 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 `Shell.TitleView` content can bind to the Shell instance, but `Shell.Title` was not updated from the active page title. This meant bindings such as `{Binding Title, Source={x:Reference Shell}}` resolved to `null` even when the current `ContentPage.Title` was set. This change mirrors the effective current page or ShellContent title into `Shell.Title` when Shell does not already have a user-set title. The rendered toolbar title still remains empty while a custom TitleView is active, and explicit Shell titles continue to work for Window title fallback. A core unit test covers the TitleView binding scenario and verifies updates when the current page title changes. ### Issues Fixed Fixes #35761 --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…tive window/status bar (#36334) <!-- 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! ### Issue Details Due to the changes introduced in PR #35800, when using Shell on Windows and macOS (Mac Catalyst), the current page's title (intended for the in-app navigation/title bar) was also being displayed in the native window title bar and status bar. ### Description of Changes <!-- Enter description of the fix in this section --> The SetValueFromRenderer(Shell.TitleProperty, title) call was moved inside the if (TitleView != null) block, so Shell.Title is only updated by the renderer when a TitleView is present. Without a TitleView, Shell.Title is left untouched, preventing the page title from propagating to the native window/status bar. ### Issues Fixed <!-- Please make sure that there is a bug logged for the issue being fixed. The bug should describe the problem and how to reproduce it. --> Fixes #36225 <!-- Are you targeting main? All PRs should target the main branch unless otherwise noted. --> **Tested the behavior in the following platforms.** - [ ] Android - [x] Windows - [ ] iOS - [ ] Mac | Before | After | |---------|--------| | **Mac**<br> <img src="https://github.com/user-attachments/assets/fa030b4b-6199-429e-a74a-ed346e118e79" width="600" height="300"> | **Mac**<br> <img src="https://github.com/user-attachments/assets/491d4a74-6acf-458a-8d45-fe3dce25f22f" width="600" height="300"> | ---------
<!-- 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 `Shell.TitleView` content can bind to the Shell instance, but `Shell.Title` was not updated from the active page title. This meant bindings such as `{Binding Title, Source={x:Reference Shell}}` resolved to `null` even when the current `ContentPage.Title` was set. This change mirrors the effective current page or ShellContent title into `Shell.Title` when Shell does not already have a user-set title. The rendered toolbar title still remains empty while a custom TitleView is active, and explicit Shell titles continue to work for Window title fallback. A core unit test covers the TitleView binding scenario and verifies updates when the current page title changes. ### Issues Fixed Fixes #35761 --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…tive window/status bar (#36334) <!-- 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! ### Issue Details Due to the changes introduced in PR #35800, when using Shell on Windows and macOS (Mac Catalyst), the current page's title (intended for the in-app navigation/title bar) was also being displayed in the native window title bar and status bar. ### Description of Changes <!-- Enter description of the fix in this section --> The SetValueFromRenderer(Shell.TitleProperty, title) call was moved inside the if (TitleView != null) block, so Shell.Title is only updated by the renderer when a TitleView is present. Without a TitleView, Shell.Title is left untouched, preventing the page title from propagating to the native window/status bar. ### Issues Fixed <!-- Please make sure that there is a bug logged for the issue being fixed. The bug should describe the problem and how to reproduce it. --> Fixes #36225 <!-- Are you targeting main? All PRs should target the main branch unless otherwise noted. --> **Tested the behavior in the following platforms.** - [ ] Android - [x] Windows - [ ] iOS - [ ] Mac | Before | After | |---------|--------| | **Mac**<br> <img src="https://github.com/user-attachments/assets/fa030b4b-6199-429e-a74a-ed346e118e79" width="600" height="300"> | **Mac**<br> <img src="https://github.com/user-attachments/assets/491d4a74-6acf-458a-8d45-fe3dce25f22f" width="600" height="300"> | ---------
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
Shell.TitleViewcontent can bind to the Shell instance, butShell.Titlewas not updated from the active page title. This meant bindings such as{Binding Title, Source={x:Reference Shell}}resolved tonulleven when the currentContentPage.Titlewas set.This change mirrors the effective current page or ShellContent title into
Shell.Titlewhen Shell does not already have a user-set title. The rendered toolbar title still remains empty while a custom TitleView is active, and explicit Shell titles continue to work for Window title fallback.A core unit test covers the TitleView binding scenario and verifies updates when the current page title changes.
Issues Fixed
Fixes #35761