From d136d03fd1badabb9161f532b5a64df6bd26c5e4 Mon Sep 17 00:00:00 2001
From: affederaffe <68356204+affederaffe@users.noreply.github.com>
Date: Sun, 23 Apr 2023 22:24:17 +0200
Subject: [PATCH 1/4] Fix slnf Headless path
---
Avalonia.Desktop.slnf | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/Avalonia.Desktop.slnf b/Avalonia.Desktop.slnf
index 76620e8b93..73e38f8cb9 100644
--- a/Avalonia.Desktop.slnf
+++ b/Avalonia.Desktop.slnf
@@ -23,8 +23,6 @@
"src\\Avalonia.Dialogs\\Avalonia.Dialogs.csproj",
"src\\Avalonia.Fonts.Inter\\Avalonia.Fonts.Inter.csproj",
"src\\Avalonia.FreeDesktop\\Avalonia.FreeDesktop.csproj",
- "src\\Avalonia.Headless.Vnc\\Avalonia.Headless.Vnc.csproj",
- "src\\Avalonia.Headless\\Avalonia.Headless.csproj",
"src\\Avalonia.MicroCom\\Avalonia.MicroCom.csproj",
"src\\Avalonia.Native\\Avalonia.Native.csproj",
"src\\Avalonia.OpenGL\\Avalonia.OpenGL.csproj",
@@ -33,6 +31,8 @@
"src\\Avalonia.Themes.Fluent\\Avalonia.Themes.Fluent.csproj",
"src\\Avalonia.Themes.Simple\\Avalonia.Themes.Simple.csproj",
"src\\Avalonia.X11\\Avalonia.X11.csproj",
+ "src\\Headless\\Avalonia.Headless.Vnc\\Avalonia.Headless.Vnc.csproj",
+ "src\\Headless\\Avalonia.Headless\\Avalonia.Headless.csproj",
"src\\Linux\\Avalonia.LinuxFramebuffer\\Avalonia.LinuxFramebuffer.csproj",
"src\\Markup\\Avalonia.Markup.Xaml.Loader\\Avalonia.Markup.Xaml.Loader.csproj",
"src\\Markup\\Avalonia.Markup.Xaml\\Avalonia.Markup.Xaml.csproj",
@@ -65,4 +65,4 @@
"tests\\Avalonia.UnitTests\\Avalonia.UnitTests.csproj"
]
}
-}
\ No newline at end of file
+}
From 1117332e4d6e83244f8c3dbf44d4f2f10f4d4005 Mon Sep 17 00:00:00 2001
From: affederaffe <68356204+affederaffe@users.noreply.github.com>
Date: Sun, 23 Apr 2023 22:24:56 +0200
Subject: [PATCH 2/4] Add AccentColor support for KDE
---
.../DBusPlatformSettings.cs | 78 ++++++++++++++-----
1 file changed, 57 insertions(+), 21 deletions(-)
diff --git a/src/Avalonia.FreeDesktop/DBusPlatformSettings.cs b/src/Avalonia.FreeDesktop/DBusPlatformSettings.cs
index a25bb68458..2b124499b3 100644
--- a/src/Avalonia.FreeDesktop/DBusPlatformSettings.cs
+++ b/src/Avalonia.FreeDesktop/DBusPlatformSettings.cs
@@ -1,6 +1,7 @@
using System;
using System.Threading.Tasks;
using Avalonia.Logging;
+using Avalonia.Media;
using Avalonia.Platform;
using Tmds.DBus.SourceGenerator;
@@ -9,7 +10,10 @@ namespace Avalonia.FreeDesktop
internal class DBusPlatformSettings : DefaultPlatformSettings
{
private readonly OrgFreedesktopPortalSettings? _settings;
+
private PlatformColorValues? _lastColorValues;
+ private PlatformThemeVariant? _themeVariant;
+ private Color? _accentColor;
public DBusPlatformSettings()
{
@@ -21,24 +25,33 @@ namespace Avalonia.FreeDesktop
_ = TryGetInitialValueAsync();
}
- public override PlatformColorValues GetColorValues()
- {
- return _lastColorValues ?? base.GetColorValues();
- }
+ public override PlatformColorValues GetColorValues() => _lastColorValues ?? base.GetColorValues();
private async Task TryGetInitialValueAsync()
{
try
{
var value = await _settings!.ReadAsync("org.freedesktop.appearance", "color-scheme");
- _lastColorValues = GetColorValuesFromSetting(value);
- OnColorValuesChanged(_lastColorValues);
+ _themeVariant = ReadAsColorScheme(value);
+ }
+ catch (Exception ex)
+ {
+ Logger.TryGet(LogEventLevel.Error, LogArea.FreeDesktopPlatform)?.Log(this, "Unable to get org.freedesktop.appearance.color-scheme value", ex);
+ }
+
+ try
+ {
+ var value = await _settings!.ReadAsync("org.kde.kdeglobals.General", "AccentColor");
+ _accentColor = ReadAsAccentColor(value);
}
catch (Exception ex)
{
- _lastColorValues = base.GetColorValues();
- Logger.TryGet(LogEventLevel.Error, LogArea.FreeDesktopPlatform)?.Log(this, "Unable to get setting value", ex);
+ Logger.TryGet(LogEventLevel.Error, LogArea.FreeDesktopPlatform)?.Log(this, "Unable to get org.kde.kdeglobals.General.AccentColor value", ex);
}
+
+ _lastColorValues = BuildPlatformColorValues();
+ if (_lastColorValues is not null)
+ OnColorValuesChanged(_lastColorValues);
}
private void SettingsChangedHandler(Exception? exception, (string @namespace, string key, DBusVariantItem value) valueTuple)
@@ -46,25 +59,48 @@ namespace Avalonia.FreeDesktop
if (exception is not null)
return;
- if (valueTuple is ("org.freedesktop.appearance", "color-scheme", { } value))
+ switch (valueTuple)
{
- /*
- 0: No preference
- 1: Prefer dark appearance
- 2: Prefer light appearance
- */
- _lastColorValues = GetColorValuesFromSetting(value);
- OnColorValuesChanged(_lastColorValues);
+ case ("org.freedesktop.appearance", "color-scheme", { } colorScheme):
+ /*
+ 0: No preference
+ 1: Prefer dark appearance
+ 2: Prefer light appearance
+ */
+ _themeVariant = ReadAsColorScheme(colorScheme);
+ _lastColorValues = BuildPlatformColorValues();
+ OnColorValuesChanged(_lastColorValues!);
+ break;
+ case ("org.kde.kdeglobals.General", "AccentColor", { } accentColor):
+ _accentColor = ReadAsAccentColor(accentColor);
+ _lastColorValues = BuildPlatformColorValues();
+ OnColorValuesChanged(_lastColorValues!);
+ break;
}
}
- private static PlatformColorValues GetColorValuesFromSetting(DBusVariantItem value)
+ private PlatformColorValues? BuildPlatformColorValues()
+ {
+ if (_themeVariant is { } themeVariant && _accentColor is { } accentColor)
+ return new PlatformColorValues { ThemeVariant = themeVariant, AccentColor1 = accentColor };
+ if (_themeVariant is { } themeVariant1)
+ return new PlatformColorValues { ThemeVariant = themeVariant1 };
+ if (_accentColor is { } accentColor1)
+ return new PlatformColorValues { AccentColor1 = accentColor1 };
+ return null;
+ }
+
+ private static PlatformThemeVariant ReadAsColorScheme(DBusVariantItem value)
{
var isDark = ((value.Value as DBusVariantItem)!.Value as DBusUInt32Item)!.Value == 1;
- return new PlatformColorValues
- {
- ThemeVariant = isDark ? PlatformThemeVariant.Dark : PlatformThemeVariant.Light
- };
+ return isDark ? PlatformThemeVariant.Dark : PlatformThemeVariant.Light;
+ }
+
+ private static Color ReadAsAccentColor(DBusVariantItem value)
+ {
+ var colorStr = ((value.Value as DBusVariantItem)!.Value as DBusStringItem)!.Value;
+ var rgb = colorStr.Split(',');
+ return new Color(255, byte.Parse(rgb[0]), byte.Parse(rgb[1]), byte.Parse(rgb[2]));
}
}
}
From f77b67db97487825d172401f118e205c6bae0510 Mon Sep 17 00:00:00 2001
From: affederaffe <68356204+affederaffe@users.noreply.github.com>
Date: Sun, 23 Apr 2023 22:32:51 +0200
Subject: [PATCH 3/4] Move comment
---
src/Avalonia.FreeDesktop/DBusPlatformSettings.cs | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/src/Avalonia.FreeDesktop/DBusPlatformSettings.cs b/src/Avalonia.FreeDesktop/DBusPlatformSettings.cs
index 2b124499b3..8b2b38bb82 100644
--- a/src/Avalonia.FreeDesktop/DBusPlatformSettings.cs
+++ b/src/Avalonia.FreeDesktop/DBusPlatformSettings.cs
@@ -62,11 +62,6 @@ namespace Avalonia.FreeDesktop
switch (valueTuple)
{
case ("org.freedesktop.appearance", "color-scheme", { } colorScheme):
- /*
- 0: No preference
- 1: Prefer dark appearance
- 2: Prefer light appearance
- */
_themeVariant = ReadAsColorScheme(colorScheme);
_lastColorValues = BuildPlatformColorValues();
OnColorValuesChanged(_lastColorValues!);
@@ -92,6 +87,11 @@ namespace Avalonia.FreeDesktop
private static PlatformThemeVariant ReadAsColorScheme(DBusVariantItem value)
{
+ /*
+ 0: No preference
+ 1: Prefer dark appearance
+ 2: Prefer light appearance
+ */
var isDark = ((value.Value as DBusVariantItem)!.Value as DBusUInt32Item)!.Value == 1;
return isDark ? PlatformThemeVariant.Dark : PlatformThemeVariant.Light;
}
From a507e92b31f24bc5cf88bedea89f47eb93c2ce42 Mon Sep 17 00:00:00 2001
From: Max Katz
Date: Mon, 24 Apr 2023 02:00:23 -0400
Subject: [PATCH 4/4] Fix theme-dependend markup extensions not knowing current
theme context
---
.../Controls/IResourceDictionary.cs | 2 +-
.../Controls/IThemeVariantProvider.cs | 22 +++
.../Controls/ResourceDictionary.cs | 12 +-
.../Controls/ResourceNodeExtensions.cs | 46 +++---
.../Styling/IThemeVariantHost.cs | 1 -
.../AvaloniaXamlIlCompiler.cs | 3 +-
...iaXamlIlThemeVariantProviderTransformer.cs | 31 ++++
.../AvaloniaXamlIlWellKnownTypes.cs | 2 +
.../DynamicResourceExtension.cs | 6 +-
.../StaticResourceExtension.cs | 22 ++-
.../Styling/ResourceInclude.cs | 4 +-
.../Themes/FluentBenchmark.cs | 22 ++-
.../Themes/ThemeBenchmark.cs | 4 +-
.../Xaml/ThemeDictionariesTests.cs | 136 +++++++++++++++++-
14 files changed, 271 insertions(+), 42 deletions(-)
create mode 100644 src/Avalonia.Base/Controls/IThemeVariantProvider.cs
create mode 100644 src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlThemeVariantProviderTransformer.cs
diff --git a/src/Avalonia.Base/Controls/IResourceDictionary.cs b/src/Avalonia.Base/Controls/IResourceDictionary.cs
index 2bd1f65638..6712498bf4 100644
--- a/src/Avalonia.Base/Controls/IResourceDictionary.cs
+++ b/src/Avalonia.Base/Controls/IResourceDictionary.cs
@@ -18,6 +18,6 @@ namespace Avalonia.Controls
///
/// Gets a collection of merged resource dictionaries that are specifically keyed and composed to address theme scenarios.
///
- IDictionary ThemeDictionaries { get; }
+ IDictionary ThemeDictionaries { get; }
}
}
diff --git a/src/Avalonia.Base/Controls/IThemeVariantProvider.cs b/src/Avalonia.Base/Controls/IThemeVariantProvider.cs
new file mode 100644
index 0000000000..d1dca2efbf
--- /dev/null
+++ b/src/Avalonia.Base/Controls/IThemeVariantProvider.cs
@@ -0,0 +1,22 @@
+using Avalonia.Metadata;
+using Avalonia.Styling;
+
+namespace Avalonia.Controls;
+
+///
+/// Resource provider with theme variant awareness.
+/// Can be used with .
+///
+///
+/// This is a helper interface for the XAML compiler to make Key property accessibly by the markup extensions.
+/// Which means, it can only be used with ResourceDictionaries and markup extensions in the XAML code.
+/// This API might be removed in the future minor updates.
+///
+[Unstable]
+public interface IThemeVariantProvider : IResourceProvider
+{
+ ///
+ /// Key property set by the compiler.
+ ///
+ ThemeVariant? Key { get; set; }
+}
diff --git a/src/Avalonia.Base/Controls/ResourceDictionary.cs b/src/Avalonia.Base/Controls/ResourceDictionary.cs
index 231a19baab..b928cf0672 100644
--- a/src/Avalonia.Base/Controls/ResourceDictionary.cs
+++ b/src/Avalonia.Base/Controls/ResourceDictionary.cs
@@ -13,13 +13,13 @@ namespace Avalonia.Controls
///
/// An indexed dictionary of resources.
///
- public class ResourceDictionary : IResourceDictionary
+ public class ResourceDictionary : IResourceDictionary, IThemeVariantProvider
{
private object? lastDeferredItemKey;
private Dictionary