Skip to content

Commit 18f6c33

Browse files
committed
[DisplayServer] Implement get_accent_color on Linux.
1 parent 7e4f6bd commit 18f6c33

7 files changed

+73
-12
lines changed

doc/classes/DisplayServer.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@
195195
<return type="Color" />
196196
<description>
197197
Returns OS theme accent color. Returns [code]Color(0, 0, 0, 0)[/code], if accent color is unknown.
198-
[b]Note:[/b] This method is implemented on macOS, Windows, and Android.
198+
[b]Note:[/b] This method is implemented on macOS, Windows, Android, and Linux (X11/Wayland).
199199
</description>
200200
</method>
201201
<method name="get_base_color" qualifiers="const">

platform/linuxbsd/freedesktop_portal_desktop.cpp

+54-9
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
#define BUS_INTERFACE_SETTINGS "org.freedesktop.portal.Settings"
5454
#define BUS_INTERFACE_FILE_CHOOSER "org.freedesktop.portal.FileChooser"
5555

56-
bool FreeDesktopPortalDesktop::try_parse_variant(DBusMessage *p_reply_message, int p_type, void *r_value) {
56+
bool FreeDesktopPortalDesktop::try_parse_variant(DBusMessage *p_reply_message, ReadVariantType p_type, void *r_value) {
5757
DBusMessageIter iter[3];
5858

5959
dbus_message_iter_init(p_reply_message, &iter[0]);
@@ -67,15 +67,44 @@ bool FreeDesktopPortalDesktop::try_parse_variant(DBusMessage *p_reply_message, i
6767
}
6868

6969
dbus_message_iter_recurse(&iter[1], &iter[2]);
70-
if (dbus_message_iter_get_arg_type(&iter[2]) != p_type) {
71-
return false;
70+
if (p_type == VAR_TYPE_COLOR) {
71+
if (dbus_message_iter_get_arg_type(&iter[2]) != DBUS_TYPE_STRUCT) {
72+
return false;
73+
}
74+
DBusMessageIter struct_iter;
75+
dbus_message_iter_recurse(&iter[2], &struct_iter);
76+
int idx = 0;
77+
while (dbus_message_iter_get_arg_type(&struct_iter) == DBUS_TYPE_DOUBLE) {
78+
double value = 0.0;
79+
dbus_message_iter_get_basic(&struct_iter, &value);
80+
if (value < 0.0 || value > 1.0) {
81+
return false;
82+
}
83+
if (idx == 0) {
84+
static_cast<Color *>(r_value)->r = value;
85+
} else if (idx == 1) {
86+
static_cast<Color *>(r_value)->g = value;
87+
} else if (idx == 2) {
88+
static_cast<Color *>(r_value)->b = value;
89+
}
90+
idx++;
91+
if (!dbus_message_iter_next(&struct_iter)) {
92+
break;
93+
}
94+
}
95+
if (idx != 3) {
96+
return false;
97+
}
98+
} else if (p_type == VAR_TYPE_UINT32) {
99+
if (dbus_message_iter_get_arg_type(&iter[2]) != DBUS_TYPE_UINT32) {
100+
return false;
101+
}
102+
dbus_message_iter_get_basic(&iter[2], r_value);
72103
}
73-
74-
dbus_message_iter_get_basic(&iter[2], r_value);
75104
return true;
76105
}
77106

78-
bool FreeDesktopPortalDesktop::read_setting(const char *p_namespace, const char *p_key, int p_type, void *r_value) {
107+
bool FreeDesktopPortalDesktop::read_setting(const char *p_namespace, const char *p_key, ReadVariantType p_type, void *r_value) {
79108
if (unsupported) {
80109
return false;
81110
}
@@ -127,8 +156,24 @@ uint32_t FreeDesktopPortalDesktop::get_appearance_color_scheme() {
127156
}
128157

129158
uint32_t value = 0;
130-
read_setting("org.freedesktop.appearance", "color-scheme", DBUS_TYPE_UINT32, &value);
131-
return value;
159+
if (read_setting("org.freedesktop.appearance", "color-scheme", VAR_TYPE_UINT32, &value)) {
160+
return value;
161+
} else {
162+
return 0;
163+
}
164+
}
165+
166+
Color FreeDesktopPortalDesktop::get_appearance_accent_color() {
167+
if (unsupported) {
168+
return Color(0, 0, 0, 0);
169+
}
170+
171+
Color value;
172+
if (read_setting("org.freedesktop.appearance", "accent-color", VAR_TYPE_COLOR, &value)) {
173+
return value;
174+
} else {
175+
return Color(0, 0, 0, 0);
176+
}
132177
}
133178

134179
static const char *cs_empty = "";
@@ -639,7 +684,7 @@ void FreeDesktopPortalDesktop::_thread_monitor(void *p_ud) {
639684
dbus_message_iter_get_basic(&iter, &value);
640685
String key = String::utf8(value);
641686

642-
if (name_space == "org.freedesktop.appearance" && key == "color-scheme") {
687+
if (name_space == "org.freedesktop.appearance" && (key == "color-scheme" || key == "accent-color")) {
643688
callable_mp(portal, &FreeDesktopPortalDesktop::_system_theme_changed_callback).call_deferred();
644689
}
645690
}

platform/linuxbsd/freedesktop_portal_desktop.h

+8-2
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,14 @@ class FreeDesktopPortalDesktop : public Object {
4444
private:
4545
bool unsupported = false;
4646

47-
static bool try_parse_variant(DBusMessage *p_reply_message, int p_type, void *r_value);
47+
enum ReadVariantType {
48+
VAR_TYPE_UINT32, // u
49+
VAR_TYPE_COLOR, // (ddd)
50+
};
51+
52+
static bool try_parse_variant(DBusMessage *p_reply_message, ReadVariantType p_type, void *r_value);
4853
// Read a setting from org.freekdesktop.portal.Settings
49-
bool read_setting(const char *p_namespace, const char *p_key, int p_type, void *r_value);
54+
bool read_setting(const char *p_namespace, const char *p_key, ReadVariantType p_type, void *r_value);
5055

5156
static void append_dbus_string(DBusMessageIter *p_iter, const String &p_string);
5257
static void append_dbus_dict_options(DBusMessageIter *p_iter, const TypedArray<Dictionary> &p_options, HashMap<String, String> &r_ids);
@@ -108,6 +113,7 @@ class FreeDesktopPortalDesktop : public Object {
108113
// 1: Prefer dark appearance.
109114
// 2: Prefer light appearance.
110115
uint32_t get_appearance_color_scheme();
116+
Color get_appearance_accent_color();
111117
void set_system_theme_change_callback(const Callable &p_system_theme_changed) {
112118
system_theme_changed = p_system_theme_changed;
113119
}

platform/linuxbsd/wayland/display_server_wayland.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,10 @@ bool DisplayServerWayland::is_dark_mode() const {
302302
}
303303
}
304304

305+
Color DisplayServerWayland::get_accent_color() const {
306+
return portal_desktop->get_appearance_accent_color();
307+
}
308+
305309
void DisplayServerWayland::set_system_theme_change_callback(const Callable &p_callable) {
306310
portal_desktop->set_system_theme_change_callback(p_callable);
307311
}

platform/linuxbsd/wayland/display_server_wayland.h

+1
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@ class DisplayServerWayland : public DisplayServer {
184184
#ifdef DBUS_ENABLED
185185
virtual bool is_dark_mode_supported() const override;
186186
virtual bool is_dark_mode() const override;
187+
virtual Color get_accent_color() const override;
187188
virtual void set_system_theme_change_callback(const Callable &p_callable) override;
188189

189190
virtual Error file_dialog_show(const String &p_title, const String &p_current_directory, const String &p_filename, bool p_show_hidden, FileDialogMode p_mode, const Vector<String> &p_filters, const Callable &p_callback, WindowID p_window_id) override;

platform/linuxbsd/x11/display_server_x11.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,10 @@ bool DisplayServerX11::is_dark_mode() const {
398398
}
399399
}
400400

401+
Color DisplayServerX11::get_accent_color() const {
402+
return portal_desktop->get_appearance_accent_color();
403+
}
404+
401405
void DisplayServerX11::set_system_theme_change_callback(const Callable &p_callable) {
402406
portal_desktop->set_system_theme_change_callback(p_callable);
403407
}

platform/linuxbsd/x11/display_server_x11.h

+1
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,7 @@ class DisplayServerX11 : public DisplayServer {
419419
#if defined(DBUS_ENABLED)
420420
virtual bool is_dark_mode_supported() const override;
421421
virtual bool is_dark_mode() const override;
422+
virtual Color get_accent_color() const override;
422423
virtual void set_system_theme_change_callback(const Callable &p_callable) override;
423424

424425
virtual Error file_dialog_show(const String &p_title, const String &p_current_directory, const String &p_filename, bool p_show_hidden, FileDialogMode p_mode, const Vector<String> &p_filters, const Callable &p_callback, WindowID p_window_id) override;

0 commit comments

Comments
 (0)