diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index b31b01580..17e8c9dfc 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -3,7 +3,7 @@ "isRoot": true, "tools": { "uno.check": { - "version": "1.33.1", + "version": "1.34.1", "commands": [ "uno-check" ] diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 81ff65cb0..8c783dd48 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -72,7 +72,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 @@ -80,6 +80,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 env: MULTI_TARGET_DIRECTORY: tooling/MultiTarget @@ -167,7 +179,7 @@ jobs: run: dotnet tool restore - name: Run Uno Check to Install Dependencies - if: ${{ matrix.multitarget != 'wasdk' && matrix.multitarget != 'linuxgtk' && matrix.multitarget != 'wpf' && env.HAS_BUILDABLE_COMPONENTS == 'true' }} + if: ${{ matrix.multitarget != 'wasdk' && matrix.multitarget != 'linux' && matrix.multitarget != 'wpf' && matrix.multitarget != 'win32' && !matrix.unoSdkHead && env.HAS_BUILDABLE_COMPONENTS == 'true' }} run: > dotnet tool run uno-check --ci @@ -180,6 +192,18 @@ jobs: --skip vswin --verbose + # uno-check pins Microsoft.Android.Sdk 36.1.2, under which the Uno 7 Android head restores a + # Mono win-x64 runtime pack that doesn't exist (NU1102); update to the current workload manifests. + - name: Update the Android workload (WinUI 3) + if: ${{ matrix.winui == 3 && matrix.multitarget == 'android' && env.HAS_BUILDABLE_COMPONENTS == 'true' }} + run: dotnet workload update + + # 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 && env.HAS_BUILDABLE_COMPONENTS == 'true' }} + run: dotnet workload install wasm-tools android ios maui + - name: Add msbuild to PATH uses: microsoft/setup-msbuild@v2 if: ${{ env.HAS_BUILDABLE_COMPONENTS == 'true' }} @@ -191,11 +215,11 @@ jobs: - name: Generate solution with ${{ matrix.multitarget }} gallery, components and tests working-directory: ./ if: ${{ env.HAS_BUILDABLE_COMPONENTS == 'true' }} - run: powershell -version 5.1 -command "./tooling/GenerateAllSolution.ps1 -MultiTargets ${{ matrix.multitarget }} ${{ env.ENABLE_DIAGNOSTICS == 'true' && ' -UseDiagnostics' || '' }} -Components ${{ env.CHANGED_COMPONENTS_LIST }} -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' || '' }} -Components ${{ env.CHANGED_COMPONENTS_LIST }} -WinUIMajorVersion ${{ matrix.winui }}" -ErrorAction Stop # Build solution - name: MSBuild (With diagnostics) - if: ${{ env.ENABLE_DIAGNOSTICS == 'true' && env.HAS_BUILDABLE_COMPONENTS == 'true' }} + if: ${{ env.ENABLE_DIAGNOSTICS == 'true' && env.HAS_BUILDABLE_COMPONENTS == 'true' && !matrix.unoSdkHead }} run: > msbuild.exe /restore /nowarn:MSB4011 /p:Configuration=Release @@ -205,9 +229,15 @@ jobs: CommunityToolkit.AllComponents.sln - name: MSBuild - if: ${{ env.ENABLE_DIAGNOSTICS == 'false' && env.HAS_BUILDABLE_COMPONENTS == 'true' }} + if: ${{ env.ENABLE_DIAGNOSTICS == 'false' && env.HAS_BUILDABLE_COMPONENTS == 'true' && !matrix.unoSdkHead }} run: msbuild.exe CommunityToolkit.AllComponents.sln /restore /nowarn:MSB4011 -p:Configuration=Release + # 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 && env.HAS_BUILDABLE_COMPONENTS == 'true' }} + 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 @@ -482,7 +512,7 @@ jobs: --api-key ${{ secrets.NUGET_PACKAGE_PUSH_TOKEN }} --skip-duplicate - wasm-linux: + uno-linux: runs-on: ubuntu-latest env: HEADS_DIRECTORY: tooling/ProjectHeads @@ -502,6 +532,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 net10.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 @@ -510,27 +546,27 @@ jobs: - name: Restore dotnet tools run: dotnet tool restore + # 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 net10.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 /p:UnoSourceGeneratorUseGenerationHost=true /p:UnoSourceGeneratorUseGenerationController=false - - # 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 net10.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/Adorners/src/MultiTarget.props b/components/Adorners/src/MultiTarget.props index b11c19426..7d1e11c3c 100644 --- a/components/Adorners/src/MultiTarget.props +++ b/components/Adorners/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/GradientSlider/src/MultiTarget.props b/components/GradientSlider/src/MultiTarget.props index b11c19426..7d1e11c3c 100644 --- a/components/GradientSlider/src/MultiTarget.props +++ b/components/GradientSlider/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/MarkdownTextBlock/samples/MarkdownTextBlockExampleSample.xaml.cs b/components/MarkdownTextBlock/samples/MarkdownTextBlockExampleSample.xaml.cs index 0e5019958..4ebf2e5f5 100644 --- a/components/MarkdownTextBlock/samples/MarkdownTextBlockExampleSample.xaml.cs +++ b/components/MarkdownTextBlock/samples/MarkdownTextBlockExampleSample.xaml.cs @@ -3,7 +3,6 @@ // See the LICENSE file in the project root for more information. using CommunityToolkit.WinUI.Controls; -using System.Diagnostics; namespace MarkdownTextBlockExperiment.Samples; @@ -607,6 +606,6 @@ public MarkdownTextBlockExampleSample() private void MarkdownTextBlock_OnLinkClicked(object? sender, LinkClickedEventArgs e) { - Debug.WriteLine($"Link Clicked: {e.Uri}"); + System.Diagnostics.Debug.WriteLine($"Link Clicked: {e.Uri}"); } } diff --git a/components/MarkdownTextBlock/samples/MarkdownTextBlockLiveEditorSample.xaml.cs b/components/MarkdownTextBlock/samples/MarkdownTextBlockLiveEditorSample.xaml.cs index f38598772..434f3bfba 100644 --- a/components/MarkdownTextBlock/samples/MarkdownTextBlockLiveEditorSample.xaml.cs +++ b/components/MarkdownTextBlock/samples/MarkdownTextBlockLiveEditorSample.xaml.cs @@ -3,7 +3,6 @@ // See the LICENSE file in the project root for more information. using CommunityToolkit.WinUI.Controls; -using System.Diagnostics; namespace MarkdownTextBlockExperiment.Samples; @@ -43,6 +42,6 @@ Try typing some **markdown** here! private void MarkdownTextBlock_OnLinkClicked(object? sender, LinkClickedEventArgs e) { - Debug.WriteLine($"Link Clicked: {e.Uri}"); + System.Diagnostics.Debug.WriteLine($"Link Clicked: {e.Uri}"); } } diff --git a/components/MarkdownTextBlock/src/CommunityToolkit.WinUI.Controls.MarkdownTextBlock.csproj b/components/MarkdownTextBlock/src/CommunityToolkit.WinUI.Controls.MarkdownTextBlock.csproj index f9a01416e..8f88739bf 100644 --- a/components/MarkdownTextBlock/src/CommunityToolkit.WinUI.Controls.MarkdownTextBlock.csproj +++ b/components/MarkdownTextBlock/src/CommunityToolkit.WinUI.Controls.MarkdownTextBlock.csproj @@ -25,7 +25,7 @@ - + @@ -33,7 +33,7 @@ - + @@ -41,6 +41,14 @@ + + + + + + + MarkdownTextBlock.xaml diff --git a/components/MarkdownTextBlock/src/Extensions.cs b/components/MarkdownTextBlock/src/Extensions.cs index 8c682fe2d..4eb5203b4 100644 --- a/components/MarkdownTextBlock/src/Extensions.cs +++ b/components/MarkdownTextBlock/src/Extensions.cs @@ -365,7 +365,7 @@ public static string ToAlphabetical(this int index) else { // Try to find the next insertion position by moving one symbol forward - TextPointer next = position.GetPositionAtOffset(1, logicalDirection); + TextPointer? next = position.GetPositionAtOffset(1, logicalDirection); // If there is no next position, return null if (next == null) { @@ -384,7 +384,7 @@ public static bool IsAtInsertionPosition(this TextPointer position, LogicalDirec // Get the character rect of the current position Rect currentRect = position.GetCharacterRect(logicalDirection); // Try to get the next position by moving one symbol forward - TextPointer next = position.GetPositionAtOffset(1, logicalDirection); + TextPointer? next = position.GetPositionAtOffset(1, logicalDirection); // If there is no next position, return false if (next == null) { diff --git a/components/MarkdownTextBlock/src/MarkdownThemes.cs b/components/MarkdownTextBlock/src/MarkdownThemes.cs index 21393cf21..78cd56205 100644 --- a/components/MarkdownTextBlock/src/MarkdownThemes.cs +++ b/components/MarkdownTextBlock/src/MarkdownThemes.cs @@ -12,7 +12,7 @@ namespace CommunityToolkit.WinUI.Controls; -public sealed class MarkdownThemes : DependencyObject +public sealed partial class MarkdownThemes : DependencyObject { internal static MarkdownThemes Default { get; } = new(); diff --git a/components/MarkdownTextBlock/src/MultiTarget.props b/components/MarkdownTextBlock/src/MultiTarget.props index 18f6c7c98..81a497fd2 100644 --- a/components/MarkdownTextBlock/src/MultiTarget.props +++ b/components/MarkdownTextBlock/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; + uwp;wasdk;wasm;win32;linux;macos;ios;android; diff --git a/components/MarkdownTextBlock/src/TextElements/MyInlineCode.cs b/components/MarkdownTextBlock/src/TextElements/MyInlineCode.cs index 090f1a21d..8edffe312 100644 --- a/components/MarkdownTextBlock/src/TextElements/MyInlineCode.cs +++ b/components/MarkdownTextBlock/src/TextElements/MyInlineCode.cs @@ -29,9 +29,14 @@ public MyInlineCode(CodeInline codeInline, MarkdownConfig config) border.BorderThickness = _config.Themes.InlineCodeBorderThickness; border.CornerRadius = _config.Themes.InlineCodeCornerRadius; border.Padding = _config.Themes.InlineCodePadding; +#if HAS_UNO + // UIElement.Transform3D is not implemented on Uno + border.RenderTransform = new TranslateTransform { Y = 4 }; +#else CompositeTransform3D transform = new CompositeTransform3D(); transform.TranslateY = 4; border.Transform3D = transform; +#endif var textBlock = new TextBlock(); textBlock.FontSize = _config.Themes.InlineCodeFontSize; textBlock.Foreground = _config.Themes.InlineCodeForeground; diff --git a/components/MarkdownTextBlock/src/TextElements/MyTaskListCheckBox.cs b/components/MarkdownTextBlock/src/TextElements/MyTaskListCheckBox.cs index afd9d39f2..19ca34adb 100644 --- a/components/MarkdownTextBlock/src/TextElements/MyTaskListCheckBox.cs +++ b/components/MarkdownTextBlock/src/TextElements/MyTaskListCheckBox.cs @@ -15,9 +15,14 @@ public MyTaskListCheckBox(TaskList taskList) { _taskList = taskList; var grid = new Grid(); +#if HAS_UNO + // UIElement.Transform3D is not implemented on Uno + grid.RenderTransform = new TranslateTransform { Y = 2 }; +#else CompositeTransform3D transform = new CompositeTransform3D(); transform.TranslateY = 2; grid.Transform3D = transform; +#endif grid.Width = 16; grid.Height = 16; grid.Margin = new Thickness(2, 0, 2, 0); diff --git a/components/Ribbon/src/MultiTarget.props b/components/Ribbon/src/MultiTarget.props index b11c19426..7d1e11c3c 100644 --- a/components/Ribbon/src/MultiTarget.props +++ b/components/Ribbon/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/TokenView/src/Helpers/ControlHelpers.cs b/components/TokenView/src/Helpers/ControlHelpers.cs index 16f565f7d..66bf04f26 100644 --- a/components/TokenView/src/Helpers/ControlHelpers.cs +++ b/components/TokenView/src/Helpers/ControlHelpers.cs @@ -10,5 +10,9 @@ namespace CommunityToolkit.WinUI.Controls; internal static partial class ControlHelpers { +#if WINUI3 + internal static bool IsXamlRootAvailable => true; +#else internal static bool IsXamlRootAvailable { get; } = Windows.Foundation.Metadata.ApiInformation.IsPropertyPresent("Windows.UI.Xaml.UIElement", "XamlRoot"); +#endif } diff --git a/components/TokenView/src/TokenView/TokenView.cs b/components/TokenView/src/TokenView/TokenView.cs index f30ce945a..7053e14fa 100644 --- a/components/TokenView/src/TokenView/TokenView.cs +++ b/components/TokenView/src/TokenView/TokenView.cs @@ -128,10 +128,13 @@ private void UpdateScrollButtonsVisibility() { return FocusManager.GetFocusedElement(XamlRoot) as TokenItem; } - else - { - return FocusManager.GetFocusedElement() as TokenItem; - } + +#if WINUI3 + // Without a XamlRoot the control isn't in a live tree, so none of its items can have focus + return null; +#else + return FocusManager.GetFocusedElement() as TokenItem; +#endif } private void SelectedIndex_PropertyChanged(DependencyObject sender, DependencyProperty dp) diff --git a/components/WrapPanel2/src/MultiTarget.props b/components/WrapPanel2/src/MultiTarget.props index b11c19426..7d1e11c3c 100644 --- a/components/WrapPanel2/src/MultiTarget.props +++ b/components/WrapPanel2/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/global.json b/global.json index 37457398e..2c9e15e29 100644 --- a/global.json +++ b/global.json @@ -5,6 +5,7 @@ }, "msbuild-sdks": { - "MSBuild.Sdk.Extras":"3.0.23" + "MSBuild.Sdk.Extras":"3.0.44", + "Uno.Sdk": "7.0.0-dev.132" } } diff --git a/tooling b/tooling index f02adf9e2..3620ce979 160000 --- a/tooling +++ b/tooling @@ -1 +1 @@ -Subproject commit f02adf9e2d1ec1fd4865116bc786e217298985af +Subproject commit 3620ce97948e1c2de82f33d611544ab4d0d23c3f