summaryrefslogtreecommitdiffstats
path: root/platform/linuxbsd
diff options
context:
space:
mode:
Diffstat (limited to 'platform/linuxbsd')
-rw-r--r--platform/linuxbsd/freedesktop_portal_desktop.cpp72
-rw-r--r--platform/linuxbsd/freedesktop_portal_desktop.h15
-rw-r--r--platform/linuxbsd/wayland/display_server_wayland.cpp4
-rw-r--r--platform/linuxbsd/wayland/display_server_wayland.h1
-rw-r--r--platform/linuxbsd/x11/display_server_x11.cpp4
-rw-r--r--platform/linuxbsd/x11/display_server_x11.h1
6 files changed, 87 insertions, 10 deletions
diff --git a/platform/linuxbsd/freedesktop_portal_desktop.cpp b/platform/linuxbsd/freedesktop_portal_desktop.cpp
index a3633e72b7..cdebed58b2 100644
--- a/platform/linuxbsd/freedesktop_portal_desktop.cpp
+++ b/platform/linuxbsd/freedesktop_portal_desktop.cpp
@@ -528,10 +528,10 @@ void FreeDesktopPortalDesktop::_file_dialog_callback(const Callable &p_callable,
}
}
-void FreeDesktopPortalDesktop::_thread_file_dialog_monitor(void *p_ud) {
+void FreeDesktopPortalDesktop::_thread_monitor(void *p_ud) {
FreeDesktopPortalDesktop *portal = (FreeDesktopPortalDesktop *)p_ud;
- while (!portal->file_dialog_thread_abort.is_set()) {
+ while (!portal->monitor_thread_abort.is_set()) {
{
MutexLock lock(portal->file_dialog_mutex);
for (int i = portal->file_dialogs.size() - 1; i >= 0; i--) {
@@ -579,10 +579,44 @@ void FreeDesktopPortalDesktop::_thread_file_dialog_monitor(void *p_ud) {
}
}
}
+
+ if (portal->theme_connection) {
+ while (true) {
+ DBusMessage *msg = dbus_connection_pop_message(portal->theme_connection);
+ if (!msg) {
+ break;
+ } else if (dbus_message_is_signal(msg, "org.freedesktop.portal.Settings", "SettingChanged")) {
+ DBusMessageIter iter;
+ if (dbus_message_iter_init(msg, &iter)) {
+ const char *value;
+ dbus_message_iter_get_basic(&iter, &value);
+ String name_space = String::utf8(value);
+ dbus_message_iter_next(&iter);
+ dbus_message_iter_get_basic(&iter, &value);
+ String key = String::utf8(value);
+
+ if (name_space == "org.freedesktop.appearance" && key == "color-scheme") {
+ callable_mp(portal, &FreeDesktopPortalDesktop::_system_theme_changed_callback).call_deferred();
+ }
+ }
+ dbus_message_unref(msg);
+ break;
+ }
+ dbus_message_unref(msg);
+ }
+ dbus_connection_read_write(portal->theme_connection, 0);
+ }
+
usleep(50000);
}
}
+void FreeDesktopPortalDesktop::_system_theme_changed_callback() {
+ if (system_theme_changed.is_valid()) {
+ system_theme_changed.call();
+ }
+}
+
FreeDesktopPortalDesktop::FreeDesktopPortalDesktop() {
#ifdef SOWRAP_ENABLED
#ifdef DEBUG_ENABLED
@@ -611,17 +645,34 @@ FreeDesktopPortalDesktop::FreeDesktopPortalDesktop() {
unsupported = true;
}
+ DBusError err;
+ dbus_error_init(&err);
+ theme_connection = dbus_bus_get(DBUS_BUS_SESSION, &err);
+ if (dbus_error_is_set(&err)) {
+ dbus_error_free(&err);
+ } else {
+ theme_path = "type='signal',sender='org.freedesktop.portal.Desktop',interface='org.freedesktop.portal.Settings',member='SettingChanged'";
+ dbus_bus_add_match(theme_connection, theme_path.utf8().get_data(), &err);
+ if (dbus_error_is_set(&err)) {
+ dbus_error_free(&err);
+ dbus_connection_unref(theme_connection);
+ theme_connection = nullptr;
+ }
+ dbus_connection_read_write(theme_connection, 0);
+ }
+
if (!unsupported) {
- file_dialog_thread_abort.clear();
- file_dialog_thread.start(FreeDesktopPortalDesktop::_thread_file_dialog_monitor, this);
+ monitor_thread_abort.clear();
+ monitor_thread.start(FreeDesktopPortalDesktop::_thread_monitor, this);
}
}
FreeDesktopPortalDesktop::~FreeDesktopPortalDesktop() {
- file_dialog_thread_abort.set();
- if (file_dialog_thread.is_started()) {
- file_dialog_thread.wait_to_finish();
+ monitor_thread_abort.set();
+ if (monitor_thread.is_started()) {
+ monitor_thread.wait_to_finish();
}
+
for (FreeDesktopPortalDesktop::FileDialogData &fd : file_dialogs) {
if (fd.connection) {
DBusError err;
@@ -631,6 +682,13 @@ FreeDesktopPortalDesktop::~FreeDesktopPortalDesktop() {
dbus_connection_unref(fd.connection);
}
}
+ if (theme_connection) {
+ DBusError err;
+ dbus_error_init(&err);
+ dbus_bus_remove_match(theme_connection, theme_path.utf8().get_data(), &err);
+ dbus_error_free(&err);
+ dbus_connection_unref(theme_connection);
+ }
}
#endif // DBUS_ENABLED
diff --git a/platform/linuxbsd/freedesktop_portal_desktop.h b/platform/linuxbsd/freedesktop_portal_desktop.h
index c9da387241..75afe02a26 100644
--- a/platform/linuxbsd/freedesktop_portal_desktop.h
+++ b/platform/linuxbsd/freedesktop_portal_desktop.h
@@ -34,6 +34,7 @@
#ifdef DBUS_ENABLED
#include "core/os/thread.h"
+#include "core/os/thread_safe.h"
#include "servers/display_server.h"
struct DBusMessage;
@@ -68,10 +69,15 @@ private:
Mutex file_dialog_mutex;
Vector<FileDialogData> file_dialogs;
- Thread file_dialog_thread;
- SafeFlag file_dialog_thread_abort;
+ Thread monitor_thread;
+ SafeFlag monitor_thread_abort;
- static void _thread_file_dialog_monitor(void *p_ud);
+ DBusConnection *theme_connection = nullptr;
+ String theme_path;
+ Callable system_theme_changed;
+ void _system_theme_changed_callback();
+
+ static void _thread_monitor(void *p_ud);
public:
FreeDesktopPortalDesktop();
@@ -86,6 +92,9 @@ public:
// 1: Prefer dark appearance.
// 2: Prefer light appearance.
uint32_t get_appearance_color_scheme();
+ void set_system_theme_change_callback(const Callable &p_system_theme_changed) {
+ system_theme_changed = p_system_theme_changed;
+ }
};
#endif // DBUS_ENABLED
diff --git a/platform/linuxbsd/wayland/display_server_wayland.cpp b/platform/linuxbsd/wayland/display_server_wayland.cpp
index b8a10ea6b9..85bbfe546a 100644
--- a/platform/linuxbsd/wayland/display_server_wayland.cpp
+++ b/platform/linuxbsd/wayland/display_server_wayland.cpp
@@ -275,6 +275,10 @@ bool DisplayServerWayland::is_dark_mode() const {
}
}
+void DisplayServerWayland::set_system_theme_change_callback(const Callable &p_callable) {
+ portal_desktop->set_system_theme_change_callback(p_callable);
+}
+
Error DisplayServerWayland::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 window_id = MAIN_WINDOW_ID;
// TODO: Use window IDs for multiwindow support.
diff --git a/platform/linuxbsd/wayland/display_server_wayland.h b/platform/linuxbsd/wayland/display_server_wayland.h
index 58c5dab586..d4da80a55f 100644
--- a/platform/linuxbsd/wayland/display_server_wayland.h
+++ b/platform/linuxbsd/wayland/display_server_wayland.h
@@ -171,6 +171,7 @@ public:
#ifdef DBUS_ENABLED
virtual bool is_dark_mode_supported() const override;
virtual bool is_dark_mode() const override;
+ virtual void set_system_theme_change_callback(const Callable &p_callable) override;
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) override;
virtual Error file_dialog_with_options_show(const String &p_title, const String &p_current_directory, const String &p_root, const String &p_filename, bool p_show_hidden, FileDialogMode p_mode, const Vector<String> &p_filters, const TypedArray<Dictionary> &p_options, const Callable &p_callback) override;
diff --git a/platform/linuxbsd/x11/display_server_x11.cpp b/platform/linuxbsd/x11/display_server_x11.cpp
index b838e4b870..35bfe81827 100644
--- a/platform/linuxbsd/x11/display_server_x11.cpp
+++ b/platform/linuxbsd/x11/display_server_x11.cpp
@@ -364,6 +364,10 @@ bool DisplayServerX11::is_dark_mode() const {
}
}
+void DisplayServerX11::set_system_theme_change_callback(const Callable &p_callable) {
+ portal_desktop->set_system_theme_change_callback(p_callable);
+}
+
Error DisplayServerX11::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 window_id = last_focused_window;
diff --git a/platform/linuxbsd/x11/display_server_x11.h b/platform/linuxbsd/x11/display_server_x11.h
index 7c094d6a41..a5cbe34d26 100644
--- a/platform/linuxbsd/x11/display_server_x11.h
+++ b/platform/linuxbsd/x11/display_server_x11.h
@@ -400,6 +400,7 @@ public:
#if defined(DBUS_ENABLED)
virtual bool is_dark_mode_supported() const override;
virtual bool is_dark_mode() const override;
+ virtual void set_system_theme_change_callback(const Callable &p_callable) override;
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) override;
virtual Error file_dialog_with_options_show(const String &p_title, const String &p_current_directory, const String &p_root, const String &p_filename, bool p_show_hidden, FileDialogMode p_mode, const Vector<String> &p_filters, const TypedArray<Dictionary> &p_options, const Callable &p_callback) override;