[Net10] OnSizeAllocated in Shell not triggered - fix#31056
[Net10] OnSizeAllocated in Shell not triggered - fix#31056kubaflo wants to merge 5 commits intodotnet:mainfrom
Conversation
There was a problem hiding this comment.
Pull Request Overview
This PR fixes the OnSizeAllocated method in AppShell not being triggered on Android and iOS in .NET 10. The issue was that the Shell's Frame property was not being properly updated during layout operations, preventing the OnSizeAllocated method from being called.
- Adds proper Frame updates in shell renderers for both iOS and Android platforms
- Overrides OnLayout method in Android's ShellFlyoutRenderer to trigger frame updates
- Adds frame synchronization in iOS ShellRenderer's ViewDidLayoutSubviews method
Reviewed Changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| PublicAPI.Unshipped.txt | Documents new public OnLayout override in ShellFlyoutRenderer |
| ShellRenderer.cs (iOS) | Adds Shell.Frame update in ViewDidLayoutSubviews to trigger size allocation |
| ShellFlyoutRenderer.cs (Android) | Implements OnLayout override to update Shell.Frame and trigger size events |
|
/azp run |
|
Azure Pipelines successfully started running 3 pipeline(s). |
|
|
||
| #if ANDROID || IOS || MACCATALYST | ||
| using ShellHandler = Microsoft.Maui.Controls.Handlers.Compatibility.ShellRenderer; | ||
| using Microsoft.Maui.Graphics; |
There was a problem hiding this comment.
Fails con compile on Windows:
C:\a\_work\1\s\src\Controls\tests\DeviceTests\Elements\Shell\ShellTests.cs(1162,22): error CS0246: The type or namespace name 'Rect' could not be found (are you missing a using directive or an assembly reference?) [C:\a\_work\1\s\src\Controls\tests\DeviceTests\Controls.DeviceTests.csproj::TargetFramework=net10.0-windows10.0.20348.0]
C:\a\_work\1\s\src\Controls\tests\DeviceTests\Elements\Shell\ShellTests.cs(1162,22): error CS0246: The type or namespace name 'Rect' could not be found (are you missing a using directive or an assembly reference?) [C:\a\_work\1\s\src\Controls\tests\DeviceTests\Controls.DeviceTests.csproj::TargetFramework=net10.0-windows10.0.19041.0]
2 Error(s)
|
/azp run |
|
Azure Pipelines successfully started running 3 pipeline(s). |
| base.OnLayout(changed, left, top, right, bottom); | ||
|
|
||
| var destination = Context.ToCrossPlatformRectInReferenceFrame(left, top, right, bottom); | ||
| Shell.Frame = destination; |
There was a problem hiding this comment.
Layout passes occur frequently (device rotation, keyboard, animations, etc.) and always sets Shell.Frame even if unchanged.
Impact the performance? (mostly, animations etc).
Could we only update if if changed?
if (Shell.Frame != destination)
|
/rebase |
51feecb to
72e80e0
Compare
|
/azp run |
|
Azure Pipelines successfully started running 3 pipeline(s). |
|
🚀 Dogfood this PR with:
curl -fsSL https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.sh | bash -s -- 31056Or
iex "& { $(irm https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.ps1) } 31056" |
🤖 AI Summary📊 Expand Full Review —
|
| # | Source | Approach | Test Result | Files Changed | Notes |
|---|---|---|---|---|---|
| PR | PR #31056 | Override OnLayout (Android) + Shell.Frame = View.Bounds.ToRectangle() in ViewDidLayoutSubviews (iOS), both with equality guard |
❌ Gate FAILED (test doesn't validate fix) | ShellFlyoutRenderer.cs, ShellRenderer.cs, PublicAPI.Unshipped.txt, ShellTests.cs |
NRE risk on both platforms after disconnect |
🔧 Fix — Analysis & Comparison
Fix Candidates
| # | Source | Approach | Test Result | Files Changed | Notes |
|---|---|---|---|---|---|
| 1 | try-fix (claude-opus-4.6) | Null-guarded Frame assignment (if (Element is Shell shell) iOS, if (_shellContext?.Shell is Shell shell) Android) + better test |
✅ PASS (202 Shell tests) | ShellRenderer.cs, ShellFlyoutRenderer.cs, ShellTests.cs |
Minimal delta over PR; fixes NRE risks |
| 2 | try-fix (claude-sonnet-4.6) | Route through SetElementSize (iOS) + OnSizeChanged (Android) |
✅ PASS (202 Shell tests) | ShellRenderer.cs, ShellFlyoutRenderer.cs, ShellTests.cs |
Uses IVisualElementRenderer API; OnSizeChanged fires only on dimension change |
| 3 | try-fix (gpt-5.3-codex) | Route through IView.Arrange(...) in layout callbacks |
✅ PASS (202 Shell tests) | ShellRenderer.cs, ShellFlyoutRenderer.cs, ShellTests.cs |
Uses MAUI IView layout contract |
| 4 | try-fix (gemini-3-pro-preview) | — | ⚫ BLOCKED | — | Model unavailable |
| 5 | try-fix (gpt-5.3-codex) | IVisualElementController.PlatformSizeChanged() with bounds guard |
❌ FAIL | ShellRenderer.cs, ShellFlyoutRenderer.cs, ShellTests.cs |
Over-notification: MeasureInvalidated fires 2× instead of 1× |
| PR | PR #31056 | Override OnLayout (Android) + Shell.Frame in ViewDidLayoutSubviews (iOS), equality guard |
❌ Gate FAILED (test doesn't validate fix) | 4 files | NRE risk on both platforms after disconnect/detach |
Cross-Pollination
| Model | Round | New Ideas? | Details |
|---|---|---|---|
| claude-opus-4.6 | 2 | NO NEW IDEAS | All canonical size-propagation pathways covered |
| claude-sonnet-4.6 | 2 | NO NEW IDEAS | Space well-explored |
| gpt-5.3-codex | 2 | NEW IDEA → attempt-5 | PlatformSizeChanged() with bounds guard — ran, ❌ FAIL |
| claude-opus-4.6 | 3 | NO NEW IDEAS | Confirmed exhausted |
| claude-sonnet-4.6 | 3 | NO NEW IDEAS | Confirmed exhausted |
| gpt-5.3-codex | 3 | NEW IDEA (covered) | "Cache last size" — already implemented via equality guards in attempts 1-3 |
Exhausted: Yes
Selected Fix: Attempt 1 (claude-opus-4.6) — null-guarded Frame assignment + better test
Reason: Simplest possible improvement over the PR's own approach. The PR's core logic is correct (set Shell.Frame from native layout callbacks); it just needs (1) null guards on both platforms to prevent NRE during teardown, and (2) the test replaced with one that validates the actual regression path. Attempt 1 addresses both with minimal code change.
📋 Report — Final Recommendation
⚠️ Final Recommendation: REQUEST CHANGES
Phase Status
| Phase | Status | Notes |
|---|---|---|
| Pre-Flight | ✅ COMPLETE | Issues #31055 (iOS+Android regression) and #31020 (Android) |
| Gate | ❌ FAILED | iOS — test SettingFrameDoesTriggerInvalidatedMeasure passes even without fix |
| Try-Fix | ✅ COMPLETE | 5 attempts (3 pass, 1 fail, 1 blocked); space exhausted |
| Report | ✅ COMPLETE |
Summary
The PR's core fix is correct and necessary: Shell compatibility renderers (ShellFlyoutRenderer on Android, ShellRenderer on iOS) never update Shell.Frame from native layout callbacks, so OnSizeAllocated is never invoked for Shell subclasses. Overriding OnLayout (Android) and updating Frame in ViewDidLayoutSubviews (iOS) is the right approach, confirmed by 3 independent try-fix attempts.
However, two issues must be addressed before merging:
-
NRE risk on both platforms — The
Shellproperty accessors ((Shell)Elementon iOS,_shellContext.Shellon Android) are accessed without null checks in system callbacks (ViewDidLayoutSubviews,OnLayout) that can fire during teardown after the renderer is detached/disconnected. -
Test doesn't validate the regression —
SettingFrameDoesTriggerInvalidatedMeasuresetsShell.Framemanually before the handler is created. This tests the baseVisualElement.Framesetter (which has always worked), not the native→MAUI layout propagation path that the PR fixes. This is why Gate ❌ FAILED: the test passes regardless of whether the fix is present.
Root Cause
Shell uses compatibility renderers that bypass the normal handler/layout pipeline. Unlike ContentPage (where MauiView.LayoutVirtualView calls Shell.Arrange), Shell's renderers never fed native layout bounds back to Shell.Frame. The virtual OnSizeAllocated(width, height) method on VisualElement is only invoked when Frame changes, so it never fires for Shell subclasses.
Fix Quality
The approach is sound and well-targeted. Try-Fix attempt 1 (null-guarded Frame assignment) is the minimal improvement needed over the PR:
Required changes for the PR:
1. Android — Add null guard in ShellFlyoutRenderer.OnLayout:
protected override void OnLayout(bool changed, int left, int top, int right, int bottom)
{
base.OnLayout(changed, left, top, right, bottom);
if (_shellContext?.Shell is not Shell shell)
return;
var destination = Context.ToCrossPlatformRectInReferenceFrame(left, top, right, bottom);
if (shell.Frame != destination)
shell.Frame = destination;
}2. iOS — Add null guard in ShellRenderer.ViewDidLayoutSubviews:
public override void ViewDidLayoutSubviews()
{
base.ViewDidLayoutSubviews();
if (_currentShellItemRenderer != null)
_currentShellItemRenderer.ViewController.View.Frame = View.Bounds;
if (Element is Shell shell)
{
var destination = View.Bounds.ToRectangle();
if (shell.Frame != destination)
shell.Frame = destination;
}
}3. Replace the test — Replace SettingFrameDoesTriggerInvalidatedMeasure with a test that validates the actual regression path:
[Fact]
public async Task ShellFrameIsNonZeroAfterAddingToWindow()
{
SetupBuilder();
var page = new ContentPage();
var shell = await CreateShellAsync(shell =>
{
shell.CurrentItem = new ShellContent { Content = page };
});
await CreateHandlerAndAddToWindow<IWindowHandler>(shell, async _ =>
{
await OnFrameSetToNotEmpty(shell);
Assert.True(shell.Frame.Width > 0);
Assert.True(shell.Frame.Height > 0);
});
}Selected Fix: Attempt 1 over PR's Fix
| PR's fix | Selected fix (attempt-1) | |
|---|---|---|
| Core approach | ✅ Same (Frame from layout callbacks) | ✅ Same |
| Android null guard | ❌ Missing — NRE if OnLayout fires after Disconnect() | ✅ _shellContext?.Shell is not Shell shell |
| iOS null guard | ❌ Missing — NRE if ViewDidLayoutSubviews fires after detach | ✅ Element is Shell shell |
| Test validity | ❌ Tests Frame setter (always worked) — Gate FAILED | ✅ Tests native layout propagation path |
| Test result | ❌ Gate FAILED | ✅ 202/202 Shell tests passed |
🚦 Gate — Test Verification📊 Expand Full Gate —
|
| # | Type | Test Name | Filter |
|---|---|---|---|
| 1 | DeviceTest | ShellTests (SettingFrameDoesTriggerInvalidatedMeasure) | Category=Shell |
| Step | Expected | Actual | Result |
|---|---|---|---|
| Without fix | FAIL | FAIL (APP_LAUNCH_FAILURE) | |
| With fix | PASS | FAIL (APP_LAUNCH_FAILURE) |
Environment blocker: Both runs crashed with XHarness exit code: 83 (APP_LAUNCH_FAILURE) — SIGABRT in load_aot_module during Mono AOT loading. Test app never launched; SettingFrameDoesTriggerInvalidatedMeasure never executed. This is an infrastructure issue unrelated to the PR fix.
Note: Prior agent review (MauiBot comment) confirmed Gate ✅ PASSED on iOS with tests FAIL without fix and PASS with fix.
Code Review — PR #31056Independent AssessmentWhat this changes: Ensures Inferred motivation: Shell uses compatibility renderers that bypass the normal handler layout pipeline. Unlike regular pages where the layout infrastructure sets Reconciliation with PR NarrativeAuthor claims: Restores Agreement: ✅ Fully consistent. The approach correctly mirrors how Findings
|
🟡 .NET MAUI Review - Changes SuggestedExpand Full Review -
|
Introduces a unit test to verify that setting the Shell's Frame property triggers the MeasureInvalidated event exactly once. This ensures correct layout invalidation behavior when the frame changes.
- Use fully qualified Microsoft.Maui.Graphics.Rect in ShellTests to fix Windows compilation error (CS0246) - Add 'if (Shell.Frame != destination)' guard in iOS ShellRenderer to avoid unnecessary frame updates during layout passes - Remove unused 'using Microsoft.Maui.Graphics' import - Restore original whitespace formatting in using directives Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
🚦 Gate - Test Before and After Fix📊 Expand Full Gate —
|
| Test | Without Fix (expect FAIL) | With Fix (expect PASS) |
|---|---|---|
📱 ShellTests (SettingFrameDoesTriggerInvalidatedMeasure) Category=Shell |
❌ PASS — 455s | ✅ PASS — 214s |
🔴 Without fix — 📱 ShellTests (SettingFrameDoesTriggerInvalidatedMeasure): PASS ❌ · 455s
(truncated to last 15,000 chars)
Run + 1208
�[40m�[37mdbug�[39m�[22m�[49m: frame #6: 0x0000000186a709e8 CoreFoundation`CFRunLoopRunSpecific + 572
�[40m�[37mdbug�[39m�[22m�[49m: frame #7: 0x0000000188040c78 Foundation`-[NSRunLoop(NSRunLoop) runMode:beforeDate:] + 212
�[40m�[37mdbug�[39m�[22m�[49m: frame #8: 0x00000001880b43a4 Foundation`-[NSRunLoop(NSRunLoop) runUntilDate:] + 100
�[40m�[37mdbug�[39m�[22m�[49m: frame #9: 0x0000000104afef28 mlaunch`xamarin_dyn_objc_msgSend + 160
�[40m�[37mdbug�[39m�[22m�[49m: frame #10: 0x000000010b04e584
�[40m�[37mdbug�[39m�[22m�[49m: frame #11: 0x000000010b3b1c48
�[40m�[37mdbug�[39m�[22m�[49m: frame #12: 0x000000010b047f6c
�[40m�[37mdbug�[39m�[22m�[49m: frame #13: 0x000000010afe10b4
�[40m�[37mdbug�[39m�[22m�[49m: frame #14: 0x000000010a7fcd54
�[40m�[37mdbug�[39m�[22m�[49m: frame #15: 0x0000000106754c04 libcoreclr.dylib`CallDescrWorkerInternal + 132
�[40m�[37mdbug�[39m�[22m�[49m: frame #16: 0x00000001065d2d30 libcoreclr.dylib`MethodDescCallSite::CallTargetWorker(unsigned long long const*, unsigned long long*, int) + 836
�[40m�[37mdbug�[39m�[22m�[49m: frame #17: 0x00000001064d9350 libcoreclr.dylib`RunMain(MethodDesc*, short, int*, PtrArray**) + 648
�[40m�[37mdbug�[39m�[22m�[49m: frame #18: 0x00000001064d9688 libcoreclr.dylib`Assembly::ExecuteMainMethod(PtrArray**, int) + 264
�[40m�[37mdbug�[39m�[22m�[49m: frame #19: 0x000000010650129c libcoreclr.dylib`CorHost2::ExecuteAssembly(unsigned int, char16_t const*, int, char16_t const**, unsigned int*) + 640
�[40m�[37mdbug�[39m�[22m�[49m: frame #20: 0x00000001064c7650 libcoreclr.dylib`coreclr_execute_assembly + 232
�[40m�[37mdbug�[39m�[22m�[49m: frame #21: 0x0000000104afa140 mlaunch`mono_jit_exec + 204
�[40m�[37mdbug�[39m�[22m�[49m: frame #22: 0x0000000104afdecc mlaunch`xamarin_main + 884
�[40m�[37mdbug�[39m�[22m�[49m: frame #23: 0x0000000104aff1f4 mlaunch`main + 64
�[40m�[37mdbug�[39m�[22m�[49m: frame #24: 0x00000001865e6b98 dyld`start + 6076
�[40m�[37mdbug�[39m�[22m�[49m: thread #2
�[40m�[37mdbug�[39m�[22m�[49m: frame #0: 0x0000000186945c34 libsystem_kernel.dylib`mach_msg2_trap + 8
�[40m�[37mdbug�[39m�[22m�[49m: frame #1: 0x00000001869583a0 libsystem_kernel.dylib`mach_msg2_internal + 76
�[40m�[37mdbug�[39m�[22m�[49m: frame #2: 0x000000018694e764 libsystem_kernel.dylib`mach_msg_overwrite + 484
�[40m�[37mdbug�[39m�[22m�[49m: frame #3: 0x0000000186945fa8 libsystem_kernel.dylib`mach_msg + 24
�[40m�[37mdbug�[39m�[22m�[49m: frame #4: 0x00000001064c52f4 libcoreclr.dylib`MachMessage::Receive(unsigned int) + 80
�[40m�[37mdbug�[39m�[22m�[49m: frame #5: 0x00000001064c461c libcoreclr.dylib`SEHExceptionThread(void*) + 164
�[40m�[37mdbug�[39m�[22m�[49m: frame #6: 0x0000000186987bc8 libsystem_pthread.dylib`_pthread_start + 136
�[40m�[37mdbug�[39m�[22m�[49m: thread #3, name = '.NET SynchManager'
�[40m�[37mdbug�[39m�[22m�[49m: frame #0: 0x000000018694bd04 libsystem_kernel.dylib`kevent + 8
�[40m�[37mdbug�[39m�[22m�[49m: frame #1: 0x00000001064b9304 libcoreclr.dylib`CorUnix::CPalSynchronizationManager::ReadBytesFromProcessPipe(int, unsigned char*, int) + 484
�[40m�[37mdbug�[39m�[22m�[49m: frame #2: 0x00000001064b89f0 libcoreclr.dylib`CorUnix::CPalSynchronizationManager::WorkerThread(void*) + 164
�[40m�[37mdbug�[39m�[22m�[49m: frame #3: 0x00000001064c20fc libcoreclr.dylib`CorUnix::CPalThread::ThreadEntry(void*) + 364
�[40m�[37mdbug�[39m�[22m�[49m: frame #4: 0x0000000186987bc8 libsystem_pthread.dylib`_pthread_start + 136
�[40m�[37mdbug�[39m�[22m�[49m: thread #4, name = '.NET EventPipe'
�[40m�[37mdbug�[39m�[22m�[49m: frame #0: 0x000000018694e498 libsystem_kernel.dylib`poll + 8
�[40m�[37mdbug�[39m�[22m�[49m: frame #1: 0x00000001067b4e90 libcoreclr.dylib`ds_ipc_poll(_DiagnosticsIpcPollHandle*, unsigned long, unsigned int, void (*)(char const*, unsigned int)) + 172
�[40m�[37mdbug�[39m�[22m�[49m: frame #2: 0x0000000106862bb0 libcoreclr.dylib`ds_ipc_stream_factory_get_next_available_stream(void (*)(char const*, unsigned int)) + 756
�[40m�[37mdbug�[39m�[22m�[49m: frame #3: 0x0000000106860a68 libcoreclr.dylib`server_thread(void*) + 372
�[40m�[37mdbug�[39m�[22m�[49m: frame #4: 0x00000001064c20fc libcoreclr.dylib`CorUnix::CPalThread::ThreadEntry(void*) + 364
�[40m�[37mdbug�[39m�[22m�[49m: frame #5: 0x0000000186987bc8 libsystem_pthread.dylib`_pthread_start + 136
�[40m�[37mdbug�[39m�[22m�[49m: thread #5, name = '.NET DebugPipe'
�[40m�[37mdbug�[39m�[22m�[49m: frame #0: 0x0000000186946678 libsystem_kernel.dylib`__open + 8
�[40m�[37mdbug�[39m�[22m�[49m: frame #1: 0x00000001869516a4 libsystem_kernel.dylib`open + 64
�[40m�[37mdbug�[39m�[22m�[49m: frame #2: 0x00000001067b5a84 libcoreclr.dylib`TwoWayPipe::WaitForConnection() + 40
�[40m�[37mdbug�[39m�[22m�[49m: frame #3: 0x00000001067b0578 libcoreclr.dylib`DbgTransportSession::TransportWorker() + 232
�[40m�[37mdbug�[39m�[22m�[49m: frame #4: 0x00000001067af5c8 libcoreclr.dylib`DbgTransportSession::TransportWorkerStatic(void*) + 40
�[40m�[37mdbug�[39m�[22m�[49m: frame #5: 0x00000001064c20fc libcoreclr.dylib`CorUnix::CPalThread::ThreadEntry(void*) + 364
�[40m�[37mdbug�[39m�[22m�[49m: frame #6: 0x0000000186987bc8 libsystem_pthread.dylib`_pthread_start + 136
�[40m�[37mdbug�[39m�[22m�[49m: thread #6, name = '.NET Debugger'
�[40m�[37mdbug�[39m�[22m�[49m: frame #0: 0x00000001869493cc libsystem_kernel.dylib`__psynch_cvwait + 8
�[40m�[37mdbug�[39m�[22m�[49m: frame #1: 0x000000018698809c libsystem_pthread.dylib`_pthread_cond_wait + 984
�[40m�[37mdbug�[39m�[22m�[49m: frame #2: 0x00000001064b6f6c libcoreclr.dylib`CorUnix::CPalSynchronizationManager::ThreadNativeWait(CorUnix::_ThreadNativeWaitData*, unsigned int, CorUnix::ThreadWakeupReason*, unsigned int*) + 320
�[40m�[37mdbug�[39m�[22m�[49m: frame #3: 0x00000001064b6bec libcoreclr.dylib`CorUnix::CPalSynchronizationManager::BlockThread(CorUnix::CPalThread*, unsigned int, bool, bool, CorUnix::ThreadWakeupReason*, unsigned int*) + 380
�[40m�[37mdbug�[39m�[22m�[49m: frame #4: 0x00000001064bb0cc libcoreclr.dylib`CorUnix::InternalWaitForMultipleObjectsEx(CorUnix::CPalThread*, unsigned int, void* const*, int, unsigned int, int, int) + 1600
�[40m�[37mdbug�[39m�[22m�[49m: frame #5: 0x00000001067adda8 libcoreclr.dylib`DebuggerRCThread::MainLoop() + 228
�[40m�[37mdbug�[39m�[22m�[49m: frame #6: 0x00000001067adc70 libcoreclr.dylib`DebuggerRCThread::ThreadProc() + 256
�[40m�[37mdbug�[39m�[22m�[49m: frame #7: 0x00000001067ada24 libcoreclr.dylib`DebuggerRCThread::ThreadProcStatic(void*) + 56
�[40m�[37mdbug�[39m�[22m�[49m: frame #8: 0x00000001064c20fc libcoreclr.dylib`CorUnix::CPalThread::ThreadEntry(void*) + 364
�[40m�[37mdbug�[39m�[22m�[49m: frame #9: 0x0000000186987bc8 libsystem_pthread.dylib`_pthread_start + 136
�[40m�[37mdbug�[39m�[22m�[49m: thread #7
�[40m�[37mdbug�[39m�[22m�[49m: frame #0: 0x00000001869493cc libsystem_kernel.dylib`__psynch_cvwait + 8
�[40m�[37mdbug�[39m�[22m�[49m: frame #1: 0x000000018698809c libsystem_pthread.dylib`_pthread_cond_wait + 984
�[40m�[37mdbug�[39m�[22m�[49m: frame #2: 0x00000001064b6f6c libcoreclr.dylib`CorUnix::CPalSynchronizationManager::ThreadNativeWait(CorUnix::_ThreadNativeWaitData*, unsigned int, CorUnix::ThreadWakeupReason*, unsigned int*) + 320
�[40m�[37mdbug�[39m�[22m�[49m: frame #3: 0x00000001064b6bec libcoreclr.dylib`CorUnix::CPalSynchronizationManager::BlockThread(CorUnix::CPalThread*, unsigned int, bool, bool, CorUnix::ThreadWakeupReason*, unsigned int*) + 380
�[40m�[37mdbug�[39m�[22m�[49m: frame #4: 0x00000001064bb0cc libcoreclr.dylib`CorUnix::InternalWaitForMultipleObjectsEx(CorUnix::CPalThread*, unsigned int, void* const*, int, unsigned int, int, int) + 1600
�[40m�[37mdbug�[39m�[22m�[49m: frame #5: 0x0000000106608078 libcoreclr.dylib`FinalizerThread::WaitForFinalizerEvent(CLREvent*) + 240
�[40m�[37mdbug�[39m�[22m�[49m: frame #6: 0x00000001066081d8 libcoreclr.dylib`FinalizerThread::FinalizerThreadWorker(void*) + 264
�[40m�[37mdbug�[39m�[22m�[49m: frame #7: 0x00000001065a5fa8 libcoreclr.dylib`ManagedThreadBase_DispatchOuter(ManagedThreadCallState*) + 248
�[40m�[37mdbug�[39m�[22m�[49m: frame #8: 0x00000001065a648c libcoreclr.dylib`ManagedThreadBase::FinalizerBase(void (*)(void*)) + 36
�[40m�[37mdbug�[39m�[22m�[49m: frame #9: 0x0000000106608350 libcoreclr.dylib`FinalizerThread::FinalizerThreadStart(void*) + 88
�[40m�[37mdbug�[39m�[22m�[49m: frame #10: 0x00000001064c20fc libcoreclr.dylib`CorUnix::CPalThread::ThreadEntry(void*) + 364
�[40m�[37mdbug�[39m�[22m�[49m: frame #11: 0x0000000186987bc8 libsystem_pthread.dylib`_pthread_start + 136
�[40m�[37mdbug�[39m�[22m�[49m: thread #8, name = '.NET SigHandler'
�[40m�[37mdbug�[39m�[22m�[49m: frame #0: 0x00000001869467dc libsystem_kernel.dylib`read + 8
�[40m�[37mdbug�[39m�[22m�[49m: frame #1: 0x0000000104bb8e98 libSystem.Native.dylib`SignalHandlerLoop + 96
�[40m�[37mdbug�[39m�[22m�[49m: frame #2: 0x0000000186987bc8 libsystem_pthread.dylib`_pthread_start + 136
�[40m�[37mdbug�[39m�[22m�[49m: thread #9
�[40m�[37mdbug�[39m�[22m�[49m: frame #0: 0x000000018694bd04 libsystem_kernel.dylib`kevent + 8
�[40m�[37mdbug�[39m�[22m�[49m: frame #1: 0x0000000104bb74a4 libSystem.Native.dylib`SystemNative_WaitForSocketEvents + 80
�[40m�[37mdbug�[39m�[22m�[49m: frame #2: 0x000000010b15cb34
�[40m�[37mdbug�[39m�[22m�[49m: frame #3: 0x000000010b15c694
�[40m�[37mdbug�[39m�[22m�[49m: frame #4: 0x000000010b15c544
�[40m�[37mdbug�[39m�[22m�[49m: frame #5: 0x000000010b041388
�[40m�[37mdbug�[39m�[22m�[49m: frame #6: 0x000000010b0411e0
�[40m�[37mdbug�[39m�[22m�[49m: frame #7: 0x000000010b041108
�[40m�[37mdbug�[39m�[22m�[49m: frame #8: 0x0000000106754c04 libcoreclr.dylib`CallDescrWorkerInternal + 132
�[40m�[37mdbug�[39m�[22m�[49m: frame #9: 0x00000001065d2988 libcoreclr.dylib`DispatchCallSimple(unsigned long*, unsigned int, unsigned long long, unsigned int) + 268
�[40m�[37mdbug�[39m�[22m�[49m: frame #10: 0x00000001065e4c6c libcoreclr.dylib`ThreadNative::KickOffThread_Worker(void*) + 148
�[40m�[37mdbug�[39m�[22m�[49m: frame #11: 0x00000001065a5fa8 libcoreclr.dylib`ManagedThreadBase_DispatchOuter(ManagedThreadCallState*) + 248
�[40m�[37mdbug�[39m�[22m�[49m: frame #12: 0x00000001065a645c libcoreclr.dylib`ManagedThreadBase::KickOff(void (*)(void*), void*) + 32
�[40m�[37mdbug�[39m�[22m�[49m: frame #13: 0x00000001065e4d44 libcoreclr.dylib`ThreadNative::KickOffThread(void*) + 172
�[40m�[37mdbug�[39m�[22m�[49m: frame #14: 0x00000001064c20fc libcoreclr.dylib`CorUnix::CPalThread::ThreadEntry(void*) + 364
�[40m�[37mdbug�[39m�[22m�[49m: frame #15: 0x0000000186987bc8 libsystem_pthread.dylib`_pthread_start + 136
�[40m�[37mdbug�[39m�[22m�[49m: thread #10
�[40m�[37mdbug�[39m�[22m�[49m: frame #0: 0x0000000186945c34 libsystem_kernel.dylib`mach_msg2_trap + 8
�[40m�[37mdbug�[39m�[22m�[49m: frame #1: 0x00000001869583a0 libsystem_kernel.dylib`mach_msg2_internal + 76
�[40m�[37mdbug�[39m�[22m�[49m: frame #2: 0x000000018694e764 libsystem_kernel.dylib`mach_msg_overwrite + 484
�[40m�[37mdbug�[39m�[22m�[49m: frame #3: 0x0000000186945fa8 libsystem_kernel.dylib`mach_msg + 24
�[40m�[37mdbug�[39m�[22m�[49m: frame #4: 0x0000000186a72c0c CoreFoundation`__CFRunLoopServiceMachPort + 160
�[40m�[37mdbug�[39m�[22m�[49m: frame #5: 0x0000000186a71528 CoreFoundation`__CFRunLoopRun + 1208
�[40m�[37mdbug�[39m�[22m�[49m: frame #6: 0x0000000186a709e8 CoreFoundation`CFRunLoopRunSpecific + 572
�[40m�[37mdbug�[39m�[22m�[49m: frame #7: 0x0000000188040c78 Foundation`-[NSRunLoop(NSRunLoop) runMode:beforeDate:] + 212
�[40m�[37mdbug�[39m�[22m�[49m: frame #8: 0x0000000104afef28 mlaunch`xamarin_dyn_objc_msgSend + 160
�[40m�[37mdbug�[39m�[22m�[49m: frame #9: 0x000000010b3a7754
�[40m�[37mdbug�[39m�[22m�[49m: frame #10: 0x000000010b3a7618
�[40m�[37mdbug�[39m�[22m�[49m: frame #11: 0x000000010b3a744c
�[40m�[37mdbug�[39m�[22m�[49m: frame #12: 0x000000010b3a43d0
�[40m�[37mdbug�[39m�[22m�[49m: frame #13: 0x000000010b041330
�[40m�[37mdbug�[39m�[22m�[49m: frame #14: 0x000000010b0411e0
�[40m�[37mdbug�[39m�[22m�[49m: frame #15: 0x000000010b041108
�[40m�[37mdbug�[39m�[22m�[49m: frame #16: 0x0000000106754c04 libcoreclr.dylib`CallDescrWorkerInternal + 132
�[40m�[37mdbug�[39m�[22m�[49m: frame #17: 0x00000001065d2988 libcoreclr.dylib`DispatchCallSimple(unsigned long*, unsigned int, unsigned long long, unsigned int) + 268
�[40m�[37mdbug�[39m�[22m�[49m: frame #18: 0x00000001065e4c6c libcoreclr.dylib`ThreadNative::KickOffThread_Worker(void*) + 148
�[40m�[37mdbug�[39m�[22m�[49m: frame #19: 0x00000001065a5fa8 libcoreclr.dylib`ManagedThreadBase_DispatchOuter(ManagedThreadCallState*) + 248
�[40m�[37mdbug�[39m�[22m�[49m: frame #20: 0x00000001065a645c libcoreclr.dylib`ManagedThreadBase::KickOff(void (*)(void*), void*) + 32
�[40m�[37mdbug�[39m�[22m�[49m: frame #21: 0x00000001065e4d44 libcoreclr.dylib`ThreadNative::KickOffThread(void*) + 172
�[40m�[37mdbug�[39m�[22m�[49m: frame #22: 0x00000001064c20fc libcoreclr.dylib`CorUnix::CPalThread::ThreadEntry(void*) + 364
�[40m�[37mdbug�[39m�[22m�[49m: frame #23: 0x0000000186987bc8 libsystem_pthread.dylib`_pthread_start + 136
�[40m�[37mdbug�[39m�[22m�[49m: thread #11
�[40m�[37mdbug�[39m�[22m�[49m: frame #0: 0x00000001869478b0 libsystem_kernel.dylib`__workq_kernreturn + 8
�[40m�[37mdbug�[39m�[22m�[49m: thread #12, name = 'com.apple.CFSocket.private'
�[40m�[37mdbug�[39m�[22m�[49m: frame #0: 0x0000000186950c2c libsystem_kernel.dylib`__select + 8
�[40m�[37mdbug�[39m�[22m�[49m: frame #1: 0x0000000186a98a80 CoreFoundation`__CFSocketManager + 704
�[40m�[37mdbug�[39m�[22m�[49m: frame #2: 0x0000000186987bc8 libsystem_pthread.dylib`_pthread_start + 136
�[40m�[37mdbug�[39m�[22m�[49m: thread #13
�[40m�[37mdbug�[39m�[22m�[49m: frame #0: 0x00000001869478b0 libsystem_kernel.dylib`__workq_kernreturn + 8
�[40m�[37mdbug�[39m�[22m�[49m: (lldb) detach
�[40m�[37mdbug�[39m�[22m�[49m: Process 9317 detached
�[40m�[37mdbug�[39m�[22m�[49m: (lldb) quit
�[40m�[37mdbug�[39m�[22m�[49m: 9317 Execution timed out after 60 seconds and the process was killed.
�[40m�[37mdbug�[39m�[22m�[49m: Process mlaunch exited with 137
�[40m�[37mdbug�[39m�[22m�[49m: Failed to list crash reports from device.
�[40m�[37mdbug�[39m�[22m�[49m: Test run started but crashed and no test results were reported
�[40m�[37mdbug�[39m�[22m�[49m: No crash reports, waiting 30 seconds for the crash report service...
�[41m�[30mfail�[39m�[22m�[49m: Application test run crashed
Failed to launch the application, please try again. If the problem persists, try rebooting MacOS
�[40m�[32minfo�[39m�[22m�[49m: Uninstalling the application 'com.microsoft.maui.controls.devicetests' from 'iPhone 11 Pro'
�[40m�[37mdbug�[39m�[22m�[49m:
�[40m�[37mdbug�[39m�[22m�[49m: Running /Applications/Xcode_26.1.1.app/Contents/Developer/usr/bin/simctl
�[40m�[37mdbug�[39m�[22m�[49m: An error was encountered processing the command (domain=com.apple.CoreSimulator.SimError, code=405):
�[40m�[37mdbug�[39m�[22m�[49m: Unable to lookup in current state: Shutdown
�[40m�[37mdbug�[39m�[22m�[49m: Process simctl exited with 149
�[41m�[30mfail�[39m�[22m�[49m: Failed to uninstall the app bundle! Check logs for more details!
XHarness exit code: 83 (APP_LAUNCH_FAILURE)
Passed: 0
Failed: 0
Tests completed with exit code: 83
🟢 With fix — 📱 ShellTests (SettingFrameDoesTriggerInvalidatedMeasure): PASS ✅ · 214s
Determining projects to restore...
All projects are up-to-date for restore.
##vso[build.updatebuildnumber]10.0.60-ci+azdo.13723433
Graphics -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Graphics/Release/net10.0-ios26.0/Microsoft.Maui.Graphics.dll
##vso[build.updatebuildnumber]10.0.60-ci+azdo.13723433
Essentials -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Essentials/Release/net10.0-ios26.0/Microsoft.Maui.Essentials.dll
##vso[build.updatebuildnumber]10.0.60-ci+azdo.13723433
Core -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Core/Release/net10.0-ios26.0/Microsoft.Maui.dll
TestUtils.DeviceTests -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/TestUtils.DeviceTests/Release/net10.0-ios/Microsoft.Maui.TestUtils.DeviceTests.dll
Controls.BindingSourceGen -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.BindingSourceGen/Release/netstandard2.0/Microsoft.Maui.Controls.BindingSourceGen.dll
##vso[build.updatebuildnumber]10.0.60-ci+azdo.13723433
Controls.Core -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Core/Release/net10.0-ios26.0/Microsoft.Maui.Controls.dll
##vso[build.updatebuildnumber]10.0.60-ci+azdo.13723433
Controls.Xaml -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Xaml/Release/net10.0-ios26.0/Microsoft.Maui.Controls.Xaml.dll
TestUtils.DeviceTests.Runners -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/TestUtils.DeviceTests.Runners/Release/net10.0-ios/Microsoft.Maui.TestUtils.DeviceTests.Runners.dll
Core.DeviceTests.Shared -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Core.DeviceTests.Shared/Release/net10.0-ios/Microsoft.Maui.DeviceTests.Shared.dll
TestUtils.DeviceTests.Runners.SourceGen -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/TestUtils.DeviceTests.Runners.SourceGen/Release/netstandard2.0/Microsoft.Maui.TestUtils.DeviceTests.Runners.SourceGen.dll
Detected signing identity:
Code Signing Key: "" (-)
Provisioning Profile: "" () - no entitlements
Bundle Id: com.microsoft.maui.controls.devicetests
App Id: com.microsoft.maui.controls.devicetests
Controls.DeviceTests -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.DeviceTests/Release/net10.0-ios/iossimulator-arm64/Microsoft.Maui.Controls.DeviceTests.dll
Optimizing assemblies for size may change the behavior of the app. Be sure to test after publishing. See: https://aka.ms/dotnet-illink
Optimizing assemblies for size. This process might take a while.
IL stripping assemblies
Build succeeded.
0 Warning(s)
0 Error(s)
Time Elapsed 00:02:29.16
[11.0.0-prerelease.26107.1+bfbac237157e59cdbd19334325b2af80bd6e9828] XHarness command issued: apple test --app artifacts/bin/Controls.DeviceTests/Release/net10.0-ios/iossimulator-arm64/Microsoft.Maui.Controls.DeviceTests.app --target ios-simulator-64_18.6 --device 755498B8-2E06-4CB4-BEE6-C43F6BDABC49 -o artifacts/log --timeout 01:00:00 -v --set-env=TestFilter=Category=Shell
�[40m�[32minfo�[39m�[22m�[49m: Preparing run for ios-simulator-64_18.6 targeting 755498B8-2E06-4CB4-BEE6-C43F6BDABC49
�[40m�[32minfo�[39m�[22m�[49m: Looking for available ios-simulator-64_18.6 simulators..
�[40m�[37mdbug�[39m�[22m�[49m: Looking for available ios-simulator-64_18.6 simulators. Storing logs into list-ios-simulator-64_18.6-20260402_033249.log
�[40m�[32minfo�[39m�[22m�[49m: Found simulator device 'iPhone 11 Pro'
�[40m�[32minfo�[39m�[22m�[49m: Getting app bundle information from '/Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.DeviceTests/Release/net10.0-ios/iossimulator-arm64/Microsoft.Maui.Controls.DeviceTests.app'..
�[40m�[37mdbug�[39m�[22m�[49m:
�[40m�[37mdbug�[39m�[22m�[49m: Running /usr/libexec/PlistBuddy
�[40m�[37mdbug�[39m�[22m�[49m: Process PlistBuddy exited with 0
�[40m�[37mdbug�[39m�[22m�[49m:
�[40m�[37mdbug�[39m�[22m�[49m: Running /usr/libexec/PlistBuddy
�[40m�[37mdbug�[39m�[22m�[49m: Process PlistBuddy exited with 0
�[40m�[37mdbug�[39m�[22m�[49m:
�[40m�[37mdbug�[39m�[22m�[49m: Running /usr/libexec/PlistBuddy
�[40m�[37mdbug�[39m�[22m�[49m: Process PlistBuddy exited with 0
�[40m�[37mdbug�[39m�[22m�[49m:
�[40m�[37mdbug�[39m�[22m�[49m: Running /usr/libexec/PlistBuddy
�[40m�[37mdbug�[39m�[22m�[49m: Process PlistBuddy exited with 0
�[40m�[32minfo�[39m�[22m�[49m: Uninstalling any previous instance of 'com.microsoft.maui.controls.devicetests' from 'iPhone 11 Pro'
�[40m�[37mdbug�[39m�[22m�[49m:
�[40m�[37mdbug�[39m�[22m�[49m: Running /Applications/Xcode_26.1.1.app/Contents/Developer/usr/bin/simctl
�[40m�[37mdbug�[39m�[22m�[49m: Process simctl exited with 0
�[40m�[32minfo�[39m�[22m�[49m: Application 'com.microsoft.maui.controls.devicetests' was uninstalled successfully
�[40m�[32minfo�[39m�[22m�[49m: Installing application 'Microsoft.Maui.Controls.DeviceTests' on 'iPhone 11 Pro'
�[40m�[37mdbug�[39m�[22m�[49m: Installing '/Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.DeviceTests/Release/net10.0-ios/iossimulator-arm64/Microsoft.Maui.Controls.DeviceTests.app' to 'iPhone 11 Pro' (142.06 MB)
�[40m�[37mdbug�[39m�[22m�[49m:
�[40m�[37mdbug�[39m�[22m�[49m: Running /Users/cloudtest/.nuget/packages/microsoft.dotnet.xharness.cli/11.0.0-prerelease.26107.1/tools/net10.0/any/../../../runtimes/any/native/mlaunch/bin/mlaunch
�[40m�[37mdbug�[39m�[22m�[49m: Using Xcode 26.1.1 found in /Applications/Xcode_26.1.1.app
�[40m�[37mdbug�[39m�[22m�[49m: xcrun simctl list --json --json-output /tmp/tmpfLItR7.tmp
�[40m�[37mdbug�[39m�[22m�[49m: Xamarin.Hosting: No need to boot (already booted): iPhone 11 Pro
�[40m�[37mdbug�[39m�[22m�[49m: Xamarin.Hosting: Installing on iPhone 11 Pro (755498B8-2E06-4CB4-BEE6-C43F6BDABC49) by executing 'xcrun simctl install 755498B8-2E06-4CB4-BEE6-C43F6BDABC49 /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.DeviceTests/Release/net10.0-ios/iossimulator-arm64/Microsoft.Maui.Controls.DeviceTests.app'
�[40m�[37mdbug�[39m�[22m�[49m: Xamarin.Hosting: The bundle id com.microsoft.maui.controls.devicetests was successfully installed.
�[40m�[37mdbug�[39m�[22m�[49m: Process mlaunch exited with 0
�[40m�[32minfo�[39m�[22m�[49m: Application 'Microsoft.Maui.Controls.DeviceTests' was installed successfully on 'iPhone 11 Pro'
�[40m�[32minfo�[39m�[22m�[49m: Starting test run for com.microsoft.maui.controls.devicetests..
�[40m�[37mdbug�[39m�[22m�[49m: *** Executing 'Microsoft.Maui.Controls.DeviceTests' on ios-simulator-64_18.6 'iPhone 11 Pro' ***
�[40m�[37mdbug�[39m�[22m�[49m: Test log server listening on: 0.0.0.0:56170
�[40m�[37mdbug�[39m�[22m�[49m: System log for the 'iPhone 11 Pro' simulator is: /Users/cloudtest/Library/Logs/CoreSimulator/755498B8-2E06-4CB4-BEE6-C43F6BDABC49/system.log
�[40m�[37mdbug�[39m�[22m�[49m: Simulator 'iPhone 11 Pro' is already booted
�[40m�[37mdbug�[39m�[22m�[49m: Scanning log stream for Microsoft.Maui.Controls.DeviceTests into '/Users/cloudtest/vss/_work/1/s/artifacts/log/Microsoft.Maui.Controls.DeviceTests.log'..
�[40m�[37mdbug�[39m�[22m�[49m:
�[40m�[37mdbug�[39m�[22m�[49m: Running /Applications/Xcode_26.1.1.app/Contents/Developer/usr/bin/simctl
�[40m�[37mdbug�[39m�[22m�[49m: Launching the app
�[40m�[37mdbug�[39m�[22m�[49m:
�[40m�[37mdbug�[39m�[22m�[49m: Running /Users/cloudtest/.nuget/packages/microsoft.dotnet.xharness.cli/11.0.0-prerelease.26107.1/tools/net10.0/any/../../../runtimes/any/native/mlaunch/bin/mlaunch
�[40m�[37mdbug�[39m�[22m�[49m: Connection from 127.0.0.1:56179 saving logs to /Users/cloudtest/vss/_work/1/s/artifacts/log/test-ios-simulator-64_18.6-20260402_033253.log
�[40m�[37mdbug�[39m�[22m�[49m: Tests have finished executing
�[40m�[37mdbug�[39m�[22m�[49m: Process mlaunch exited with 0
�[40m�[37mdbug�[39m�[22m�[49m: Test run completed
�[40m�[37mdbug�[39m�[22m�[49m: Process simctl exited with 137
�[40m�[37mdbug�[39m�[22m�[49m:
�[40m�[37mdbug�[39m�[22m�[49m: Running /bin/bash
�[40m�[37mdbug�[39m�[22m�[49m: cp: /Users/cloudtest/Library/Developer/CoreSimulator/Devices/755498B8-2E06-4CB4-BEE6-C43F6BDABC49/data/Containers/Data/Application/9406A8E7-0C74-4833-AA93-FA0929E9E779/Documents/test-results.xml: No such file or directory
�[40m�[37mdbug�[39m�[22m�[49m: Process bash exited with 1
�[40m�[37mdbug�[39m�[22m�[49m: Test run succeeded
�[40m�[37mdbug�[39m�[22m�[49m: No crash reports, waiting 0 seconds for the crash report service...
�[40m�[32minfo�[39m�[22m�[49m: Application finished the test run successfully
�[40m�[32minfo�[39m�[22m�[49m: Tests run: 202 Passed: 202 Inconclusive: 0 Failed: 0 Ignored: 0
�[40m�[32minfo�[39m�[22m�[49m: Uninstalling the application 'com.microsoft.maui.controls.devicetests' from 'iPhone 11 Pro'
�[40m�[37mdbug�[39m�[22m�[49m:
�[40m�[37mdbug�[39m�[22m�[49m: Running /Applications/Xcode_26.1.1.app/Contents/Developer/usr/bin/simctl
�[40m�[37mdbug�[39m�[22m�[49m: Process simctl exited with 0
�[40m�[32minfo�[39m�[22m�[49m: Application 'com.microsoft.maui.controls.devicetests' was uninstalled successfully
XHarness exit code: 0
Passed: 404
Failed: 0
Tests completed successfully
⚠️ Issues found
- ❌ ShellTests (SettingFrameDoesTriggerInvalidatedMeasure) PASSED without fix (should fail) — tests don't catch the bug
📁 Fix files reverted (7 files)
eng/pipelines/ci-copilot.ymlsrc/Controls/src/Core/Compatibility/Handlers/Shell/Android/ShellFlyoutRenderer.cssrc/Controls/src/Core/Compatibility/Handlers/Shell/iOS/ShellRenderer.cssrc/Controls/src/Core/FlyoutPage/FlyoutPage.cssrc/Controls/src/Core/PublicAPI/net-android/PublicAPI.Unshipped.txtsrc/Core/src/Handlers/FlyoutView/FlyoutViewHandler.Android.cssrc/Core/src/Platform/Android/Navigation/NavigationViewFragment.cs
New files (not reverted):
github-merge-flow-release-11.jsonc
|
No longer needed |
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
This PR restores the expected behavior of the
OnSizeAllocatedmethod in Shell, which currently does not get called on either Android or iOS in .NET 10.In previous .NET MAUI versions, OnSizeAllocated would fire on iOS when overridden in Shell, and still works for individual pages like MainPage. However, with .NET 10, the method is never called, which breaks layout-dependent initialization or resizing logic that developers may include in the Shell.
Issues Fixed
Fixes #31055
Fixes #31020