From ec94bdd36d956dbd77db685cd39f068c9bf2089a Mon Sep 17 00:00:00 2001
From: Zhang Dian <54255897+zdpcdt@users.noreply.github.com>
Date: Mon, 18 May 2026 21:16:03 +0800
Subject: [PATCH] Integrate font management for Linux demo (#822)
* feat: integrate font management by adding Semi.Avalonia.Demo.Fonts project.
* chore: test on ubuntu.
* feat: add linux options.
* feat: update theme settings and adjust window decorations.
* feat: add font to DRM project.
* misc: net8.0->net10.0
---
Semi.Avalonia.slnx | 1 +
.../Semi.Avalonia.Demo.Android/Application.cs | 3 +-
.../AvaloniaAppBuilderExtensions.cs | 16 ---------
.../Semi.Avalonia.Demo.Android.csproj | 4 +--
demo/Semi.Avalonia.Demo.Desktop/Program.cs | 34 ++++++++++--------
.../Semi.Avalonia.Demo.Desktop.csproj | 3 +-
demo/Semi.Avalonia.Demo.Drm/Program.cs | 18 +++++-----
.../Semi.Avalonia.Demo.Drm.csproj | 3 +-
.../Assets}/SourceHanSansCN-Bold.otf | Bin
.../Assets}/SourceHanSansCN-Regular.otf | Bin
.../AvaloniaAppBuilderExtensions.cs | 16 +++++++++
.../Semi.Avalonia.Demo.Fonts.csproj | 16 +++++++++
.../AvaloniaAppBuilderExtensions.cs | 16 ---------
demo/Semi.Avalonia.Demo.Web/Program.cs | 3 +-
.../Semi.Avalonia.Demo.Web.csproj | 5 +--
demo/Semi.Avalonia.Demo/App.axaml | 1 +
demo/Semi.Avalonia.Demo/App.axaml.cs | 30 +++++++++-------
.../Semi.Avalonia.Demo.csproj | 2 +-
demo/global.json | 5 ---
global.json | 2 +-
.../Controls/WindowDrawnDecorations.axaml | 14 ++++----
21 files changed, 101 insertions(+), 91 deletions(-)
delete mode 100644 demo/Semi.Avalonia.Demo.Android/AvaloniaAppBuilderExtensions.cs
rename demo/{Fonts => Semi.Avalonia.Demo.Fonts/Assets}/SourceHanSansCN-Bold.otf (100%)
rename demo/{Fonts => Semi.Avalonia.Demo.Fonts/Assets}/SourceHanSansCN-Regular.otf (100%)
create mode 100644 demo/Semi.Avalonia.Demo.Fonts/AvaloniaAppBuilderExtensions.cs
create mode 100644 demo/Semi.Avalonia.Demo.Fonts/Semi.Avalonia.Demo.Fonts.csproj
delete mode 100644 demo/Semi.Avalonia.Demo.Web/AvaloniaAppBuilderExtensions.cs
delete mode 100644 demo/global.json
diff --git a/Semi.Avalonia.slnx b/Semi.Avalonia.slnx
index b1024c6..47a5506 100644
--- a/Semi.Avalonia.slnx
+++ b/Semi.Avalonia.slnx
@@ -3,6 +3,7 @@
+
diff --git a/demo/Semi.Avalonia.Demo.Android/Application.cs b/demo/Semi.Avalonia.Demo.Android/Application.cs
index 611e568..fb85aee 100644
--- a/demo/Semi.Avalonia.Demo.Android/Application.cs
+++ b/demo/Semi.Avalonia.Demo.Android/Application.cs
@@ -2,6 +2,7 @@
using Android.Runtime;
using Avalonia;
using Avalonia.Android;
+using Semi.Avalonia.Demo.Fonts;
namespace Semi.Avalonia.Demo.Android;
@@ -17,4 +18,4 @@ public class Application : AvaloniaAndroidApplication
return base.CustomizeAppBuilder(builder)
.WithSourceHanSansCNFont();
}
-}
\ No newline at end of file
+}
diff --git a/demo/Semi.Avalonia.Demo.Android/AvaloniaAppBuilderExtensions.cs b/demo/Semi.Avalonia.Demo.Android/AvaloniaAppBuilderExtensions.cs
deleted file mode 100644
index ef18895..0000000
--- a/demo/Semi.Avalonia.Demo.Android/AvaloniaAppBuilderExtensions.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-using Avalonia;
-using Avalonia.Media;
-
-namespace Semi.Avalonia.Demo.Android;
-
-public static class AvaloniaAppBuilderExtensions
-{
- private static string DefaultFontFamily => "avares://Semi.Avalonia.Demo.Android/Assets#Source Han Sans CN";
-
- public static AppBuilder WithSourceHanSansCNFont(this AppBuilder builder) =>
- builder.With(new FontManagerOptions
- {
- DefaultFamilyName = DefaultFontFamily,
- FontFallbacks = [new FontFallback { FontFamily = new FontFamily(DefaultFontFamily) }]
- });
-}
\ No newline at end of file
diff --git a/demo/Semi.Avalonia.Demo.Android/Semi.Avalonia.Demo.Android.csproj b/demo/Semi.Avalonia.Demo.Android/Semi.Avalonia.Demo.Android.csproj
index c65aded..ea4cb33 100644
--- a/demo/Semi.Avalonia.Demo.Android/Semi.Avalonia.Demo.Android.csproj
+++ b/demo/Semi.Avalonia.Demo.Android/Semi.Avalonia.Demo.Android.csproj
@@ -21,7 +21,6 @@
-
@@ -31,5 +30,6 @@
+
-
\ No newline at end of file
+
diff --git a/demo/Semi.Avalonia.Demo.Desktop/Program.cs b/demo/Semi.Avalonia.Demo.Desktop/Program.cs
index 8de4d49..c62a2ad 100644
--- a/demo/Semi.Avalonia.Demo.Desktop/Program.cs
+++ b/demo/Semi.Avalonia.Demo.Desktop/Program.cs
@@ -2,8 +2,10 @@
using Avalonia;
using Avalonia.Dialogs;
using Avalonia.Media;
+using Semi.Avalonia.Demo.Fonts;
namespace Semi.Avalonia.Demo.Desktop;
+#pragma warning disable CA1416, AVALONIA_X11_CSD, AVALONIA_X11_FORCE_CSD
sealed class Program
{
@@ -11,24 +13,28 @@ sealed class Program
// SynchronizationContext-reliant code before AppMain is called: things aren't initialized
// yet and stuff might break.
[STAThread]
- public static void Main(string[] args) => BuildAvaloniaApp()
- .With(new FontManagerOptions
- {
- FontFallbacks =
- [
- new FontFallback
- {
- FontFamily = new FontFamily("Microsoft YaHei")
- }
- ]
- })
- .StartWithClassicDesktopLifetime(args);
+ public static void Main(string[] args)
+ {
+ var appBuilder = BuildAvaloniaApp();
+ if (!OperatingSystem.IsLinux())
+ appBuilder.With(new FontManagerOptions
+ {
+ FontFallbacks = [new FontFallback { FontFamily = new FontFamily("Microsoft YaHei") }]
+ });
+
+ appBuilder.StartWithClassicDesktopLifetime(args);
+ }
// Avalonia configuration, don't remove; also used by visual designer.
public static AppBuilder BuildAvaloniaApp()
- => AppBuilder.Configure()
+ {
+ var appBuilder = AppBuilder.Configure()
.UseManagedSystemDialogs()
.UsePlatformDetect()
.With(new Win32PlatformOptions())
+ .With(new X11PlatformOptions { EnableDrawnDecorations = true })
.LogToTrace();
-}
\ No newline at end of file
+ if (OperatingSystem.IsLinux()) appBuilder.WithSourceHanSansCNFont();
+ return appBuilder;
+ }
+}
diff --git a/demo/Semi.Avalonia.Demo.Desktop/Semi.Avalonia.Demo.Desktop.csproj b/demo/Semi.Avalonia.Demo.Desktop/Semi.Avalonia.Demo.Desktop.csproj
index 4e50e58..45a0ea5 100644
--- a/demo/Semi.Avalonia.Demo.Desktop/Semi.Avalonia.Demo.Desktop.csproj
+++ b/demo/Semi.Avalonia.Demo.Desktop/Semi.Avalonia.Demo.Desktop.csproj
@@ -1,7 +1,7 @@
WinExe
- net8.0
+ net10.0
enable
true
..\Semi.Avalonia.Demo\Assets\irihi.ico
@@ -28,5 +28,6 @@
+
diff --git a/demo/Semi.Avalonia.Demo.Drm/Program.cs b/demo/Semi.Avalonia.Demo.Drm/Program.cs
index c04db70..efce36a 100644
--- a/demo/Semi.Avalonia.Demo.Drm/Program.cs
+++ b/demo/Semi.Avalonia.Demo.Drm/Program.cs
@@ -4,8 +4,10 @@ using System.Linq;
using System.Threading;
using Avalonia;
using Avalonia.Dialogs;
+using Semi.Avalonia.Demo.Fonts;
namespace Semi.Avalonia.Demo.Drm;
+#pragma warning disable CA1416, AVALONIA_X11_CSD, AVALONIA_X11_FORCE_CSD
sealed class Program
{
@@ -40,17 +42,17 @@ sealed class Program
=> AppBuilder.Configure()
.UseManagedSystemDialogs()
.UsePlatformDetect()
- .With(new Win32PlatformOptions())
+ .With(new X11PlatformOptions { EnableDrawnDecorations = true })
+ .WithSourceHanSansCNFont()
.LogToTrace();
private static void SilenceConsole()
{
new Thread(() =>
- {
- Console.CursorVisible = false;
- while (true)
- Console.ReadKey(true);
- })
- { IsBackground = true }.Start();
+ {
+ Console.CursorVisible = false;
+ while (true)
+ Console.ReadKey(true);
+ }) { IsBackground = true }.Start();
}
-}
\ No newline at end of file
+}
diff --git a/demo/Semi.Avalonia.Demo.Drm/Semi.Avalonia.Demo.Drm.csproj b/demo/Semi.Avalonia.Demo.Drm/Semi.Avalonia.Demo.Drm.csproj
index 53b15ad..e09b1ee 100644
--- a/demo/Semi.Avalonia.Demo.Drm/Semi.Avalonia.Demo.Drm.csproj
+++ b/demo/Semi.Avalonia.Demo.Drm/Semi.Avalonia.Demo.Drm.csproj
@@ -1,7 +1,7 @@
WinExe
- net8.0
+ net10.0
enable
true
..\Semi.Avalonia.Demo\Assets\irihi.ico
@@ -29,5 +29,6 @@
+
diff --git a/demo/Fonts/SourceHanSansCN-Bold.otf b/demo/Semi.Avalonia.Demo.Fonts/Assets/SourceHanSansCN-Bold.otf
similarity index 100%
rename from demo/Fonts/SourceHanSansCN-Bold.otf
rename to demo/Semi.Avalonia.Demo.Fonts/Assets/SourceHanSansCN-Bold.otf
diff --git a/demo/Fonts/SourceHanSansCN-Regular.otf b/demo/Semi.Avalonia.Demo.Fonts/Assets/SourceHanSansCN-Regular.otf
similarity index 100%
rename from demo/Fonts/SourceHanSansCN-Regular.otf
rename to demo/Semi.Avalonia.Demo.Fonts/Assets/SourceHanSansCN-Regular.otf
diff --git a/demo/Semi.Avalonia.Demo.Fonts/AvaloniaAppBuilderExtensions.cs b/demo/Semi.Avalonia.Demo.Fonts/AvaloniaAppBuilderExtensions.cs
new file mode 100644
index 0000000..3a989d3
--- /dev/null
+++ b/demo/Semi.Avalonia.Demo.Fonts/AvaloniaAppBuilderExtensions.cs
@@ -0,0 +1,16 @@
+using Avalonia;
+using Avalonia.Media;
+
+namespace Semi.Avalonia.Demo.Fonts;
+
+public static class AvaloniaAppBuilderExtensions
+{
+ public static AppBuilder WithSourceHanSansCNFont(this AppBuilder builder)
+ {
+ const string uri = "avares://Semi.Avalonia.Demo.Fonts/Assets#Source Han Sans CN";
+ return builder.With(new FontManagerOptions
+ {
+ DefaultFamilyName = uri, FontFallbacks = [new FontFallback { FontFamily = new FontFamily(uri) }]
+ });
+ }
+}
diff --git a/demo/Semi.Avalonia.Demo.Fonts/Semi.Avalonia.Demo.Fonts.csproj b/demo/Semi.Avalonia.Demo.Fonts/Semi.Avalonia.Demo.Fonts.csproj
new file mode 100644
index 0000000..2878568
--- /dev/null
+++ b/demo/Semi.Avalonia.Demo.Fonts/Semi.Avalonia.Demo.Fonts.csproj
@@ -0,0 +1,16 @@
+
+
+
+ net10.0
+ enable
+ enable
+
+
+
+
+
+
+
+
+
+
diff --git a/demo/Semi.Avalonia.Demo.Web/AvaloniaAppBuilderExtensions.cs b/demo/Semi.Avalonia.Demo.Web/AvaloniaAppBuilderExtensions.cs
deleted file mode 100644
index 29386d5..0000000
--- a/demo/Semi.Avalonia.Demo.Web/AvaloniaAppBuilderExtensions.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-using Avalonia;
-using Avalonia.Media;
-
-namespace Semi.Avalonia.Demo.Web;
-
-public static class AvaloniaAppBuilderExtensions
-{
- private static string DefaultFontFamily => "avares://Semi.Avalonia.Demo.Web/Assets#Source Han Sans CN";
-
- public static AppBuilder WithSourceHanSansCNFont(this AppBuilder builder) =>
- builder.With(new FontManagerOptions
- {
- DefaultFamilyName = DefaultFontFamily,
- FontFallbacks = [new FontFallback { FontFamily = new FontFamily(DefaultFontFamily) }]
- });
-}
\ No newline at end of file
diff --git a/demo/Semi.Avalonia.Demo.Web/Program.cs b/demo/Semi.Avalonia.Demo.Web/Program.cs
index 62d4e94..5e70213 100644
--- a/demo/Semi.Avalonia.Demo.Web/Program.cs
+++ b/demo/Semi.Avalonia.Demo.Web/Program.cs
@@ -2,6 +2,7 @@
using System.Threading.Tasks;
using Avalonia;
using Avalonia.Browser;
+using Semi.Avalonia.Demo.Fonts;
[assembly: SupportedOSPlatform("browser")]
@@ -15,4 +16,4 @@ internal sealed partial class Program
public static AppBuilder BuildAvaloniaApp()
=> AppBuilder.Configure();
-}
\ No newline at end of file
+}
diff --git a/demo/Semi.Avalonia.Demo.Web/Semi.Avalonia.Demo.Web.csproj b/demo/Semi.Avalonia.Demo.Web/Semi.Avalonia.Demo.Web.csproj
index f52b4a3..96efbd8 100644
--- a/demo/Semi.Avalonia.Demo.Web/Semi.Avalonia.Demo.Web.csproj
+++ b/demo/Semi.Avalonia.Demo.Web/Semi.Avalonia.Demo.Web.csproj
@@ -6,15 +6,12 @@
enable
-
-
-
-
+
diff --git a/demo/Semi.Avalonia.Demo/App.axaml b/demo/Semi.Avalonia.Demo/App.axaml
index cd3224a..cf66547 100644
--- a/demo/Semi.Avalonia.Demo/App.axaml
+++ b/demo/Semi.Avalonia.Demo/App.axaml
@@ -5,6 +5,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:semi="https://irihi.tech/semi"
xmlns:vm="clr-namespace:Semi.Avalonia.Demo.ViewModels"
+ RequestedThemeVariant="Default"
x:DataType="vm:ApplicationViewModel">
diff --git a/demo/Semi.Avalonia.Demo/App.axaml.cs b/demo/Semi.Avalonia.Demo/App.axaml.cs
index b617ffe..d3255ed 100644
--- a/demo/Semi.Avalonia.Demo/App.axaml.cs
+++ b/demo/Semi.Avalonia.Demo/App.axaml.cs
@@ -1,6 +1,6 @@
+using System;
using Avalonia;
using Avalonia.Controls.ApplicationLifetimes;
-using Avalonia.Data.Core.Plugins;
using Avalonia.Markup.Xaml;
using Semi.Avalonia.Demo.ViewModels;
using Semi.Avalonia.Demo.Views;
@@ -15,25 +15,29 @@ public partial class App : Application
#if DEBUG
this.AttachDeveloperTools();
#endif
- this.DataContext = new ApplicationViewModel();
+ DataContext = new ApplicationViewModel();
+ if (OperatingSystem.IsLinux())
+ {
+ Resources.Add("DefaultFontFamily", null);
+ }
}
public override void OnFrameworkInitializationCompleted()
{
- switch (ApplicationLifetime)
+ if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{
- case IClassicDesktopStyleApplicationLifetime desktop:
- // Line below is needed to remove Avalonia data validation.
- // Without this line you will get duplicate validations from both Avalonia and CT
- // BindingPlugins.DataValidators.RemoveAt(0);
- desktop.MainWindow = new MainWindow();
- break;
- case ISingleViewApplicationLifetime singleView:
- singleView.MainView = new MainView();
- break;
+ desktop.MainWindow = new MainWindow { DataContext = new MainViewModel() };
+ }
+ else if (ApplicationLifetime is IActivityApplicationLifetime applicationLifetime)
+ {
+ applicationLifetime.MainViewFactory = () => new MainView { DataContext = new MainViewModel() };
+ }
+ else if (ApplicationLifetime is ISingleViewApplicationLifetime singleViewPlatform)
+ {
+ singleViewPlatform.MainView = new MainView { DataContext = new MainViewModel() };
}
this.RegisterFollowSystemTheme();
base.OnFrameworkInitializationCompleted();
}
-}
\ No newline at end of file
+}
diff --git a/demo/Semi.Avalonia.Demo/Semi.Avalonia.Demo.csproj b/demo/Semi.Avalonia.Demo/Semi.Avalonia.Demo.csproj
index ab804eb..12bb3c5 100644
--- a/demo/Semi.Avalonia.Demo/Semi.Avalonia.Demo.csproj
+++ b/demo/Semi.Avalonia.Demo/Semi.Avalonia.Demo.csproj
@@ -1,6 +1,6 @@
- net8.0
+ net10.0
enable
latest
diff --git a/demo/global.json b/demo/global.json
deleted file mode 100644
index b365003..0000000
--- a/demo/global.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "sdk": {
- "version": "8.0"
- }
-}
diff --git a/global.json b/global.json
index dad2db5..a11f48e 100644
--- a/global.json
+++ b/global.json
@@ -1,6 +1,6 @@
{
"sdk": {
- "version": "8.0.0",
+ "version": "10.0.0",
"rollForward": "latestMajor",
"allowPrerelease": true
}
diff --git a/src/Semi.Avalonia/Controls/WindowDrawnDecorations.axaml b/src/Semi.Avalonia/Controls/WindowDrawnDecorations.axaml
index b3d090f..997fc20 100644
--- a/src/Semi.Avalonia/Controls/WindowDrawnDecorations.axaml
+++ b/src/Semi.Avalonia/Controls/WindowDrawnDecorations.axaml
@@ -46,8 +46,8 @@
-
-
+
+
@@ -189,16 +189,16 @@
@@ -214,4 +214,4 @@
-
\ No newline at end of file
+