Conversation
<!-- 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 Fixes #33532 When a XAML file contains `NaN` as a value (e.g., `Padding="NaN"`), the XAML Source Generator was generating invalid C# code using bare `NaN` instead of `double.NaN`, resulting in: ``` error CS0103: The name 'NaN' does not exist in the current context ``` ### Root Cause The `FormatInvariant()` helper method in `GeneratorHelpers.cs` uses `SymbolDisplay.FormatPrimitive()` which outputs just `"NaN"` for `double.NaN` values, without the required type prefix. ### Fix Updated `FormatInvariant()` to explicitly check for special floating-point values (`NaN`, `PositiveInfinity`, `NegativeInfinity`) for both `double` and `float` types, and return the properly qualified C# literals (e.g., `double.NaN`, `float.PositiveInfinity`). ## Changes ### Modified - `src/Controls/src/SourceGen/GeneratorHelpers.cs` - Added special handling for NaN and Infinity values ### Added Tests - `src/Controls/tests/SourceGen.UnitTests/Maui33532Tests.cs` - 5 SourceGen unit tests for ThicknessConverter with NaN - `src/Controls/tests/Xaml.UnitTests/Issues/Maui33532.xaml[.cs]` - XAML unit test for all inflators ## Testing All new tests pass: - `ThicknessWithSingleNaNValue` - Tests `Padding="NaN"` - `ThicknessWithTwoNaNValues` - Tests `Padding="NaN,NaN"` - `ThicknessWithFourNaNValues` - Tests `Padding="NaN,NaN,NaN,NaN"` - `ThicknessWithMixedNaNAndRegularValues` - Tests `Padding="NaN,10,NaN,20"` - `MarginWithNaNValue` - Tests `Margin="NaN"`
…ow disposal (#33353) <!-- 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 Fixes an intermittent `ObjectDisposedException` crash when exiting MacCatalyst/iOS apps. **Root cause:** When a window closes, `Window.Destroying()` disposes the service provider scope, then iOS/MacCatalyst calls `TraitCollectionDidChange` on view controllers. The override in `ShellSectionRootRenderer` tried to access disposed services, causing the crash. **Architectural improvement:** This PR removes duplicate theme handling code: 1. **REMOVED** `TraitCollectionDidChange` override from `ShellSectionRootRenderer` (Controls layer - Shell-specific) 2. **ENHANCED** `TraitCollectionDidChange` in `PageViewController` (Core layer - applies to ALL pages) with: - `window?.Handler == null` check to detect window destruction before accessing services - try-catch safety net for race conditions **Why this approach:** - Core implementation handles theme changes for all pages (not just Shell) - Window.Handler check proactively detects teardown phase (Handler disconnects before service disposal) - try-catch provides safety net for potential race conditions - Eliminates code duplication across layers **Test added:** `Issue33352` test verifies no crash when `TraitCollectionDidChange` called after window disposal. ### Issues Fixed Fixes #33352 ``` --- ## What Changed from Original | Section | Original | Recommended | Why | |---------|----------|-------------|-----| | **NOTE block** | Missing | Added | Required for user testing | | **Root cause** | Brief mention | Detailed window disposal sequence | Helps future developers understand timing | | **Implementation** | "disabled/removed" | Two-part architectural improvement | Accurately describes both removal AND enhancement | | **PageViewController** | Not mentioned | Detailed enhancement with checks | This is half the fix - must be documented | | **Rationale** | Not provided | "Why this approach" section | Explains architectural decision | | **Test** | Not mentioned | Mentioned with test name | Documents test coverage | --- --------- Co-authored-by: Shane Neuville <shneuvil@microsoft.com>
…ies (#33562) ## Description Fixes an issue where using source-generated bindable properties (created via `[BindableProperty]` attribute) in Style Setters would cause the XAML source generator to fail with error `MAUIG1001: The method or operation is not implemented`. ## Problem When a Style Setter references a source-generated bindable property, `GetBindableProperty()` returns `null` because the property field symbol is not available the same way as for manually-defined bindable properties. The code then called `bpRef.ToFQDisplayString()` on a null reference, causing the failure. Example XAML that failed: ```xml <Style x:Key="MyLabelStyle" TargetType="local:MyLabel"> <Setter Property="MyProperty" Value="Bar" /> </Style> ``` Where `MyProperty` is defined as: ```csharp public partial class MyLabel : Label { [BindableProperty] public partial string MyProperty { get; set; } } ``` ## Solution Added a fallback mechanism in `SetterValueProvider` that: 1. When `GetBindableProperty()` returns null, parses the property name from the Setter's `Property` attribute 2. Resolves the target type from the parent Style/Trigger element 3. Uses `HasBindablePropertyHeuristic` to verify a bindable property exists 4. Constructs the fully-qualified property reference directly (e.g., `global::Namespace.MyLabel.MyPropertyProperty`) ## Testing - All 147 source generator unit tests pass - Verified with repro project that previously failed now builds successfully and generates correct code
### Description of Change Fixes jankiness with using a PanGestureRecognizer to translate a control. <!-- Enter description of the fix in this section --> ### Issues Fixed Fixes #20772 <!-- Are you targeting main? All PRs should target the main branch unless otherwise noted. --> --------- Co-authored-by: Javier Suárez <javiersuarezruiz@hotmail.com> Co-authored-by: Shane Neuville <shneuvil@microsoft.com>
…33442) Removes all `InternalsVisibleTo` attributes that grant the .NET MAUI Community Toolkit access to internal APIs. This reverts the visibility changes previously added in PR #29321 while preserving all other modifications. ### Files Modified - **src/Controls/src/Xaml/Properties/AssemblyInfo.cs** - Removed 6 CommunityToolkit assembly references - **src/Controls/src/Core/Properties/AssemblyInfo.cs** - Removed 6 CommunityToolkit assembly references - **src/Essentials/src/AssemblyInfo/AssemblyInfo.shared.cs** - Removed 5 CommunityToolkit assembly references - **src/Core/src/Properties/AssemblyInfo.cs** - Removed 5 CommunityToolkit assembly references Total: 22 InternalsVisibleTo declarations removed for the following assemblies: - CommunityToolkit.Maui - CommunityToolkit.Maui.Core - CommunityToolkit.Maui.Embedding - CommunityToolkit.Maui.UnitTests - CommunityToolkit.Maui.Markup - CommunityToolkit.Maui.Markup.UnitTests <!-- START COPILOT CODING AGENT SUFFIX --> <!-- START COPILOT ORIGINAL PROMPT --> <details> <summary>Original prompt</summary> > I want to remove the InternalsVisibleTo attribute for all the .NET MAUI Community Toolkit references. We reverted those changes once here: #29321 > > Ignore all the other changes, only add back the removal of the InternalsVisibleTo. Target the main branch. </details> <!-- START COPILOT CODING AGENT TIPS --> --- 💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more [Copilot coding agent tips](https://gh.io/copilot-coding-agent-tips) in the docs. --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: jfversluis <939291+jfversluis@users.noreply.github.com>
…#33621) Syncing with the maui-samples repo: dotnet/maui-samples#724 Accessibility note (iOS / VoiceOver) While investigating this issue, it’s worth noting that setting IsAccessibilityElement = true on the UIViewControllerWrapperView causes VoiceOver to treat the wrapper as a single accessibility element. As a result, all child elements (including individual cells) are no longer exposed to the accessibility tree. This is expected UIKit behavior: An accessibility element replaces its children in the VoiceOver hierarchy. Therefore, I've removed the SemanticProperties.Description="Tags Collection" Fixes #30891 Fixes #30749
…ght when the parent layout changes dynamically, causing incorrect sizing. (#33559) <!-- 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! <!-- !!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING MAIN. !!!!!!! --> ### Root Cause: The issue occurs because of Android RecyclerView reusing ViewHolders with previously measured dimensions and not automatically remeasuring them when only the layout size changes, causing the EmptyView to retain its old dimensions instead of adapting to the new available space. ### Fix Description: The fix involves explicitly forcing the EmptyView to remeasure when the RecyclerView dimensions change by detecting width or height updates, locating the corresponding EmptyView ViewHolder, and requesting a layout pass so it is resized to match the new available space. When the ViewHolder isn't immediately available, the layout request is deferred to the next UI loop iteration. ### Issues Fixed Fixes #33324 ### Tested the behaviour in the following platforms - [x] Android - [x] Windows - [x] iOS - [x] Mac ### Output Screenshot Before Issue Fix | After Issue Fix | |----------|----------| |<video width="100" height="100" alt="Before Fix" src="https://github.com/user-attachments/assets/fcdb9637-56b8-4dd3-8a23-1dc4e881bb36">|<video width="100" height="100" alt="After Fix" src="https://github.com/user-attachments/assets/3ff0bee9-8c80-4d3f-8042-acff1807ece6">|
# PR Changes - MacCatalyst Picker Improvements Fixes #30897 Fixes #30891 ## Overview Improved MacCatalyst Picker implementation with proper focus management ## Changes Made ### 1. **PickerHandler.iOS.cs** - MacCatalyst-specific improvements #### Added UIAlertController instance field - Declared `UIAlertController? pickerController` as an instance field to enable proper dismissal via `Unfocus` command - Allows external code to programmatically close the picker dialog #### Improved picker dismiss logic - Moved picker dismiss logic from event handler to the "Done" button action - Removed `EditingDidEnd` event handler that was causing duplicate dismiss calls - Simplified focus state management by handling it directly in the Done action #### Added MapUnfocus command handler - Implemented `MapUnfocus` method for MacCatalyst to programmatically dismiss the picker - Properly updates `IsFocused` and `IsOpen` states when dismissed - Includes null checks for safety ### 2. **PickerHandler.cs** - Command mapper registration #### Registered Unfocus command for MacCatalyst - Added `#elif MACCATALYST` section to CommandMapper - Registered `nameof(IPicker.Unfocus)` command to enable programmatic picker dismissal on MacCatalyst - Brings MacCatalyst picker behavior in line with Android implementation ## Testing Issue2339 ## Platforms Affected - **MacCatalyst** (primary) - iOS (no behavior changes, shared code) ## Breaking Changes None - this is purely an implementation improvement with no API changes.
…dictive Back Gesture Changes (#33213) <!-- !!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING MAIN. !!!!!!! --> ### Issue Description BlazorWebView back navigation stopped working in .NET 10 on Android. When the user presses the back button while viewing a BlazorWebView with navigable history, the entire page is popped instead of navigating back within the WebView content ### RootCause The AndroidLifecycle.OnBackPressed lifecycle event system introduced for Android 13+ predictive back gesture support intercepts back navigation. Since BlazorWebView doesn't register a handler to check WebView.CanGoBack(), the system pops the entire page instead of allowing the WebView to navigate its internal history first, breaking the back navigation behavior that worked in .NET 9. ### Description of Change PR #32461 introduced distributed back navigation handling for Android 13+ predictive back gesture support. This PR extends that implementation to include BlazorWebView **BlazorWebViewHandler.Android.cs:** Added an `AndroidLifecycle.OnBackPressed` handler in ConnectHandler. The handler checks `WebView.CanGoBack()` to determine whether the BlazorWebView maintains internal navigation history. If history exists, it calls `WebView.GoBack()` and returns true, ensuring the user navigates backwards within the WebView instead of closing the page. If no internal history exists, it returns false, allowing the standard MAUI navigation stack to handle the back action. **LifecycleEventService.cs**: Added `RemoveEvent<TDelegate>` method to properly cleanup lifecycle event handlers and prevent memory leaks when handlers are disconnected. ### Issues Fixed Fixes #32767 ### Tested the behaviour on the following platforms - [x] Android - [ ] Windows - [ ] iOS - [ ] Mac ### Output Screenshot Before Issue Fix | After Issue Fix | |----------|----------| |<video width="300" height="150" alt="Before Fix" src="https://github.com/user-attachments/assets/0d6550f8-115a-4893-bb0c-ee24bff38378">|<video width="300" height="150" alt="After Fix" src="https://github.com/user-attachments/assets/49bf38a5-f7be-4790-8fbb-b29ab96b1ed3">| --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Stephane Delcroix <stephane@delcroix.org> Co-authored-by: Subhiksha Chandrasekaran <subhiksha.c@syncfusion.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! <!-- !!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING MAIN. !!!!!!! --> ### Root Cause of the Issue: - In WinUI, the theme can only be set when the app is started, not while it's running. On the .NET MAUI side, we explicitly update control colors according to the defined styles for the respective theme. As a result, colors were updated correctly for the controls we handled explicitly. - However, controls where we did not explicitly set the colors (e.g., DatePicker/TimePicker backgrounds, Checkbox tick marks, and TitleBar colors) were not updated properly when the theme changed. - This happens because WinUI default colors are tied to the theme at the time the app is launched. For example, if the app starts in Light theme, the WinUI theme is initialized as Light and its colors are applied for the entire lifecycle. These defaults are not refreshed when the theme changes at runtime. - Due to this limitation, theme-related colors (including TitleBar color) were not updated as expected. ### Description of Change - Implemented a common logic to apply the appropriate theme by setting the RequestedTheme on the root view of the Window. This approach is consistent with what is used in the WinUI Gallery repo. - With this change, theme-related colors are correctly refreshed across all child views, resolving both theming inconsistencies and the TitleBar color issue when the app theme is changed. ### Reference: - The implementation is based on the following references. Additionally, there is a known issue in WinUI where updating the theme at runtime does not refresh the TitleBar caption button colors, which requires manual handling. - **Updating Root View RequestedTheme:** https://github.com/microsoft/WinUI-Gallery/blob/96dc185a3a3e488f820d06579d85cb4f480a7089/WinUIGallery/Helpers/ThemeHelper.cs#L62 - **AppWindow TitleBar doesn't update caption button colors correctly when changed while app is running:** https://github.com/microsoft/WinUI-Gallery/blob/96dc185a3a3e488f820d06579d85cb4f480a7089/WinUIGallery/Helpers/TitleBarHelper.cs#L22 ### Screenshot | Before Fix | After Fix | |----------|----------| | <video src="https://github.com/user-attachments/assets/0db22e18-cbcc-4cdc-857e-c1b093497309"> | <video src="https://github.com/user-attachments/assets/2e53efce-4122-4179-93aa-c549ded74878"> | ### 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 #12507 Fixes #22058 Fixes #30518 (Windows) Fixes #30807 Fixes #31819 <!-- Are you targeting main? All PRs should target the main branch unless otherwise noted. --> --------- Co-authored-by: Vignesh-SF3580 <vignesh.nagarajan@syncfusion.com>
…ti-range delegate (#33616) <!-- !!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING MAIN. !!!!!!! --> ### Issue Details On iOS 26, DisplayPromptAsync ignores the maxLength parameter, allowing users to enter an unlimited number of characters beyond the specified limit. ### Root Cause iOS 26 introduced a new delegate method, ShouldChangeCharactersInRanges, which accepts multiple text ranges instead of the older ShouldChangeCharacters method. On iOS 26, the old delegate is no longer invoked, causing MAUI’s maxLength enforcement to break. ### Description of Change A runtime version check was added to use the ShouldChangeCharactersInRanges delegate on iOS 26 and later, and the ShouldChangeCharacters delegate on earlier iOS versions. The new delegate calculates the total text length by summing all range lengths and validating the result against maxLength. Validated the behavior in the following platforms - [x] Android - [x] Windows - [x] iOS - [x] Mac ### Issues Fixed Fixes #33549 ### Test case In the test for DisplayPromptAsync, there is no supported way to type text into the display prompt text fields using Appium. ### Output ScreenShot |Before|After| |--|--| | <video src="https://github.com/user-attachments/assets/e9c48ea5-1dc8-42da-a5a2-b7de13df39cd" >| <video src="https://github.com/user-attachments/assets/5324954b-d4dd-4013-a3c8-3f5c34a845cf">|
<!-- 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 Fixed application crash when dragging an element to the end of a CollectionView with a header on Android. **Root cause:** Android's RecyclerView adapter includes the header at position 0, offsetting all item positions by 1. When reordering items, the code was using adapter positions directly to access the ItemsSource (which doesn't include the header), causing an ArgumentOutOfRangeException. **Fix:** Added header offset calculation when accessing ItemsSource indices: - Uses existing `itemsSource.HasHeader` property to detect header presence - Calculates source indices by subtracting 1 from adapter positions when header is present - Mirrors the existing pattern used for grouped CollectionView (lines 33-38) **Key insight:** RecyclerView adapter indices (includes header) ≠ ItemsSource indices (items only). Must translate between these two index spaces when reordering. **Files changed:** - `ReorderableItemsViewAdapter.cs` - Added header offset calculation (+7 -3 lines) - Test files - Added UI tests to verify fix prevents crash ### Issues Fixed Fixes #17823 --- ## Comparison with Current Description ### Current (Minimal but Accurate) ```markdown ### Description of Change Fixed application crash when dragging an element to the end of a collection on Android. ### Issues Fixed Fixes #17823 ``` ### What's Added 1. ✅ **Required NOTE block** - Enables community testing of artifacts 2. ✅ **Root cause explanation** - Helps future maintainers understand why the bug occurred 3. ✅ **Fix approach details** - Documents the solution pattern for similar issues 4. ✅ **Key insight** - Captures the fundamental concept (index space translation) 5. ✅ **File changes summary** - Quick overview of what was modified ### Why This Matters - **For future agents**: Clear context about the adapter vs. source index pattern - **For community**: Ability to test artifacts before merge - **For maintainers**: Understanding of the fix without reading code - **For similar issues**: Pattern to follow (already used for grouped CollectionView) --- ## Usage Copy the "Enhanced Description with Context" section above and paste it into the PR description on GitHub. The current description is functionally correct - this enhancement adds valuable context without changing accuracy. --------- Co-authored-by: vitvov <vitvov@hotmail.com> Co-authored-by: Gerald Versluis <gerald.versluis@microsoft.com> Co-authored-by: Jakub Florkowski <kubaflo123@gmail.com>
…r popups (#33152) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ### Description of Change This PR fixes VoiceOver accessibility on iOS for Picker, DatePicker, and TimePicker controls. When picker popups open/close, VoiceOver now properly shifts focus using iOS accessibility notifications. **Root cause:** VoiceOver on iOS requires explicit focus notifications via `UIAccessibility.PostNotification(ScreenChanged, view)` when modal UI appears or dismisses. Without these notifications, VoiceOver doesn't know to shift focus, leaving users navigating background controls instead of the picker popup. **Fix:** - Adds `PostAccessibilityFocusNotification()` extension methods in `SemanticExtensions.cs` - Posts `ScreenChanged` notification when picker popups open (in `EditingDidBegin` event) - Posts `ScreenChanged` notification to restore focus when popups close (in `EditingDidEnd` event) - Handles edge cases: null window checks, main thread dispatch for delayed InputView availability **Tests:** UI tests created in `Issue30746.xaml[.cs]` and marked with `ManualReview` category since VoiceOver focus cannot be automated with Appium. Manual testing with VoiceOver enabled confirms proper focus behavior. ### Issues Fixed Fixes #30746
…l) (#33526) <!-- 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! ### Root Cause In `MauiView.GetAdjustedSafeAreaInsets()` on iOS, views that don't implement `ISafeAreaView` or `ISafeAreaView2` (such as `ContentPresenter`, `Border`) were falling through to return `baseSafeArea`. This applied full device safe area insets to views that never opted into safe area handling, causing double-padding when used inside ControlTemplates. ### Description of Change Changed the fallback behavior in `GetAdjustedSafeAreaInsets()` to return `SafeAreaPadding.Empty` instead of `baseSafeArea` for views that don't implement `ISafeAreaView` or `ISafeAreaView2`. **This is a philosophy change:** - **Before:** Safe area applied by default (opt-out model) - **After:** Safe area only applies to views that implement the interfaces (opt-in model) This aligns iOS with Android, where `SafeAreaExtensions.GetSafeAreaView2()` returns `null` for non-safe-area views. ### Key Technical Details **Safe area interfaces (opt-in contract):** - `ISafeAreaView` - Legacy interface with `IgnoreSafeArea` property - `ISafeAreaView2` - Modern interface with per-edge `SafeAreaRegions` control **Views that implement these interfaces (safe area works):** - `ContentPage`, `ContentView`, `Layout`, `ScrollView`, `Border`, `Page` **Views that don't (now return Empty):** - `ContentPresenter`, custom views without interface, third-party controls ### What NOT to Do (for future agents) - ❌ **Don't use Element type in Platform layer** - `src/Core/src/Platform/` cannot reference Controls-layer types like `Element`. Use `IView`, `ISafeAreaView`, `ISafeAreaView2` only. - ❌ **Don't use type name string matching** - Checking `View.GetType().Name.Contains("ContentPresenter")` is brittle - ❌ **Don't check ancestor hierarchy for safe area** - Performance cost and wrong abstraction (safe area is per-edge, not binary) ### Edge Cases | Scenario | Risk | Mitigation | |----------|------|------------| | Legacy layouts (`LegacyLayouts/`) | Low | Already `[Obsolete]` | | Custom views without ISafeAreaView | Medium | Implement interface to opt-in | | GraphicsView/WebView as root | Low | Parent ContentPage handles safe area | ### Issues Fixed Fixes #33458 ### Platforms Tested - [x] iOS - [x] Android - [ ] Windows (no SafeAreaEdges implementation) - [ ] Mac (no SafeAreaEdges implementation) ### Screenshots | Before Fix | After Fix | |------------|-----------| | <img width="350" alt="withoutfix" src="https://github.com/user-attachments/assets/3bd10b79-6472-4e86-b717-d433b56f1f82" /> | <img width="350" alt="withfix" src="https://github.com/user-attachments/assets/d30e8c0c-3918-4528-bbd2-6fb3bba8d766" /> |
### Description of Change This PR hides obsolete FontSize named values (like "Large", "Medium", "Small", etc.) from IDE autocomplete suggestions in XAML. The named font size values have been marked [obsolete](https://learn.microsoft.com/en-us/dotnet/api/microsoft.maui.controls.namedsize?view=net-maui-9.0) since .NET 9. However, the design-time type converter was still suggesting these values in the IDE's IntelliSense, leading users to use them and then receive "Obsolete" warnings - especially when using XAML source generation (MauiXamlInflator=SourceGen). The fix overrides `GetStandardValuesSupported()` to return false and `GetStandardValues()` to return an empty collection in `FontSizeDesignTypeConverter`. This prevents the IDE from suggesting the obsolete named font size values while still allowing them to be used (with appropriate obsolete warnings) for backward compatibility. ### Issues Fixed #33560 see also: #33623 --------- Co-authored-by: Kirill Ovchinnikov <kovchinnikov@microsoft.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…nresponsive (#33256) <!-- !!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING MAIN. !!!!!!! --> ### Issue Details On Windows, when TitleBar.IsVisible is set to false, the system caption buttons (minimize, maximize, close) become unresponsive after resizing the window. ### Description of Change <!-- Enter description of the fix in this section --> Updated WindowRootView.UpdateTitleBarContentSize() to apply passthrough regions only when the TitleBar is visible and to clear them when it is hidden, preventing stale regions from blocking caption button interactions. ### 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 #33171 <!-- 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 | |---------|--------| | **Windows**<br> <video src="https://github.com/user-attachments/assets/6b30d580-ea49-4b5d-9e4c-f6db75897d5d" width="600" height="300"> | **Windows**<br> <video src="https://github.com/user-attachments/assets/52f04718-3f2e-4d5e-985b-72efac175af7" width="600" height="300"> | --------- Co-authored-by: Shane Neuville <shane94@hotmail.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 Footer position calculation in `ShellFlyoutContentRenderer.UpdateFooterPosition()` did not account for `SafeAreaInsets.Bottom`, causing footers with horizontal `StackLayout` to render below the visible area. ```csharp // Before _footerView.Frame = new CGRect(0, View.Frame.Height - footerHeight, footerWidth, footerHeight); // After var footerY = View.Frame.Height - footerHeight - View.SafeAreaInsets.Bottom; _footerView.Frame = new CGRect(0, footerY, footerWidth, footerHeight); ``` Also enabled horizontal orientation in `HeaderFooterShellFlyout` test case that was previously commented out due to this bug. ### Issues Fixed Fixes #26395 > [!WARNING] > > <details> > <summary>Firewall rules blocked me from connecting to one or more addresses (expand for details)</summary> > > #### I tried to connect to the following addresses, but was blocked by firewall rules: > > - `4zjvsblobprodcus390.vsblob.vsassets.io` > - Triggering command: `/home/REDACTED/work/maui/maui/.dotnet/dotnet dotnet restore src/Controls/tests/TestCases.HostApp/Controls.TestCases.HostApp.csproj` (dns block) > > If you need me to access, download, or install something from one of these locations, you can either: > > - Configure [Actions setup steps](https://gh.io/copilot/actions-setup-steps) to set up my environment, which run before the firewall is enabled > - Add the appropriate URLs or hosts to the custom allowlist in this repository's [Copilot coding agent settings](https://github.com/kubaflo/maui/settings/copilot/coding_agent) (admins only) > > </details> <!-- START COPILOT CODING AGENT SUFFIX --> <details> <summary>Original prompt</summary> > can you please work on this #26395 </details> > **Custom agent used: issue-resolver** > Specialized agent for investigating and resolving community-reported .NET MAUI issues through hands-on testing and implementation <!-- START COPILOT CODING AGENT TIPS --> --- 💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more [Copilot coding agent tips](https://gh.io/copilot-coding-agent-tips) in the docs.
) Fixes #28570 Fixes #33139 (I poked around a bit and I think there is indeed an issue in MAUI here. When a control is added to the visual tree, MAUI checks the parent’s BackButtonBehavior and propagates it to the child. The problem is that, at that point, the Command is not yet assigned, so the propagated behavior ends up in an incomplete state. Because BackButtonBehavior depends on bindings and command resolution, its propagation is more complex than that of simple properties. For this reason, it probably shouldn’t be propagated automatically in the same way as other properties.) > [!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! ## Summary This PR provides an **alternative solution** to issue #28570, which was previously fixed via property propagation in PR #28615. The issue: setting `BackButtonBehavior` with `IsVisible="False"` or `IsEnabled="False"` on a Shell in XAML doesn't work - the back button still appears. **This alternative approach uses explicit fallback lookup instead of automatic property propagation**, making the behavior more predictable and avoiding side effects. **Quick verification:** - ✅ Tested on Android - Issue resolved - ✅ Tested on iOS - Issue resolved - ✅ UI tests passing (existing Issue28570 test) - ✅ No propagation side effects <details> <summary><b>📋 Click to expand full PR details</b></summary> ## Problem Statement When a user sets `BackButtonBehavior` on a `Shell` in XAML: ```xml <Shell> <Shell.BackButtonBehavior> <BackButtonBehavior IsVisible="False"/> </Shell.BackButtonBehavior> <!-- Shell content --> </Shell> ``` The back button should be hidden on all child pages, but it still appears. The `BackButtonBehavior` set on the Shell is not being applied to navigated pages. --- ## Original Fix (PR #28615) The merged PR #28615 solved this by adding `BackButtonBehaviorProperty` to the property propagation system in `PropertyPropagationExtensions.cs`: ```csharp if (propertyName == null || propertyName == Shell.BackButtonBehaviorProperty.PropertyName) BaseShellItem.PropagateFromParent(Shell.BackButtonBehaviorProperty, element); ``` **How it works**: Automatically propagates `BackButtonBehavior` from parent (Shell) to child (Page) through the property propagation infrastructure. **Issues with this approach**: 1. **Hidden magic**: Developers don't expect attached properties to propagate automatically 2. **BindingContext conflicts**: Propagation can cause `BindingContext` inheritance issues (as seen in the Sandbox app testing) 3. **Performance**: Checks and propagates on every property change event 4. **Complexity**: Relies on the property propagation system which is already complex --- ## Alternative Solution (This PR) Instead of automatic propagation, this PR implements **explicit fallback lookup**: ### New Method: `GetEffectiveBackButtonBehavior()` ```csharp internal static BackButtonBehavior GetEffectiveBackButtonBehavior(BindableObject page) { if (page == null) return null; // First check if the page has its own BackButtonBehavior var behavior = GetBackButtonBehavior(page); if (behavior != null) return behavior; // Fallback: check if the Shell itself has a BackButtonBehavior if (page is Element element) { var shell = element.FindParentOfType<Shell>(); if (shell != null) { behavior = GetBackButtonBehavior(shell); if (behavior != null) return behavior; } } return null; } ``` ### How It Works 1. **Check page first**: Look for `BackButtonBehavior` on the page itself 2. **Check Shell if not found**: Walk up the tree to find the parent Shell and check its `BackButtonBehavior` 3. **Return what's found**: First match wins (page overrides Shell) ### Where It's Used All call sites that previously used `GetBackButtonBehavior()` now use `GetEffectiveBackButtonBehavior()`: **Cross-platform**: - `Shell.OnBackButtonPressed()` - Windows back button handling - `ShellToolbar.UpdateBackbuttonBehavior()` - Toolbar updates **Android**: - `ShellToolbarTracker.OnClick()` - Back button click - `ShellToolbarTracker.SetPage()` - Page changes - `ShellToolbarTracker.OnPagePropertyChanged()` - Property updates - `ShellToolbarTracker.UpdateDrawerArrowFromBackButtonBehavior()` - Drawer arrow - `ShellToolbarTracker.UpdateToolbarIconAccessibilityText()` - Accessibility **iOS**: - `ShellSectionRenderer` - Back button in navigation - `ShellPageRendererTracker.OnPagePropertyChanged()` - Property updates - `ShellPageRendererTracker.UpdateToolbar()` - Toolbar updates --- ## Advantages of Alternative Approach | Aspect | Propagation (Original) | Fallback Lookup (This PR) | |--------|----------------------|---------------------------| | **Predictability** | Hidden, automatic | Explicit, clear intent | | **BindingContext** | Can cause conflicts | No interference | | **Performance** | Checks on every property change | Only checks when needed | | **Debugging** | Hard to trace | Easy to follow | | **Mental Model** | "Magic happens" | "Check page, then Shell" | | **Side Effects** | Propagation system interactions | None | ### Specific Benefits 1. **No BindingContext Issues**: Avoids the propagation-related `BindingContext` inheritance problems 2. **Clearer Intent**: The code explicitly says "get from page, or fall back to Shell" 3. **Better Performance**: Only performs lookup when `BackButtonBehavior` is actually needed 4. **Easier Maintenance**: No coupling with property propagation infrastructure 5. **Simpler Mental Model**: Developers can understand the lookup logic without knowing propagation internals --- ## Root Cause The original issue existed because Shell's back button handling code only checked the current page for `BackButtonBehavior`: ```csharp var backButtonBehavior = GetBackButtonBehavior(GetVisiblePage()); ``` If the page didn't have a `BackButtonBehavior` set, it would return `null`, even though the Shell had one defined. The code had no fallback mechanism. --- ## Testing ### Before Fix Setting `BackButtonBehavior` on Shell: ```xml <Shell> <Shell.BackButtonBehavior> <BackButtonBehavior IsVisible="False" TextOverride="BackButton"/> </Shell.BackButtonBehavior> </Shell> ``` **Result**: Back button still visible ❌ ### After Fix Same XAML code. **Result**: Back button hidden ✅ ### Test Evidence ```bash # Run Issue28570 test pwsh .github/scripts/BuildAndRunHostApp.ps1 -Platform android -TestFilter "Issue28570" # Output: # >>>>> BackButtonShouldNotBeVisible Start # >>>>> BackButtonShouldNotBeVisible Stop # Passed BackButtonShouldNotBeVisible [1 s] # ✅ All tests passed ``` The test verifies: 1. Navigate to detail page 2. Back button should NOT be visible (because Shell has `IsVisible="False"`) 3. Test uses `App.WaitForNoElement("BackButton")` to confirm --- ## Files Changed ### Core Changes **`src/Controls/src/Core/Shell/Shell.cs`** - ➕ Added `GetEffectiveBackButtonBehavior()` method (lines 200-225) - ✏️ Modified `OnBackButtonPressed()` to use new method (line 1570) **`src/Controls/src/Core/Internals/PropertyPropagationExtensions.cs`** - ➖ Removed `BackButtonBehaviorProperty` propagation (lines 44-45) **`src/Controls/src/Core/ShellToolbar.cs`** - ✏️ Modified `UpdateBackbuttonBehavior()` to use new method (line 134) ### Platform-Specific Changes **Android** - `src/Controls/src/Core/Compatibility/Handlers/Shell/Android/ShellToolbarTracker.cs` - ✏️ Updated 5 call sites to use `GetEffectiveBackButtonBehavior()` - `OnClick()` (line 162) - `SetPage()` (line 258) - `OnPagePropertyChanged()` (line 312) - `UpdateDrawerArrowFromBackButtonBehavior()` (line 410) - `UpdateToolbarIconAccessibilityText()` (line 543) **iOS** - Platform-specific handlers - ✏️ `ShellSectionRenderer.cs` (line 152) - ✏️ `ShellPageRendererTracker.cs` (lines 136, 216) **Total**: 8 files changed, 11 call sites updated --- ## Edge Cases Tested ✅ **BackButtonBehavior on Shell only**: Works (this is the fix) ✅ **BackButtonBehavior on Page only**: Works (page takes precedence) ✅ **BackButtonBehavior on both**: Page overrides Shell (expected behavior) ✅ **No BackButtonBehavior anywhere**: Returns `null` (graceful fallback) ✅ **Multiple navigation levels**: Each page correctly looks up to Shell --- ## Breaking Changes **None**. This is a pure bug fix that makes the documented behavior work correctly. **API Surface**: No public API changes. The new method is `internal`. **Behavior Changes**: - ✅ Previously broken: Setting `BackButtonBehavior` on Shell had no effect - ✅ Now works: Shell's `BackButtonBehavior` applies to child pages as expected --- ## Comparison with Original PR #28615 | | PR #28615 (Propagation) | This PR (Fallback Lookup) | |---|---|---| | **Lines Changed** | +3 lines | +30 lines | | **Approach** | Add to propagation list | Explicit lookup method | | **Call Sites Modified** | 0 | 11 | | **BindingContext Safe** |⚠️ Can cause issues | ✅ No side effects | | **Performance** | Checks on all property changes | Only checks when needed | | **Testability** | Implicit behavior | Explicit behavior | | **Maintainability** | Coupled to propagation | Standalone | While the propagation approach is simpler in terms of lines changed, this alternative provides: - Better separation of concerns - No hidden side effects - More explicit and predictable behavior - Easier to debug and maintain long-term --- ## Migration Notes **For users**: No code changes needed. This fix makes the existing, documented API work correctly. **For maintainers**: If modifying back button handling, use `GetEffectiveBackButtonBehavior()` instead of `GetBackButtonBehavior()` to ensure Shell fallback works. --- ## Test Coverage **Existing test reused**: `Issue28570` test already exists from PR #28615 and passes with this alternative fix. **Test location**: - HostApp: `src/Controls/tests/TestCases.HostApp/Issues/Issue28570.cs` - NUnit: `src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue28570.cs` The test: 1. Creates Shell with `BackButtonBehavior` having `IsVisible="False"` 2. Navigates to detail page 3. Verifies back button is NOT visible using `App.WaitForNoElement("BackButton")` --- ## Related Issues - #28570 - Original issue (this PR fixes) - PR #28615 - Original fix via propagation (this PR provides alternative) --- ## Screenshots/Evidence ### Test Output ``` 🔹 Running UI tests with filter: Issue28570 >>>>> BackButtonShouldNotBeVisible Start >>>>> BackButtonShouldNotBeVisible Stop ✅ All tests passed ╔═══════════════════════════════════════════════╗ ║ Test Summary ║ ╠═══════════════════════════════════════════════╣ ║ Platform: ANDROID ║ ║ Test Filter: Issue28570 ║ ║ Result: SUCCESS ✅ ║ ╚═══════════════════════════════════════════════╝ ``` </details> --- ## Recommendation This alternative fix provides a cleaner, more maintainable solution to issue #28570. While the original PR #28615's propagation approach works, this explicit fallback approach: - ✅ Avoids propagation side effects - ✅ Makes the code more understandable - ✅ Provides better long-term maintainability - ✅ Solves the same issue with the same test passing **Suggested action**: Replace PR #28615 with this alternative approach for the reasons outlined above.
…3726) > [!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 Fixes JavaScript string escaping in `WebViewHelper.EscapeJsString` to properly handle both backslashes and single quotes. ### Changes - Escape backslashes **before** single quotes (order matters for `eval()`) - Prevents potential injection issues when passing strings to JavaScript - Updated unit tests to cover backslash escaping scenarios ## Testing - Unit tests added/updated in `WebViewHelperTests.cs` --------- Co-authored-by: Shane Neuville <shane94@hotmail.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! ### Root Cause The Shell routing system allowed duplicate routes to be registered for sibling elements (e.g., two ShellContent items in the same ShellSection with route "MapPage"). This caused confusing navigation behavior where `OnNavigatedTo` would not be called when navigating between pages with duplicate routes. The user discovered this was the root cause of issue #14000 and requested that MAUI throw an exception when duplicate routes are detected, to prevent this confusing scenario. ### Description of Change Added **sibling-based duplicate route validation**: 1. **`Routing.ValidateForDuplicates(Element, string)`** - New validation method that: - Checks if a route is already assigned to a sibling element (elements with same parent) - Allows same route at different hierarchy levels (e.g., `//one/content` and `//two/content`) - Throws `ArgumentException` with clear error message when duplicate found 2. **`BaseShellItem.Route` property setter** - Now calls validation before setting route 3. **5 comprehensive unit tests** - Verify: - Duplicate sibling routes throw exception - Same route in different parents is allowed (hierarchical routing) - Changing/removing routes frees them for reuse - Reassigning same route to same element is idempotent 4. **Cleanup** - Removed duplicate `AddTopTab()` call in Issue6878 test that would now throw **This is a philosophy change:** - **Before:** Duplicate routes silently accepted, caused confusing behavior - **After:** Duplicate sibling routes rejected immediately with clear error message ### Key Technical Details **Sibling-based validation:** - Only checks duplicates among elements with the same parent (`element.Parent.LogicalChildrenInternal`) - Respects Shell's hierarchical routing structure - No global state needed **Why sibling-based, not global?** - Shell supports hierarchical routing where same route can exist at different levels - Example: `//route1/content` and `//route2/content` are both valid - Global tracking would incorrectly reject this valid scenario ### What NOT to Do (for future agents) - ❌ **Don't use global route tracking (HashSet<string>)** - Breaks Shell's hierarchical routing. Reviewers rejected this approach because same route at different hierarchy levels is valid. - ❌ **Don't use ConcurrentDictionary or shared state** - Not thread-safe and causes lifecycle issues (routes never removed when elements deleted) - ❌ **Don't validate at Shell level** - Validation must be at BaseShellItem.Route setter for immediate feedback ### Issues Fixed Fixes #14000 ### Tested the behavior in the following platforms - [x] Windows - [x] Android - [x] iOS - [x] Mac --------- Co-authored-by: Stephane Delcroix <stephane@delcroix.org>
There was a problem hiding this comment.
Pull request overview
This PR is a broad “candidate” bundle that updates several MAUI subsystems (Shell/navigation, safe-area handling, Windows theming/title bar behavior, Android/BlazorWebView back navigation), plus XAML source-gen fixes and new/updated tests/assets.
Changes:
- Improves platform behavior: iOS/MacCatalyst accessibility & lifecycle safety, Windows title bar interactions/theme propagation, Android gesture/back-navigation handling.
- Updates Shell routing/back-button behavior logic (duplicate route validation; effective BackButtonBehavior lookup).
- Expands test coverage and baselines (new unit/UI tests, WinUI snapshot images, XAML/source-gen tests).
Reviewed changes
Copilot reviewed 74 out of 110 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| src/TestUtils/src/UITest.Appium/HelperExtensions.cs | Adds Windows caption button helpers for WinUI/Appium UI tests. |
| src/Templates/src/templates/maui-mobile/Pages/ProjectDetailPage.xaml | Template tweak to tag selection UI (removes a semantic description). |
| src/Essentials/src/AssemblyInfo/AssemblyInfo.shared.cs | Removes InternalsVisibleTo entries for CommunityToolkit assemblies. |
| src/Core/src/Properties/AssemblyInfo.cs | Removes InternalsVisibleTo entries for CommunityToolkit assemblies. |
| src/Core/src/Platform/iOS/SemanticExtensions.cs | Adds iOS VoiceOver focus notification helpers. |
| src/Core/src/Platform/iOS/PageViewController.cs | Avoids theme updates during teardown; guards disposed service access. |
| src/Core/src/Platform/iOS/MauiView.cs | Adjusts safe-area fallback behavior (legacy ISafeAreaView path). |
| src/Core/src/Platform/Windows/WindowRootView.cs | Adjusts passthrough regions behavior when title bar is hidden. |
| src/Core/src/Platform/Windows/MauiWinUIWindow.cs | Refactors event handlers; alters title bar button color updates. |
| src/Core/src/LifecycleEvents/LifecycleEventService.cs | Adds lifecycle handler removal API (currently internal). |
| src/Core/src/Handlers/WebView/WebViewHelper.cs | Reworks JS string escaping (handles backslashes and line terminators). |
| src/Core/src/Handlers/TimePicker/TimePickerHandler.iOS.cs | Posts VoiceOver focus notifications for TimePicker open/close. |
| src/Core/src/Handlers/Picker/PickerHandler.iOS.cs | Improves MacCatalyst Picker dismissal/unfocus + VoiceOver focus behavior. |
| src/Core/src/Handlers/Picker/PickerHandler.cs | Adds MacCatalyst Unfocus mapping. |
| src/Core/src/Handlers/DatePicker/DatePickerHandler.iOS.cs | Posts VoiceOver focus notifications for DatePicker open/close. |
| src/Controls/tests/Xaml.UnitTests/Issues/Maui33532.xaml.cs | Adds XAML unit test for NaN values generating valid code. |
| src/Controls/tests/Xaml.UnitTests/Issues/Maui33532.xaml | Adds XAML content reproducing NaN parsing/source-gen issue. |
| src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyTitleBarBackgroundColorChange.png | Adds/updates WinUI visual baseline. |
| src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/ToolbarItemsShouldBeVisible.png | Adds/updates WinUI visual baseline. |
| src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/EntryClearButtonColorShouldUpdateOnThemeChange.png | Adds/updates WinUI visual baseline. |
| src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue33688.cs | Adds UI test for BackButtonBehavior with CollectionView ItemsSource change. |
| src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue33458.cs | Adds UI test for safe-area behavior with ControlTemplate/ContentPresenter. |
| src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue33352.cs | Adds (currently commented-out) UI test draft for MacCatalyst exit crash scenario. |
| src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue33324.cs | Adds UI test for CollectionView.EmptyView remeasure on layout changes. |
| src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue33171.cs | Adds Windows UI test for title bar caption button responsiveness. |
| src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue22058.cs | Adds Windows/MacCatalyst UI test for system components following app theme. |
| src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue20772.cs | Adds Android UI test for pan/resize flicker regression. |
| src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue17823.cs | Adds Android UI test for CollectionView reordering with header. |
| src/Controls/tests/TestCases.HostApp/Issues/XFIssue/Issue6878.cs | Removes a top-tab addition in an XF issue repro. |
| src/Controls/tests/TestCases.HostApp/Issues/XFIssue/HeaderFooterShellFlyout.cs | Enables horizontal flyout footer orientation. |
| src/Controls/tests/TestCases.HostApp/Issues/Issue33688.cs | Adds HostApp repro Shell/pages for BackButtonBehavior regression. |
| src/Controls/tests/TestCases.HostApp/Issues/Issue33458.cs | Adds HostApp repro page for safe-area/ControlTemplate scenario. |
| src/Controls/tests/TestCases.HostApp/Issues/Issue33352.cs | Adds HostApp repro page for MacCatalyst exit/theme crash investigation. |
| src/Controls/tests/TestCases.HostApp/Issues/Issue33324.cs | Adds HostApp repro page for EmptyView remeasure issue (Android-focused). |
| src/Controls/tests/TestCases.HostApp/Issues/Issue33171.cs | Adds HostApp repro page for Windows title bar visibility/caption buttons. |
| src/Controls/tests/TestCases.HostApp/Issues/Issue22058.cs | Adds HostApp repro page for Windows title bar theme behavior. |
| src/Controls/tests/TestCases.HostApp/Issues/Issue20772.cs | Adds HostApp repro page for Android pan/resize flicker behavior. |
| src/Controls/tests/TestCases.HostApp/Issues/Issue17823.xaml.cs | Adds HostApp XAML code-behind for reorder-with-header repro. |
| src/Controls/tests/TestCases.HostApp/Issues/Issue17823.xaml | Adds HostApp XAML UI for reorder-with-header repro. |
| src/Controls/tests/SourceGen.UnitTests/Maui33532Tests.cs | Adds source-gen unit tests validating NaN emission as double.NaN. |
| src/Controls/tests/SourceGen.UnitTests/InitializeComponent/BindablePropertyHeuristic.cs | Adds test covering Style Setter + heuristic BP resolution for source-generated BP patterns. |
| src/Controls/tests/Core.UnitTests/WebViewHelperTests.cs | Expands tests to match new JS escaping behavior (slashes/newlines/separators). |
| src/Controls/tests/Core.UnitTests/ShellTests.cs | Adds tests for duplicate sibling route validation and reuse scenarios. |
| src/Controls/tests/Core.Design.UnitTests/FontSizeDesignTypeConverterTests.cs | Adds design-time converter tests for font size standard values behavior. |
| src/Controls/tests/Core.Design.UnitTests/Controls.Core.Design.UnitTests.csproj | Includes new FontSizeDesignTypeConverterTests file. |
| src/Controls/src/Xaml/Properties/AssemblyInfo.cs | Removes InternalsVisibleTo entries for CommunityToolkit assemblies. |
| src/Controls/src/SourceGen/SetterValueProvider.cs | Adds fallback heuristic BP resolution for Setter generation. |
| src/Controls/src/SourceGen/NodeSGExtensions.cs | Refactors target type lookup into shared helper used by source-gen. |
| src/Controls/src/SourceGen/GeneratorHelpers.cs | Formats NaN/Infinity float/double as double.NaN/etc in generated code. |
| src/Controls/src/Core/ShellToolbar.cs | Uses “effective” BackButtonBehavior lookup (fallback to Shell). |
| src/Controls/src/Core/Shell/Shell.cs | Introduces GetEffectiveBackButtonBehavior + uses it for back handling. |
| src/Controls/src/Core/Shell/BaseShellItem.cs | Validates routes for duplicates before setting Routing.Route. |
| src/Controls/src/Core/Routing.cs | Adds sibling duplicate route validation helper. |
| src/Controls/src/Core/PublicAPI/net-maccatalyst/PublicAPI.Unshipped.txt | Records removal of ShellSectionRootRenderer.TraitCollectionDidChange override. |
| src/Controls/src/Core/PublicAPI/net-ios/PublicAPI.Unshipped.txt | Records removal of ShellSectionRootRenderer.TraitCollectionDidChange override. |
| src/Controls/src/Core/Properties/AssemblyInfo.cs | Removes InternalsVisibleTo entries for CommunityToolkit assemblies. |
| src/Controls/src/Core/Platform/GestureManager/GesturePlatformManager.Android.cs | Ensures touch handling sets e.Handled based on OnTouchEvent result. |
| src/Controls/src/Core/Platform/Android/InnerGestureListener.cs | Switches to RawX/RawY for gesture deltas (reduces coordinate drift). |
| src/Controls/src/Core/Platform/AlertManager/AlertManager.iOS.cs | Uses iOS/macOS multi-range callback for MaxLength on newer OS versions. |
| src/Controls/src/Core/Internals/PropertyPropagationExtensions.cs | Stops propagating BackButtonBehaviorProperty via property propagation. |
| src/Controls/src/Core/Handlers/Items/ItemsViewHandler.Android.cs | Forces EmptyView layout update when RecyclerView size changes. |
| src/Controls/src/Core/Handlers/Items/Android/Adapters/ReorderableItemsViewAdapter.cs | Fixes reorder indices when a header is present. |
| src/Controls/src/Core/Compatibility/Handlers/Shell/iOS/ShellSectionRootRenderer.cs | Removes TraitCollectionDidChange override (avoids teardown crash). |
| src/Controls/src/Core/Compatibility/Handlers/Shell/iOS/ShellSectionRenderer.cs | Uses effective BackButtonBehavior lookup when intercepting back navigation. |
| src/Controls/src/Core/Compatibility/Handlers/Shell/iOS/ShellPageRendererTracker.cs | Uses effective BackButtonBehavior lookup when syncing nav items. |
| src/Controls/src/Core/Compatibility/Handlers/Shell/iOS/ShellFlyoutContentRenderer.cs | Adjusts flyout footer frame for SafeAreaInsets.Bottom. |
| src/Controls/src/Core/Compatibility/Handlers/Shell/Android/ShellToolbarTracker.cs | Uses effective BackButtonBehavior lookup across toolbar/back logic. |
| src/Controls/src/Core/Application/Application.cs | Adds Windows hooks for theme changes and window added/removed callbacks. |
| src/Controls/src/Core/Application/Application.Windows.cs | Applies theme + title bar button colors across windows on Windows. |
| src/Controls/src/Core.Design/FontSizeDesignTypeConverter.cs | Disables standard values to avoid IDE suggesting obsolete names. |
| src/BlazorWebView/tests/DeviceTests/Elements/BlazorWebViewTests.BackNavigation.cs | Adds Android device tests verifying back handler lifecycle registration/cleanup. |
| src/BlazorWebView/src/Maui/PublicAPI/net-android/PublicAPI.Unshipped.txt | Records BlazorWebViewHandler.ConnectHandler override. |
| src/BlazorWebView/src/Maui/Android/BlazorWebViewHandler.Android.cs | Adds Android back handling (OnBackPressed + predictive back integration). |
| src/BlazorWebView/src/Maui/Android/BlazorAndroidWebView.cs | Tracks whether Back navigation was handled in OnKeyDown. |
| .github/agent-pr-session/pr-33152.md | Adds agent session notes (PR review record). |
| .github/agent-pr-session/pr-33127.md | Adds agent session notes (PR review record). |
| .github/agent-pr-session/issue-33352.md | Adds agent session notes (issue exploration record). |
| await Task.Delay(1000); // Slight delay to apply the theme change | ||
|
|
There was a problem hiding this comment.
Same as above: a fixed Task.Delay before VerifyScreenshot is prone to flakiness. Prefer VerifyScreenshot(retryTimeout: ...) or waiting on a concrete UI signal that the theme change has applied.
| /// Tests if the Windows maximize/restore button is accessible and responsive | ||
| /// </summary> | ||
| /// <param name="app">The Windows app instance</param> | ||
| /// <param name="clickButton">Whether to actually click the maximize button (default: false)</param> | ||
| /// <returns>True if the maximize/restore button is accessible and responsive</returns> |
There was a problem hiding this comment.
The XML doc for TapMaximizeButton doesn’t match the method signature/behavior: it mentions a clickButton parameter and a boolean return value, but the method is void and always clicks when found. Please update the doc (or adjust the signature) so it accurately reflects what the method does.
| SelectionChangedCommand="{Binding SelectionChangedCommand}" | ||
| SelectionChangedCommandParameter="{Binding SelectedTags}" | ||
| SemanticProperties.Description="Tags Collection"> | ||
| SelectionChangedCommandParameter="{Binding SelectedTags}"> |
There was a problem hiding this comment.
Removing SemanticProperties.Description here looks like an accessibility regression for screen readers (the tag selector loses its spoken description). If this was removed intentionally, consider replacing it with an equivalent description elsewhere; otherwise please restore it.
| @@ -0,0 +1,29 @@ | |||
| #if IOS || ANDROID | |||
There was a problem hiding this comment.
This UITest is wrapped in #if IOS || ANDROID, but the issue/page is marked as iOS-only. Including Android here risks running the test on Android where the scenario may not apply (or may behave differently/flakily). Consider restricting this to iOS only (or updating the issue/page metadata if Android is also affected).
| await Task.Delay(1000); // Slight delay to apply the theme change | ||
| VerifyScreenshot(includeTitleBar: true); |
There was a problem hiding this comment.
Using a fixed Task.Delay before VerifyScreenshot is likely to introduce flakiness; the test infra already supports VerifyScreenshot(retryTimeout: ...) for animations/theme propagation. Consider removing the delay and using retryTimeout (and/or a specific WaitFor... condition) instead.
| internal void RemoveEvent<TDelegate>(string eventName, TDelegate action) | ||
| where TDelegate : Delegate | ||
| { | ||
| if (_mapper.TryGetValue(eventName, out var delegates) && delegates != null) | ||
| { |
There was a problem hiding this comment.
LifecycleEventService.RemoveEvent is internal, but it’s being called from the BlazorWebView project (different assembly). This won’t compile unless the method is made public (and added to PublicAPI) or the removal functionality is exposed via a public API (e.g., on ILifecycleEventService).
| // Clean up lifecycle event handler to prevent memory leaks | ||
| if (_onBackPressedHandler != null) | ||
| { | ||
| var lifecycleService = TryGetLifecycleEventService(); | ||
| if (lifecycleService != null) | ||
| { | ||
| lifecycleService.RemoveEvent(nameof(AndroidLifecycle.OnBackPressed), _onBackPressedHandler); | ||
| _onBackPressedHandler = null; | ||
| } |
There was a problem hiding this comment.
This call uses LifecycleEventService.RemoveEvent, but that method is internal in the Core project. Since BlazorWebView is a different assembly, this should not compile. Either make RemoveEvent public (and update PublicAPI) or remove the dependency on the internal method (e.g., by extending ILifecycleEventService or tracking registrations differently).
| // Clean up lifecycle event handler to prevent memory leaks | |
| if (_onBackPressedHandler != null) | |
| { | |
| var lifecycleService = TryGetLifecycleEventService(); | |
| if (lifecycleService != null) | |
| { | |
| lifecycleService.RemoveEvent(nameof(AndroidLifecycle.OnBackPressed), _onBackPressedHandler); | |
| _onBackPressedHandler = null; | |
| } | |
| if (_onBackPressedHandler != null) | |
| { | |
| _onBackPressedHandler = null; |
| BackNavigationHandled = false; | ||
| return false; |
There was a problem hiding this comment.
For non-Back keys, this override currently resets BackNavigationHandled and returns false, which bypasses base.OnKeyDown and can break default key handling (e.g., keyboard navigation/shortcuts). Consider returning base.OnKeyDown(keyCode, e) when you don’t handle the event, while still resetting BackNavigationHandled appropriately.
| BackNavigationHandled = false; | |
| return false; | |
| BackNavigationHandled = false; | |
| return base.OnKeyDown(keyCode, e); |
| #if WINDOWS // TimePicker pop up is only supported on Windows | ||
| App.Tap("TimePickerControl"); | ||
| #endif |
There was a problem hiding this comment.
Inline #if WINDOWS inside the test method makes the test flow harder to follow and goes against the repo’s UI test pattern of hiding platform-specific behavior behind helper/extension methods. Consider moving the platform-specific tap into an App helper (or a test extension) so the test method stays platform-agnostic.
|
/rebase |
…dableProperty - Candidate Failure Feb 2nd (#33854) ### Root Cause of the issue - The SourceGen XAML inflator was silently failing when a Setter referenced a **non-BindableProperty**/ Property doesn't exist, while XamlC and Runtime inflators correctly reported errors. The Problem: XamlC behavior (compile-time): Throws BuildException when encountering <Setter Property="NonBindable" /> on a property that isn't a BindableProperty Runtime inflator behavior: Throws XamlParseException for the same invalid XAML SourceGen behavior (BEFORE fix): SetterValueProvider.TryProvideValue() would detect the property can't be resolved Returns `false` without reporting any diagnostic **Silently fails - no error message to the developer** Test expected (`ShouldThrow(inflator: SourceGen`) Assert.NotEmpty(result.Diagnostics) but got empty diagnostics ❌ Why It Failed Silently: When TryGetBindablePropertyNameAndType() returns false (property not found): ### Description of Change - Detects failure: When TryGetBindablePropertyNameAndType returns false (property doesn't exist or isn't a BindableProperty) Reports diagnostic: Uses Descriptors.MemberResolution (MAUIX2002) - the standard "cannot resolve member" error Provides context: Exact location in XAML file (line/column) Property name that failed to resolve Consistent behavior: Now all three inflators report errors for invalid Setter properties: ✅ XamlC → BuildException ✅ Runtime → XamlParseException ✅ SourceGen → Diagnostic (MAUIX2002) ### Unit Test case failed **ShouldThrow(inflator: SourceGen** https://dev.azure.com/dnceng-public/public/_build/results?buildId=1272666&view=ms.vss-test-web.build-test-results-tab&runId=35509658&resultId=101501&paneView=debug Test location: https://github.com/dotnet/maui/blob/inflight/candidate/src/Controls/tests/Xaml.UnitTests/Validation/SetterOnNonBP.rt.xaml.cs#L22 ### Issues Fixed Fixes #33562 ### Screenshot | Before Issue Fix | After Issue Fix | |----------|----------| | <img width="400" height="500" src="https://github.com/user-attachments/assets/8128a742-460a-48fa-82bb-d310b80f688c"/> | <img width="400" height="500" src="https://github.com/user-attachments/assets/196f856b-9d45-4604-adc9-ae233ac09b1f"> |
<!-- 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 Enables XAML Source Generator (XSG) on the `Controls.ManualTests` project by setting `MauiXamlInflator=SourceGen`. ## Changes - Added `<MauiXamlInflator>SourceGen</MauiXamlInflator>` to enable XAML Source Generator for better performance and debugging - Added `NoWarn="0612"` for `HeaderFooterAddClearPage.xaml` which uses deprecated `NamedSize` (`FontSize="Title"`) ## Testing - Built and ran on MacCatalyst successfully
.NET MAUI inflight/candidate introduces significant improvements across all platforms with focus on quality, performance, and developer experience. This release includes 20 commits with various improvements, bug fixes, and enhancements.
Blazor
Fix for BlazorWebView Back Navigation Issues on Android 13+ After Predictive Back Gesture Changes by @SuthiYuvaraj in Fix for BlazorWebView Back Navigation Issues on Android 13+ After Predictive Back Gesture Changes #33213
🔧 Fixes
CollectionView
[Android] Fix for CollectionView.EmptyView does not remeasure its height when the parent layout changes dynamically, causing incorrect sizing. by @BagavathiPerumal in [Android] Fix for CollectionView.EmptyView does not remeasure its height when the parent layout changes dynamically, causing incorrect sizing. #33559
🔧 Fixes
CollectionView.EmptyViewdoes not remeasure its height when the parent layout changes dynamically, causing incorrect sizing.[Android] Fixed CollectionView reordering last item by @vitalii-vov in [Android] Fixed CollectionView reordering last item #17825
🔧 Fixes
DateTimePicker
[iOS] Fix VoiceOver focus not shifting to Picker/DatePicker/TimePicker popups by @kubaflo in [iOS] Fix VoiceOver focus not shifting to Picker/DatePicker/TimePicker popups #33152
🔧 Fixes
Dialogalert
[iOS 26] Fix DisplayPromptAsync maxLength not enforced due to new multi-range delegate by @Shalini-Ashokan in [iOS 26] Fix DisplayPromptAsync maxLength not enforced due to new multi-range delegate #33616
🔧 Fixes
Flyout
[iOS] Shell: Account for SafeArea when positioning flyout footer by @kubaflo in [iOS] Shell: Account for SafeArea when positioning flyout footer #32891
🔧 Fixes
Fonts
Gestures
Android pan fixes by @BurningLights in Android pan fixes #21547
🔧 Fixes
Navigation
Shell: Add duplicate route validation for sibling elements by @SubhikshaSf4851 in Shell: Add duplicate route validation for sibling elements #32296
🔧 Fixes
Picker
Improved Unfocus support for Picker on Mac Catalyst by @kubaflo in Improved Unfocus support for Picker on Mac Catalyst #33127
🔧 Fixes
SafeArea
[iOS] SafeArea: Return Empty for non-ISafeAreaView views (opt-in model) by @praveenkumarkarunanithi in [iOS] SafeArea: Return Empty for non-ISafeAreaView views (opt-in model) #33526
🔧 Fixes
Shell
[iOS] Fix ObjectDisposedException in TraitCollectionDidChange on window disposal by @jeremy-visionaid in [iOS] Fix ObjectDisposedException in TraitCollectionDidChange on window disposal #33353
🔧 Fixes
[Issue-Resolver] Explicit fallback for BackButtonBehavior lookup by @kubaflo in [Issue-Resolver] Explicit fallback for BackButtonBehavior lookup #33204
🔧 Fixes
Templates
[Templates] Remove redundant SemanticProperties.Description attribute by @kubaflo in [Templates] Remove redundant SemanticProperties.Description attribute #33621
🔧 Fixes
Theme
[Windows] Fix runtime theme update for controls and TitleBar by @Tamilarasan-Paranthaman in [Windows] Fix runtime theme update for controls and TitleBar #31714
🔧 Fixes
Switchis invisible onPointOverwhen theme has changedTheming
Titlebar
[Windows] Fix TitleBar.IsVisible = false the caption buttons become unresponsive by @devanathan-vaithiyanathan in [Windows] Fix TitleBar.IsVisible = false the caption buttons become unresponsive #33256
🔧 Fixes
WebView
Xaml
[XSG] Fix NaN value in XAML generating invalid code by @StephaneDelcroix in [XSG] Fix NaN value in XAML generating invalid code #33533
🔧 Fixes
📦 Other (1)