Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement xdg-desktop-portal accent-color spec #12674

Merged
merged 7 commits into from
Nov 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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