From d47a5250dd275ec17712e4f0b3402ab9bb86d053 Mon Sep 17 00:00:00 2001 From: Martin Zikmund Date: Fri, 9 Oct 2026 12:10:02 +0200 Subject: [PATCH 1/6] Adopt Uno.Sdk tooling Squashed recreation of #862 on current main. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01E8bkzyS24p8CYDWLUPsaPC --- .github/workflows/build.yml | 69 +++++++++++++------ components/Animations/src/MultiTarget.props | 2 +- .../Abstract/Animation{TValue,TKeyFrame}.cs | 6 ++ .../Abstract/KeyFrame{TValue,TKeyFrame}.cs | 3 + .../src/Headers/HeaderBehaviorBase.cs | 3 + components/Behaviors/src/MultiTarget.props | 2 +- components/Collections/src/MultiTarget.props | 2 +- components/ColorPicker/src/MultiTarget.props | 2 +- components/Converters/src/MultiTarget.props | 2 +- .../src/FocusTracker/FocusTracker.cs | 3 + .../DeveloperTools/src/MultiTarget.props | 2 +- components/Extensions/src/MultiTarget.props | 2 +- .../HeaderedControls/src/MultiTarget.props | 2 +- components/Helpers/src/MultiTarget.props | 2 +- .../src/MultiTarget.props | 2 +- .../MetadataControl/src/MultiTarget.props | 2 +- components/Primitives/src/MultiTarget.props | 2 +- .../RangeSelector/src/MultiTarget.props | 2 +- components/Segmented/src/MultiTarget.props | 2 +- .../Segmented/src/Segmented/Segmented.cs | 3 + .../SettingsControls/src/MultiTarget.props | 2 +- .../src/SettingsCard/SettingsCard.cs | 3 + components/Sizers/src/MultiTarget.props | 2 +- .../TabbedCommandBar/src/MultiTarget.props | 2 +- .../TokenizingTextBox/src/MultiTarget.props | 2 +- .../src/TokenizingTextBox.Selection.cs | 3 + .../src/TokenizingTextBox.cs | 3 + components/Triggers/src/MultiTarget.props | 2 +- tooling | 2 +- 29 files changed, 95 insertions(+), 41 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index cb4ad4dd2..e3347c28c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -88,7 +88,7 @@ jobs: fail-fast: false # prevent one matrix pipeline from being cancelled if one fails, we want them all to run to completion. matrix: winui: [2, 3] - multitarget: ['uwp', 'wasdk', 'wasm', 'wpf', 'linuxgtk', 'macos', 'ios', 'android'] + multitarget: ['uwp', 'wasdk', 'wasm', 'wpf', 'win32', 'linux', 'macos', 'ios', 'android'] exclude: # WinUI 2 not supported on wasdk - winui: 2 @@ -96,6 +96,18 @@ jobs: # WinUI 3 not supported on uwp - winui: 3 multitarget: uwp + # wpf is the Uno 5 Skia WPF head, which Uno 6 replaced with win32 + - winui: 3 + multitarget: wpf + # win32 is the Uno 6 Skia desktop head, which has no Uno 5 equivalent + - winui: 2 + multitarget: win32 + include: + # On WinUI 3 the Uno.Sdk head replaces the classic Wasm head, so it rides on the + # existing wasm job as a flag rather than a fake entry in the multitarget axis. + - winui: 3 + multitarget: wasm + unoSdkHead: true # Steps represent a sequence of tasks that will be executed as part of the job steps: @@ -133,9 +145,9 @@ jobs: run: dotnet tool restore - name: Run Uno Check to Install Dependencies - if: ${{ matrix.multitarget != 'wasdk' && matrix.multitarget != 'linuxgtk' && matrix.multitarget != 'wpf' }} + if: ${{ matrix.multitarget != 'wasdk' && matrix.multitarget != 'linux' && matrix.multitarget != 'wpf' && matrix.multitarget != 'win32' && !matrix.unoSdkHead }} run: > - dotnet tool run uno-check + dotnet tool run uno-check --ci --target ${{ matrix.multitarget }} --fix @@ -146,18 +158,26 @@ jobs: --skip vswin --verbose + # The Uno.Sdk head builds desktop/browserwasm/android (iOS is filtered on + # Windows). Install the matching workloads directly instead of uno-check. + - name: Install .NET workloads (Uno.Sdk head) + if: ${{ matrix.unoSdkHead }} + run: dotnet workload install wasm-tools android ios maui + - name: Add msbuild to PATH uses: microsoft/setup-msbuild@v2 with: vs-version: '[17.9,)' # Generate full solution with all projects (sample gallery heads, components, tests) + # The Uno.Sdk head also covers Windows desktop, so it asks for win32 alongside wasm. - name: Generate solution with ${{ matrix.multitarget }} gallery, components and tests working-directory: ./ - run: powershell -version 5.1 -command "./tooling/GenerateAllSolution.ps1 -MultiTargets ${{ matrix.multitarget }} ${{ env.ENABLE_DIAGNOSTICS == 'true' && ' -UseDiagnostics' || '' }} -WinUIMajorVersion ${{ matrix.winui }}" -ErrorAction Stop + run: powershell -version 5.1 -command "./tooling/GenerateAllSolution.ps1 -MultiTargets ${{ matrix.multitarget }}${{ matrix.unoSdkHead && ',win32 -IncludeUnoSdkHead' || '' }} ${{ env.ENABLE_DIAGNOSTICS == 'true' && ' -UseDiagnostics' || '' }} -WinUIMajorVersion ${{ matrix.winui }}" -ErrorAction Stop # Build solution - name: MSBuild + if: ${{ !matrix.unoSdkHead }} run: > msbuild.exe /restore /nowarn:MSB4011 /p:Configuration=Release @@ -166,6 +186,12 @@ jobs: /v:${{ env.MSBUILD_VERBOSITY }} CommunityToolkit.AllComponents.sln + # The Uno.Sdk head is a single project covering desktop/browserwasm/android + # (iOS is filtered on Windows); build it directly with dotnet. + - name: Build Uno.Sdk head + if: ${{ matrix.unoSdkHead }} + run: dotnet build tooling/ProjectHeads/AllComponents/Uno/CommunityToolkit.App.Uno.csproj -p:Configuration=Release ${{ env.ENABLE_DIAGNOSTICS == 'true' && '/bl' || '' }} + # Run tests - name: Setup VSTest Path uses: darenm/setup-vstest@3a16d909a1f3bbc65b52f8270d475d905e7d3e44 @@ -445,7 +471,7 @@ jobs: --api-key ${{ secrets.NUGET_PACKAGE_PUSH_TOKEN }} --skip-duplicate - wasm-linux: + uno-linux: runs-on: ubuntu-latest steps: @@ -460,6 +486,12 @@ jobs: with: global-json-file: global.json + # iOS/maccatalyst aren't installable on Linux (Uno.Sdk filters those TFMs + # there). android + wasm-tools are both required: even a single-TFM build + # restores all of the head's TargetFrameworks, validating net9.0-android. + - name: Install .NET workloads + run: dotnet workload install android wasm-tools + - name: .NET Info (if diagnostics) if: ${{ env.ENABLE_DIAGNOSTICS == 'true' }} run: dotnet --info @@ -468,31 +500,26 @@ jobs: - name: Restore dotnet tools run: dotnet tool restore - - name: Enable WASM TargetFrameworks - shell: pwsh - working-directory: ./${{ env.MULTI_TARGET_DIRECTORY }} - run: ./UseTargetFrameworks.ps1 wasm - + # Generate the full solution with the Uno.Sdk gallery head, components and tests - name: Generate solution shell: pwsh working-directory: ./ - run: ./tooling/GenerateAllSolution.ps1${{ env.ENABLE_DIAGNOSTICS == 'true' && ' -UseDiagnostics' || '' }} + run: ./tooling/GenerateAllSolution.ps1 -MultiTargets wasm,linux -IncludeUnoSdkHead -WinUIMajorVersion 3${{ env.ENABLE_DIAGNOSTICS == 'true' && ' -UseDiagnostics' || '' }} - - name: Install ninja for WASM native dependencies - run: sudo apt-get install ninja-build + - name: Build Uno head (browserwasm) + shell: pwsh + working-directory: ./ + run: dotnet build tooling/ProjectHeads/AllComponents/Uno/CommunityToolkit.App.Uno.csproj -f net9.0-browserwasm -p:Configuration=Release - # Issue with Comment Links currently, see: https://github.com/mrlacey/CommentLinks/issues/38 - # See launch.json configuration file for analogous command we're emulating here to build LINK: ../../.vscode/launch.json:CommunityToolkit.App.Wasm.csproj - - name: dotnet build - working-directory: ./${{ env.HEADS_DIRECTORY }}/AllComponents/Wasm/ - run: dotnet build /r /bl -v:${{ env.MSBUILD_VERBOSITY }} - - # TODO: Do we want to run tests here? Can we do that on linux easily? + - name: Build Uno head (desktop) + shell: pwsh + working-directory: ./ + run: dotnet build tooling/ProjectHeads/AllComponents/Uno/CommunityToolkit.App.Uno.csproj -f net9.0-desktop -p:Configuration=Release - name: Artifact - Diagnostic Logs uses: actions/upload-artifact@v4 if: ${{ (env.ENABLE_DIAGNOSTICS == 'true' || env.COREHOST_TRACE != '') && always() }} with: - name: linux-logs + name: uno-linux-logs path: ./**/*.*log diff --git a/components/Animations/src/MultiTarget.props b/components/Animations/src/MultiTarget.props index c780abffe..aa297d836 100644 --- a/components/Animations/src/MultiTarget.props +++ b/components/Animations/src/MultiTarget.props @@ -4,6 +4,6 @@ MultiTarget is a custom property that indicates which target a project is designed to be built for / run on. Used to create project references, generate solution files, enable/disable TargetFrameworks, and build nuget packages. --> - uwp;wasdk;wpf;wasm;linuxgtk;macos;ios;android; + uwp;wasdk;wpf;win32;wasm;linux;macos;ios;android; diff --git a/components/Animations/src/Xaml/Abstract/Animation{TValue,TKeyFrame}.cs b/components/Animations/src/Xaml/Abstract/Animation{TValue,TKeyFrame}.cs index cc98af6e0..12e845e8d 100644 --- a/components/Animations/src/Xaml/Abstract/Animation{TValue,TKeyFrame}.cs +++ b/components/Animations/src/Xaml/Abstract/Animation{TValue,TKeyFrame}.cs @@ -30,11 +30,14 @@ public TValue? To /// /// Identifies the dependency property. /// + // typeof(TValue?) is only used as dependency property metadata, not for reflective construction. +#pragma warning disable IL2087 public static readonly DependencyProperty ToProperty = DependencyProperty.Register( nameof(To), typeof(TValue?), typeof(Animation), new PropertyMetadata(null)); +#pragma warning restore IL2087 /// /// Gets or sets the optional starting value for the animation. @@ -48,11 +51,14 @@ public TValue? From /// /// Identifies the dependency property. /// + // typeof(TValue?) is only used as dependency property metadata, not for reflective construction. +#pragma warning disable IL2087 public static readonly DependencyProperty FromProperty = DependencyProperty.Register( nameof(From), typeof(TValue?), typeof(Animation), new PropertyMetadata(null)); +#pragma warning restore IL2087 /// /// Gets or sets the optional keyframe collection for the current animation. diff --git a/components/Animations/src/Xaml/Abstract/KeyFrame{TValue,TKeyFrame}.cs b/components/Animations/src/Xaml/Abstract/KeyFrame{TValue,TKeyFrame}.cs index ea5627cec..fbe2fadaa 100644 --- a/components/Animations/src/Xaml/Abstract/KeyFrame{TValue,TKeyFrame}.cs +++ b/components/Animations/src/Xaml/Abstract/KeyFrame{TValue,TKeyFrame}.cs @@ -60,11 +60,14 @@ public TValue? Value /// /// Identifies the dependency property. /// + // typeof(TValue?) is only used as dependency property metadata, not for reflective construction. +#pragma warning disable IL2087 public static readonly DependencyProperty ValueProperty = DependencyProperty.Register( nameof(Value), typeof(TValue?), typeof(KeyFrame), new PropertyMetadata(null)); +#pragma warning restore IL2087 /// /// Gets or sets the optional expression for the current keyframe. diff --git a/components/Behaviors/src/Headers/HeaderBehaviorBase.cs b/components/Behaviors/src/Headers/HeaderBehaviorBase.cs index 57b1c3756..e1eccdf06 100644 --- a/components/Behaviors/src/Headers/HeaderBehaviorBase.cs +++ b/components/Behaviors/src/Headers/HeaderBehaviorBase.cs @@ -184,7 +184,10 @@ private void ScrollViewer_GotFocus(object sender, RoutedEventArgs e) } else { + // Obsolete on WinUI 3/Uno, but required as a fallback where XamlRoot is unavailable (e.g. UWP). +#pragma warning disable CS0618 focusedElement = FocusManager.GetFocusedElement()!; +#pragma warning restore CS0618 } // To prevent Popups (Flyouts...) from triggering the autoscroll, we check if the focused element has a valid parent. diff --git a/components/Behaviors/src/MultiTarget.props b/components/Behaviors/src/MultiTarget.props index b11c19426..7d1e11c3c 100644 --- a/components/Behaviors/src/MultiTarget.props +++ b/components/Behaviors/src/MultiTarget.props @@ -4,6 +4,6 @@ MultiTarget is a custom property that indicates which target a project is designed to be built for / run on. Used to create project references, generate solution files, enable/disable TargetFrameworks, and build nuget packages. --> - uwp;wasdk;wpf;wasm;linuxgtk;macos;ios;android; + uwp;wasdk;wpf;win32;wasm;linux;macos;ios;android; \ No newline at end of file diff --git a/components/Collections/src/MultiTarget.props b/components/Collections/src/MultiTarget.props index b11c19426..7d1e11c3c 100644 --- a/components/Collections/src/MultiTarget.props +++ b/components/Collections/src/MultiTarget.props @@ -4,6 +4,6 @@ MultiTarget is a custom property that indicates which target a project is designed to be built for / run on. Used to create project references, generate solution files, enable/disable TargetFrameworks, and build nuget packages. --> - uwp;wasdk;wpf;wasm;linuxgtk;macos;ios;android; + uwp;wasdk;wpf;win32;wasm;linux;macos;ios;android; \ No newline at end of file diff --git a/components/ColorPicker/src/MultiTarget.props b/components/ColorPicker/src/MultiTarget.props index b11c19426..7d1e11c3c 100644 --- a/components/ColorPicker/src/MultiTarget.props +++ b/components/ColorPicker/src/MultiTarget.props @@ -4,6 +4,6 @@ MultiTarget is a custom property that indicates which target a project is designed to be built for / run on. Used to create project references, generate solution files, enable/disable TargetFrameworks, and build nuget packages. --> - uwp;wasdk;wpf;wasm;linuxgtk;macos;ios;android; + uwp;wasdk;wpf;win32;wasm;linux;macos;ios;android; \ No newline at end of file diff --git a/components/Converters/src/MultiTarget.props b/components/Converters/src/MultiTarget.props index b11c19426..7d1e11c3c 100644 --- a/components/Converters/src/MultiTarget.props +++ b/components/Converters/src/MultiTarget.props @@ -4,6 +4,6 @@ MultiTarget is a custom property that indicates which target a project is designed to be built for / run on. Used to create project references, generate solution files, enable/disable TargetFrameworks, and build nuget packages. --> - uwp;wasdk;wpf;wasm;linuxgtk;macos;ios;android; + uwp;wasdk;wpf;win32;wasm;linux;macos;ios;android; \ No newline at end of file diff --git a/components/DeveloperTools/src/FocusTracker/FocusTracker.cs b/components/DeveloperTools/src/FocusTracker/FocusTracker.cs index 39feacb29..c41c3496a 100644 --- a/components/DeveloperTools/src/FocusTracker/FocusTracker.cs +++ b/components/DeveloperTools/src/FocusTracker/FocusTracker.cs @@ -83,7 +83,10 @@ private void Start() } else { + // Obsolete on WinUI 3/Uno, but required as a fallback where XamlRoot is unavailable (e.g. UWP). +#pragma warning disable CS0618 if (FocusManager.GetFocusedElement() is FrameworkElement element) +#pragma warning restore CS0618 { FocusOnControl(element); } diff --git a/components/DeveloperTools/src/MultiTarget.props b/components/DeveloperTools/src/MultiTarget.props index b11c19426..7d1e11c3c 100644 --- a/components/DeveloperTools/src/MultiTarget.props +++ b/components/DeveloperTools/src/MultiTarget.props @@ -4,6 +4,6 @@ MultiTarget is a custom property that indicates which target a project is designed to be built for / run on. Used to create project references, generate solution files, enable/disable TargetFrameworks, and build nuget packages. --> - uwp;wasdk;wpf;wasm;linuxgtk;macos;ios;android; + uwp;wasdk;wpf;win32;wasm;linux;macos;ios;android; \ No newline at end of file diff --git a/components/Extensions/src/MultiTarget.props b/components/Extensions/src/MultiTarget.props index b11c19426..7d1e11c3c 100644 --- a/components/Extensions/src/MultiTarget.props +++ b/components/Extensions/src/MultiTarget.props @@ -4,6 +4,6 @@ MultiTarget is a custom property that indicates which target a project is designed to be built for / run on. Used to create project references, generate solution files, enable/disable TargetFrameworks, and build nuget packages. --> - uwp;wasdk;wpf;wasm;linuxgtk;macos;ios;android; + uwp;wasdk;wpf;win32;wasm;linux;macos;ios;android; \ No newline at end of file diff --git a/components/HeaderedControls/src/MultiTarget.props b/components/HeaderedControls/src/MultiTarget.props index b11c19426..7d1e11c3c 100644 --- a/components/HeaderedControls/src/MultiTarget.props +++ b/components/HeaderedControls/src/MultiTarget.props @@ -4,6 +4,6 @@ MultiTarget is a custom property that indicates which target a project is designed to be built for / run on. Used to create project references, generate solution files, enable/disable TargetFrameworks, and build nuget packages. --> - uwp;wasdk;wpf;wasm;linuxgtk;macos;ios;android; + uwp;wasdk;wpf;win32;wasm;linux;macos;ios;android; \ No newline at end of file diff --git a/components/Helpers/src/MultiTarget.props b/components/Helpers/src/MultiTarget.props index b11c19426..7d1e11c3c 100644 --- a/components/Helpers/src/MultiTarget.props +++ b/components/Helpers/src/MultiTarget.props @@ -4,6 +4,6 @@ MultiTarget is a custom property that indicates which target a project is designed to be built for / run on. Used to create project references, generate solution files, enable/disable TargetFrameworks, and build nuget packages. --> - uwp;wasdk;wpf;wasm;linuxgtk;macos;ios;android; + uwp;wasdk;wpf;win32;wasm;linux;macos;ios;android; \ No newline at end of file diff --git a/components/LayoutTransformControl/src/MultiTarget.props b/components/LayoutTransformControl/src/MultiTarget.props index b11c19426..7d1e11c3c 100644 --- a/components/LayoutTransformControl/src/MultiTarget.props +++ b/components/LayoutTransformControl/src/MultiTarget.props @@ -4,6 +4,6 @@ MultiTarget is a custom property that indicates which target a project is designed to be built for / run on. Used to create project references, generate solution files, enable/disable TargetFrameworks, and build nuget packages. --> - uwp;wasdk;wpf;wasm;linuxgtk;macos;ios;android; + uwp;wasdk;wpf;win32;wasm;linux;macos;ios;android; \ No newline at end of file diff --git a/components/MetadataControl/src/MultiTarget.props b/components/MetadataControl/src/MultiTarget.props index b11c19426..7d1e11c3c 100644 --- a/components/MetadataControl/src/MultiTarget.props +++ b/components/MetadataControl/src/MultiTarget.props @@ -4,6 +4,6 @@ MultiTarget is a custom property that indicates which target a project is designed to be built for / run on. Used to create project references, generate solution files, enable/disable TargetFrameworks, and build nuget packages. --> - uwp;wasdk;wpf;wasm;linuxgtk;macos;ios;android; + uwp;wasdk;wpf;win32;wasm;linux;macos;ios;android; \ No newline at end of file diff --git a/components/Primitives/src/MultiTarget.props b/components/Primitives/src/MultiTarget.props index b11c19426..7d1e11c3c 100644 --- a/components/Primitives/src/MultiTarget.props +++ b/components/Primitives/src/MultiTarget.props @@ -4,6 +4,6 @@ MultiTarget is a custom property that indicates which target a project is designed to be built for / run on. Used to create project references, generate solution files, enable/disable TargetFrameworks, and build nuget packages. --> - uwp;wasdk;wpf;wasm;linuxgtk;macos;ios;android; + uwp;wasdk;wpf;win32;wasm;linux;macos;ios;android; \ No newline at end of file diff --git a/components/RangeSelector/src/MultiTarget.props b/components/RangeSelector/src/MultiTarget.props index b11c19426..7d1e11c3c 100644 --- a/components/RangeSelector/src/MultiTarget.props +++ b/components/RangeSelector/src/MultiTarget.props @@ -4,6 +4,6 @@ MultiTarget is a custom property that indicates which target a project is designed to be built for / run on. Used to create project references, generate solution files, enable/disable TargetFrameworks, and build nuget packages. --> - uwp;wasdk;wpf;wasm;linuxgtk;macos;ios;android; + uwp;wasdk;wpf;win32;wasm;linux;macos;ios;android; \ No newline at end of file diff --git a/components/Segmented/src/MultiTarget.props b/components/Segmented/src/MultiTarget.props index b11c19426..7d1e11c3c 100644 --- a/components/Segmented/src/MultiTarget.props +++ b/components/Segmented/src/MultiTarget.props @@ -4,6 +4,6 @@ MultiTarget is a custom property that indicates which target a project is designed to be built for / run on. Used to create project references, generate solution files, enable/disable TargetFrameworks, and build nuget packages. --> - uwp;wasdk;wpf;wasm;linuxgtk;macos;ios;android; + uwp;wasdk;wpf;win32;wasm;linux;macos;ios;android; \ No newline at end of file diff --git a/components/Segmented/src/Segmented/Segmented.cs b/components/Segmented/src/Segmented/Segmented.cs index 6fbc6c301..ff85cb42e 100644 --- a/components/Segmented/src/Segmented/Segmented.cs +++ b/components/Segmented/src/Segmented/Segmented.cs @@ -116,7 +116,10 @@ private bool MoveFocus(int adjustment) } else { + // Obsolete on WinUI 3/Uno, but required as a fallback where XamlRoot is unavailable (e.g. UWP). +#pragma warning disable CS0618 return FocusManager.GetFocusedElement() as SegmentedItem; +#pragma warning restore CS0618 } } diff --git a/components/SettingsControls/src/MultiTarget.props b/components/SettingsControls/src/MultiTarget.props index b11c19426..7d1e11c3c 100644 --- a/components/SettingsControls/src/MultiTarget.props +++ b/components/SettingsControls/src/MultiTarget.props @@ -4,6 +4,6 @@ MultiTarget is a custom property that indicates which target a project is designed to be built for / run on. Used to create project references, generate solution files, enable/disable TargetFrameworks, and build nuget packages. --> - uwp;wasdk;wpf;wasm;linuxgtk;macos;ios;android; + uwp;wasdk;wpf;win32;wasm;linux;macos;ios;android; \ No newline at end of file diff --git a/components/SettingsControls/src/SettingsCard/SettingsCard.cs b/components/SettingsControls/src/SettingsCard/SettingsCard.cs index fbfc9e160..3b498128d 100644 --- a/components/SettingsControls/src/SettingsCard/SettingsCard.cs +++ b/components/SettingsControls/src/SettingsCard/SettingsCard.cs @@ -325,7 +325,10 @@ private void CheckVerticalSpacingState(VisualState s) } else { + // Obsolete on WinUI 3/Uno, but required as a fallback where XamlRoot is unavailable (e.g. UWP). +#pragma warning disable CS0618 return FocusManager.GetFocusedElement() as FrameworkElement; +#pragma warning restore CS0618 } } diff --git a/components/Sizers/src/MultiTarget.props b/components/Sizers/src/MultiTarget.props index b11c19426..7d1e11c3c 100644 --- a/components/Sizers/src/MultiTarget.props +++ b/components/Sizers/src/MultiTarget.props @@ -4,6 +4,6 @@ MultiTarget is a custom property that indicates which target a project is designed to be built for / run on. Used to create project references, generate solution files, enable/disable TargetFrameworks, and build nuget packages. --> - uwp;wasdk;wpf;wasm;linuxgtk;macos;ios;android; + uwp;wasdk;wpf;win32;wasm;linux;macos;ios;android; \ No newline at end of file diff --git a/components/TabbedCommandBar/src/MultiTarget.props b/components/TabbedCommandBar/src/MultiTarget.props index b11c19426..7d1e11c3c 100644 --- a/components/TabbedCommandBar/src/MultiTarget.props +++ b/components/TabbedCommandBar/src/MultiTarget.props @@ -4,6 +4,6 @@ MultiTarget is a custom property that indicates which target a project is designed to be built for / run on. Used to create project references, generate solution files, enable/disable TargetFrameworks, and build nuget packages. --> - uwp;wasdk;wpf;wasm;linuxgtk;macos;ios;android; + uwp;wasdk;wpf;win32;wasm;linux;macos;ios;android; \ No newline at end of file diff --git a/components/TokenizingTextBox/src/MultiTarget.props b/components/TokenizingTextBox/src/MultiTarget.props index b11c19426..7d1e11c3c 100644 --- a/components/TokenizingTextBox/src/MultiTarget.props +++ b/components/TokenizingTextBox/src/MultiTarget.props @@ -4,6 +4,6 @@ MultiTarget is a custom property that indicates which target a project is designed to be built for / run on. Used to create project references, generate solution files, enable/disable TargetFrameworks, and build nuget packages. --> - uwp;wasdk;wpf;wasm;linuxgtk;macos;ios;android; + uwp;wasdk;wpf;win32;wasm;linux;macos;ios;android; \ No newline at end of file diff --git a/components/TokenizingTextBox/src/TokenizingTextBox.Selection.cs b/components/TokenizingTextBox/src/TokenizingTextBox.Selection.cs index 0b20a6fee..b13a21c28 100644 --- a/components/TokenizingTextBox/src/TokenizingTextBox.Selection.cs +++ b/components/TokenizingTextBox/src/TokenizingTextBox.Selection.cs @@ -141,7 +141,10 @@ private bool MoveFocusAndSelection(MoveDirection direction) } else { + // Obsolete on WinUI 3/Uno, but required as a fallback where XamlRoot is unavailable (e.g. UWP). +#pragma warning disable CS0618 return FocusManager.GetFocusedElement() as TokenizingTextBoxItem; +#pragma warning restore CS0618 } } diff --git a/components/TokenizingTextBox/src/TokenizingTextBox.cs b/components/TokenizingTextBox/src/TokenizingTextBox.cs index db1dd0122..ea48b3eb1 100644 --- a/components/TokenizingTextBox/src/TokenizingTextBox.cs +++ b/components/TokenizingTextBox/src/TokenizingTextBox.cs @@ -361,7 +361,10 @@ private object GetFocusedElement() } else { + // Obsolete on WinUI 3/Uno, but required as a fallback where XamlRoot is unavailable (e.g. UWP). +#pragma warning disable CS0618 return FocusManager.GetFocusedElement()!; +#pragma warning restore CS0618 } } diff --git a/components/Triggers/src/MultiTarget.props b/components/Triggers/src/MultiTarget.props index b11c19426..7d1e11c3c 100644 --- a/components/Triggers/src/MultiTarget.props +++ b/components/Triggers/src/MultiTarget.props @@ -4,6 +4,6 @@ MultiTarget is a custom property that indicates which target a project is designed to be built for / run on. Used to create project references, generate solution files, enable/disable TargetFrameworks, and build nuget packages. --> - uwp;wasdk;wpf;wasm;linuxgtk;macos;ios;android; + uwp;wasdk;wpf;win32;wasm;linux;macos;ios;android; \ No newline at end of file diff --git a/tooling b/tooling index 394263e10..3433dc511 160000 --- a/tooling +++ b/tooling @@ -1 +1 @@ -Subproject commit 394263e1054cac12c5feb49ae2458f5e13681a68 +Subproject commit 3433dc511a74e20f0ae27cd744bfa8a8dc96636a From 0b1d96b8f6ae8b30c38139529617cb54a4471afa Mon Sep 17 00:00:00 2001 From: Martin Zikmund Date: Fri, 9 Oct 2026 12:10:11 +0200 Subject: [PATCH 2/6] Target Uno Platform 7.0 / .NET 10 for WinUI 3 Matches the tooling: .NET SDK 10.0.401, Uno.Sdk 7.0.0-dev.51, MSBuild.Sdk.Extras 3.0.44. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01E8bkzyS24p8CYDWLUPsaPC --- .github/workflows/build.yml | 8 ++++---- .../samples/TabbedCommandBar.Samples.csproj | 2 +- ...ommunityToolkit.WinUI.Controls.TabbedCommandBar.csproj | 2 +- global.json | 5 +++-- 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e3347c28c..136caf151 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -17,7 +17,7 @@ on: merge_group: env: - DOTNET_VERSION: '9.0.310' # Only used by jobs that cannot access global.json (no checkout/artifact-only jobs) + DOTNET_VERSION: '10.0.401' # Only used by jobs that cannot access global.json (no checkout/artifact-only jobs) ENABLE_DIAGNOSTICS: true MSBUILD_VERBOSITY: normal #COREHOST_TRACE: 1 @@ -488,7 +488,7 @@ jobs: # iOS/maccatalyst aren't installable on Linux (Uno.Sdk filters those TFMs # there). android + wasm-tools are both required: even a single-TFM build - # restores all of the head's TargetFrameworks, validating net9.0-android. + # restores all of the head's TargetFrameworks, validating net10.0-android. - name: Install .NET workloads run: dotnet workload install android wasm-tools @@ -509,12 +509,12 @@ jobs: - name: Build Uno head (browserwasm) shell: pwsh working-directory: ./ - run: dotnet build tooling/ProjectHeads/AllComponents/Uno/CommunityToolkit.App.Uno.csproj -f net9.0-browserwasm -p:Configuration=Release + run: dotnet build tooling/ProjectHeads/AllComponents/Uno/CommunityToolkit.App.Uno.csproj -f net10.0-browserwasm -p:Configuration=Release - name: Build Uno head (desktop) shell: pwsh working-directory: ./ - run: dotnet build tooling/ProjectHeads/AllComponents/Uno/CommunityToolkit.App.Uno.csproj -f net9.0-desktop -p:Configuration=Release + run: dotnet build tooling/ProjectHeads/AllComponents/Uno/CommunityToolkit.App.Uno.csproj -f net10.0-desktop -p:Configuration=Release - name: Artifact - Diagnostic Logs uses: actions/upload-artifact@v4 diff --git a/components/TabbedCommandBar/samples/TabbedCommandBar.Samples.csproj b/components/TabbedCommandBar/samples/TabbedCommandBar.Samples.csproj index 986a36629..e570b08e1 100644 --- a/components/TabbedCommandBar/samples/TabbedCommandBar.Samples.csproj +++ b/components/TabbedCommandBar/samples/TabbedCommandBar.Samples.csproj @@ -1,4 +1,4 @@ - + TabbedCommandBar diff --git a/components/TabbedCommandBar/src/CommunityToolkit.WinUI.Controls.TabbedCommandBar.csproj b/components/TabbedCommandBar/src/CommunityToolkit.WinUI.Controls.TabbedCommandBar.csproj index f97cd6e1e..9d38932ef 100644 --- a/components/TabbedCommandBar/src/CommunityToolkit.WinUI.Controls.TabbedCommandBar.csproj +++ b/components/TabbedCommandBar/src/CommunityToolkit.WinUI.Controls.TabbedCommandBar.csproj @@ -1,4 +1,4 @@ - + TabbedCommandBar Display multiple CommandBars in the same space using tabs, like Microsoft Office's ribbon. diff --git a/global.json b/global.json index 338ca727d..7f21440ea 100644 --- a/global.json +++ b/global.json @@ -1,10 +1,11 @@ { "sdk": { - "version": "9.0.310", + "version": "10.0.401", "rollForward": "latestFeature" }, "msbuild-sdks": { - "MSBuild.Sdk.Extras":"3.0.23" + "MSBuild.Sdk.Extras":"3.0.44", + "Uno.Sdk": "7.0.0-dev.51" } } From aedaf67f813d0e74df6195a4e8ee7c1588ba2fcb Mon Sep 17 00:00:00 2001 From: Martin Zikmund Date: Fri, 9 Oct 2026 12:10:13 +0200 Subject: [PATCH 3/6] Only use the interface-era DependencyObject constraint on Uno 5 DependencyObject is a class in Uno 7, so 'class, DependencyObject' fails with CS0450. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01E8bkzyS24p8CYDWLUPsaPC --- .../src/Tree/DependencyObjectExtensions.cs | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/components/Extensions/src/Tree/DependencyObjectExtensions.cs b/components/Extensions/src/Tree/DependencyObjectExtensions.cs index 7bc8d1b90..7a5b41b65 100644 --- a/components/Extensions/src/Tree/DependencyObjectExtensions.cs +++ b/components/Extensions/src/Tree/DependencyObjectExtensions.cs @@ -32,8 +32,8 @@ public static class DependencyObjectExtensions /// The root element. /// The descendant that was found, or . public static T? FindDescendant(this DependencyObject element) -#if HAS_UNO - where T : class, DependencyObject // Note: In Uno, DependencyObject is an interface, background: https://github.com/unoplatform/uno/issues/25 +#if HAS_UNO && WINUI2 + where T : class, DependencyObject // Note: In Uno 5 and older, DependencyObject is an interface, background: https://github.com/unoplatform/uno/issues/25 #else where T : notnull, DependencyObject #endif @@ -64,7 +64,7 @@ public static class DependencyObjectExtensions /// The predicatee to use to match the descendant nodes. /// The descendant that was found, or . public static T? FindDescendant(this DependencyObject element, Func predicate) -#if HAS_UNO +#if HAS_UNO && WINUI2 where T : class, DependencyObject #else where T : notnull, DependencyObject @@ -85,7 +85,7 @@ public static class DependencyObjectExtensions /// The predicatee to use to match the descendant nodes. /// The descendant that was found, or . public static T? FindDescendant(this DependencyObject element, TState state, Func predicate) -#if HAS_UNO +#if HAS_UNO && WINUI2 where T : class, DependencyObject #else where T : notnull, DependencyObject @@ -105,7 +105,7 @@ public static class DependencyObjectExtensions /// The predicatee to use to match the descendant nodes. /// The descendant that was found, or . private static T? FindDescendant(this DependencyObject element, ref TPredicate predicate) -#if HAS_UNO +#if HAS_UNO && WINUI2 where T : class, DependencyObject #else where T : notnull, DependencyObject @@ -158,7 +158,7 @@ public static class DependencyObjectExtensions /// The root element. /// The descendant (or self) that was found, or . public static T? FindDescendantOrSelf(this DependencyObject element) -#if HAS_UNO +#if HAS_UNO && WINUI2 where T : class, DependencyObject #else where T : notnull, DependencyObject @@ -196,7 +196,7 @@ public static class DependencyObjectExtensions /// The predicatee to use to match the descendant nodes. /// The descendant (or self) that was found, or . public static T? FindDescendantOrSelf(this DependencyObject element, Func predicate) -#if HAS_UNO +#if HAS_UNO && WINUI2 where T : class, DependencyObject #else where T : notnull, DependencyObject @@ -220,7 +220,7 @@ public static class DependencyObjectExtensions /// The predicatee to use to match the descendant nodes. /// The descendant (or self) that was found, or . public static T? FindDescendantOrSelf(this DependencyObject element, TState state, Func predicate) -#if HAS_UNO +#if HAS_UNO && WINUI2 where T : class, DependencyObject #else where T : notnull, DependencyObject @@ -284,7 +284,7 @@ public static IEnumerable FindDescendants(this DependencyObjec /// The starting element. /// The ascendant that was found, or . public static T? FindAscendant(this DependencyObject element) -#if HAS_UNO +#if HAS_UNO && WINUI2 where T : class, DependencyObject #else where T : notnull, DependencyObject @@ -316,7 +316,7 @@ public static IEnumerable FindDescendants(this DependencyObjec /// The predicatee to use to match the ascendant nodes. /// The ascendant that was found, or . public static T? FindAscendant(this DependencyObject element, Func predicate) -#if HAS_UNO +#if HAS_UNO && WINUI2 where T : class, DependencyObject #else where T : notnull, DependencyObject @@ -337,7 +337,7 @@ public static IEnumerable FindDescendants(this DependencyObjec /// The predicatee to use to match the ascendant nodes. /// The ascendant that was found, or . public static T? FindAscendant(this DependencyObject element, TState state, Func predicate) -#if HAS_UNO +#if HAS_UNO && WINUI2 where T : class, DependencyObject #else where T : notnull, DependencyObject @@ -357,7 +357,7 @@ public static IEnumerable FindDescendants(this DependencyObjec /// The predicatee to use to match the ascendant nodes. /// The ascendant that was found, or . private static T? FindAscendant(this DependencyObject element, ref TPredicate predicate) -#if HAS_UNO +#if HAS_UNO && WINUI2 where T : class, DependencyObject #else where T : notnull, DependencyObject @@ -406,7 +406,7 @@ public static IEnumerable FindDescendants(this DependencyObjec /// The starting element. /// The ascendant (or self) that was found, or . public static T? FindAscendantOrSelf(this DependencyObject element) -#if HAS_UNO +#if HAS_UNO && WINUI2 where T : class, DependencyObject #else where T : notnull, DependencyObject @@ -444,7 +444,7 @@ public static IEnumerable FindDescendants(this DependencyObjec /// The predicatee to use to match the ascendant nodes. /// The ascendant (or self) that was found, or . public static T? FindAscendantOrSelf(this DependencyObject element, Func predicate) -#if HAS_UNO +#if HAS_UNO && WINUI2 where T : class, DependencyObject #else where T : notnull, DependencyObject @@ -468,7 +468,7 @@ public static IEnumerable FindDescendants(this DependencyObjec /// The predicatee to use to match the ascendant nodes. /// The ascendant (or self) that was found, or . public static T? FindAscendantOrSelf(this DependencyObject element, TState state, Func predicate) -#if HAS_UNO +#if HAS_UNO && WINUI2 where T : class, DependencyObject #else where T : notnull, DependencyObject From 9daca091d1f4a5ba0485ab87484b5d7d4f528f50 Mon Sep 17 00:00:00 2001 From: Martin Zikmund Date: Fri, 9 Oct 2026 12:10:15 +0200 Subject: [PATCH 4/6] Don't pass a null easing function to InsertExpressionKeyFrame Uno 7 annotates the parameter as non-nullable. Use the overload without easing instead. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01E8bkzyS24p8CYDWLUPsaPC --- .../Animations/src/Expressions/CompositionExtensions.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/components/Animations/src/Expressions/CompositionExtensions.cs b/components/Animations/src/Expressions/CompositionExtensions.cs index 4f508553c..57f182555 100644 --- a/components/Animations/src/Expressions/CompositionExtensions.cs +++ b/components/Animations/src/Expressions/CompositionExtensions.cs @@ -186,7 +186,14 @@ public static void InsertExpressionKeyFrame(this KeyFrameAnimation keyframeAnima { expressionNode.ClearReferenceInfo(); - keyframeAnimation.InsertExpressionKeyFrame(normalizedProgressKey, expressionNode.ToExpressionString(), easing); + if (easing is null) + { + keyframeAnimation.InsertExpressionKeyFrame(normalizedProgressKey, expressionNode.ToExpressionString()); + } + else + { + keyframeAnimation.InsertExpressionKeyFrame(normalizedProgressKey, expressionNode.ToExpressionString(), easing); + } expressionNode.SetAllParameters(keyframeAnimation); } From 2e16dbb9ac871e0f97f09fc5d5d38ea77cc8db69 Mon Sep 17 00:00:00 2001 From: Martin Zikmund Date: Fri, 9 Oct 2026 12:10:17 +0200 Subject: [PATCH 5/6] Match Uno 7's ListViewBaseAutomationPeer.GetChildrenCore signature Uno returns List instead of WinUI's IList, fixed in unoplatform/uno#25141. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01E8bkzyS24p8CYDWLUPsaPC --- .../TokenizingTextBox/src/TokenizingTextBoxAutomationPeer.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/components/TokenizingTextBox/src/TokenizingTextBoxAutomationPeer.cs b/components/TokenizingTextBox/src/TokenizingTextBoxAutomationPeer.cs index ca2f30e4d..fd1f0df2d 100644 --- a/components/TokenizingTextBox/src/TokenizingTextBoxAutomationPeer.cs +++ b/components/TokenizingTextBox/src/TokenizingTextBoxAutomationPeer.cs @@ -110,7 +110,12 @@ protected override object GetPatternCore(PatternInterface patternInterface) /// child elements of the automation peer. /// /// The children elements. +#if HAS_UNO && WINUI3 + // Uno 7 declares ListViewBaseAutomationPeer.GetChildrenCore() as returning List instead of WinUI's IList + protected override List GetChildrenCore() +#else protected override IList GetChildrenCore() +#endif { TokenizingTextBox owner = this.OwningTokenizingTextBox; From ba8f5cc802e509a6b1a08136ad55ca9e8620f559 Mon Sep 17 00:00:00 2001 From: Martin Zikmund Date: Fri, 9 Oct 2026 12:10:18 +0200 Subject: [PATCH 6/6] Bump tooling to Uno 7 Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01E8bkzyS24p8CYDWLUPsaPC --- tooling | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tooling b/tooling index 3433dc511..a1e28b762 160000 --- a/tooling +++ b/tooling @@ -1 +1 @@ -Subproject commit 3433dc511a74e20f0ae27cd744bfa8a8dc96636a +Subproject commit a1e28b7626defa8e9d4025af9b49922c1e1c03bc