Skip to content

Commit

Permalink
Implement xdg-desktop-portal accent-color spec (#12674)
Browse files Browse the repository at this point in the history
* Use Tmds.DBus.SourceGenerator 0.0.11

* Use xdg-desktop-portal settings to retrieve accent color

---------

Co-authored-by: Jumar Macato <16554748+jmacato@users.noreply.github.com>
  • Loading branch information
affederaffe and jmacato authored Nov 19, 2023
1 parent c6c12ce commit fce38aa
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 13 deletions.
51 changes: 39 additions & 12 deletions src/Avalonia.FreeDesktop/DBusPlatformSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,15 @@ private async Task TryGetInitialValuesAsync()
{
try
{
var value = await _settings!.ReadAsync("org.freedesktop.appearance", "color-scheme");
return ToColorScheme(((value.Value as DBusVariantItem)!.Value as DBusUInt32Item)!.Value);
var version = await _settings!.GetVersionPropertyAsync();
DBusVariantItem value;
if (version >= 2)
value = await _settings!.ReadOneAsync("org.freedesktop.appearance", "color-scheme");
else
value = (DBusVariantItem)(await _settings!.ReadAsync("org.freedesktop.appearance", "color-scheme")).Value;
if (value.Value is DBusUInt32Item dBusUInt32Item)
return ToColorScheme(dBusUInt32Item.Value);
return null;
}
catch (DBusException)
{
Expand All @@ -53,16 +60,23 @@ private async Task TryGetInitialValuesAsync()
{
try
{
var value = await _settings!.ReadAsync("org.kde.kdeglobals.General", "AccentColor");
return ToAccentColor(((value.Value as DBusVariantItem)!.Value as DBusStringItem)!.Value);
var version = await _settings!.GetVersionPropertyAsync();
DBusVariantItem value;
if (version >= 2)
value = await _settings!.ReadOneAsync("org.freedesktop.appearance", "accent-color");
else
value = (DBusVariantItem)(await _settings!.ReadAsync("org.freedesktop.appearance", "accent-color")).Value;
if (value.Value is DBusStructItem dBusStructItem)
return ToAccentColor(dBusStructItem);
return null;
}
catch (DBusException)
{
return null;
}
}

private async void SettingsChangedHandler(Exception? exception, (string @namespace, string key, DBusVariantItem value) valueTuple)
private void SettingsChangedHandler(Exception? exception, (string @namespace, string key, DBusVariantItem value) valueTuple)
{
if (exception is not null)
return;
Expand All @@ -71,7 +85,11 @@ private async void SettingsChangedHandler(Exception? exception, (string @namespa
{
case ("org.freedesktop.appearance", "color-scheme", { } colorScheme):
_themeVariant = ToColorScheme((colorScheme.Value as DBusUInt32Item)!.Value);
_accentColor = await TryGetAccentColorAsync();
_lastColorValues = BuildPlatformColorValues();
OnColorValuesChanged(_lastColorValues!);
break;
case ("org.freedesktop.appearance", "accent-color", { } accentColor):
_accentColor = ToAccentColor((accentColor.Value as DBusStructItem)!);
_lastColorValues = BuildPlatformColorValues();
OnColorValuesChanged(_lastColorValues!);
break;
Expand All @@ -92,18 +110,27 @@ private async void SettingsChangedHandler(Exception? exception, (string @namespa
private static PlatformThemeVariant ToColorScheme(uint value)
{
/*
<member>0: No preference</member>
<member>1: Prefer dark appearance</member>
<member>2: Prefer light appearance</member>
0: No preference
1: Prefer dark appearance
2: Prefer light appearance
*/
var isDark = value == 1;
return isDark ? PlatformThemeVariant.Dark : PlatformThemeVariant.Light;
}

private static Color ToAccentColor(string value)
private static Color? ToAccentColor(DBusStructItem value)
{
var rgb = value.Split(',');
return new Color(255, byte.Parse(rgb[0]), byte.Parse(rgb[1]), byte.Parse(rgb[2]));
/*
Indicates the system's preferred accent color as a tuple of RGB values
in the sRGB color space, in the range [0,1].
Out-of-range RGB values should be treated as an unset accent color.
*/
var r = (value[0] as DBusDoubleItem)!.Value;
var g = (value[1] as DBusDoubleItem)!.Value;
var b = (value[2] as DBusDoubleItem)!.Value;
if (r is < 0 or > 1 || g is < 0 or > 1 || b is < 0 or > 1)
return null;
return Color.FromRgb((byte)(r * 255), (byte)(g * 255), (byte)(b * 255));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,21 @@
Unknown values should be treated as 0 (no preference).
</para></listitem>
</varlistentry>
<varlistentry>
<term>org.freedesktop.appearance accent-color (ddd)</term>
<listitem><para>
Indicates the system's preferred accent color as a tuple of RGB values
in the sRGB color space, in the range [0,1].
Out-of-range RGB values should be treated as an unset accent color.
</para></listitem>
</varlistentry>
</variablelist>
Implementations can provide other keys; they are entirely
implementation details that are undocumented. If you are a
toolkit and want to use this please open an issue.
This documentation describes version 1 of this interface.
This documentation describes version 2 of this interface.
-->
<interface name="org.freedesktop.portal.Settings">

Expand All @@ -73,8 +81,31 @@
@value: The value @key is set to.
Reads a single value. Returns an error on any unknown namespace or key.
Deprecated, use ReadOne instead. The value argument was intended to have
the value inside one layer of variant as it is in ReadOne, for example
`&lt;string "hello"&gt;` in GVariant text notation; but it is actually
returned inside two layers of variant, for example
`&lt;&lt;string "hello"&gt;&gt;`.
-->
<method name='Read'>
<annotation name="org.freedesktop.DBus.Deprecated" value="true"/>
<arg name='namespace' type='s'/>
<arg name='key' type='s'/>
<arg name='value' direction='out' type='v'/>
</method>

<!--
ReadOne:
@namespace: Namespace to look up @key in.
@key: The key to get.
@value: The value @key is set to.
Reads a single value which may be any valid DBus type. Returns an error on any unknown namespace or key.
This method was added in version 2.
-->
<method name='ReadOne'>
<arg name='namespace' type='s'/>
<arg name='key' type='s'/>
<arg name='value' direction='out' type='v'/>
Expand Down

0 comments on commit fce38aa

Please sign in to comment.