vcl/inc/unx/gtk/gtkframe.hxx | 6 ++ vcl/unx/gtk3/gtkframe.cxx | 98 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 103 insertions(+), 1 deletion(-)
New commits: commit 8167859a27ecaf37565ebafd004476fd59f32701 Author: Caolán McNamara <caol...@redhat.com> AuthorDate: Thu May 19 10:35:38 2022 +0100 Commit: Caolán McNamara <caol...@redhat.com> CommitDate: Thu May 19 16:57:36 2022 +0200 follow org.freedesktop.appearance.color-scheme setting Change-Id: Id26d01fd19cc3ee12c0e14b785b3a5149d22baf5 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/134553 Tested-by: Jenkins Reviewed-by: Caolán McNamara <caol...@redhat.com> diff --git a/vcl/inc/unx/gtk/gtkframe.hxx b/vcl/inc/unx/gtk/gtkframe.hxx index ced3613ad0ca..c90afbdee899 100644 --- a/vcl/inc/unx/gtk/gtkframe.hxx +++ b/vcl/inc/unx/gtk/gtkframe.hxx @@ -185,6 +185,8 @@ class GtkSalFrame final : public SalFrame GtkEventControllerKey* m_pKeyController; gulong m_nSettingChangedSignalId; #endif + gulong m_nPortalSettingChangedSignalId; + GDBusProxy* m_pSettingsPortal; #if !GTK_CHECK_VERSION(4, 0, 0) GdkWindow* m_pForeignParent; GdkNativeWindow m_aForeignParentWindow; @@ -412,6 +414,8 @@ class GtkSalFrame final : public SalFrame bool HandleMenubarMnemonic(guint eState, guint nKeyval); + void ListenPortalSettings(); + public: cairo_surface_t* m_pSurface; basegfx::B2IVector m_aFrameSize; @@ -633,6 +637,8 @@ public: const cairo_font_options_t* get_font_options(); + void SetColorScheme(GVariant* variant); + void DisallowCycleFocusOut(); bool IsCycleFocusOutDisallowed() const; void AllowCycleFocusOut(); diff --git a/vcl/unx/gtk3/gtkframe.cxx b/vcl/unx/gtk3/gtkframe.cxx index 9037b9eaf915..80f235d10642 100644 --- a/vcl/unx/gtk3/gtkframe.cxx +++ b/vcl/unx/gtk3/gtkframe.cxx @@ -699,8 +699,14 @@ GtkSalFrame::~GtkSalFrame() { SolarMutexGuard aGuard; - if(m_nWatcherId) + if (m_nWatcherId) g_bus_unwatch_name(m_nWatcherId); + + if (m_nPortalSettingChangedSignalId) + g_signal_handler_disconnect(m_pSettingsPortal, m_nPortalSettingChangedSignalId); + + if (m_pSettingsPortal) + g_object_unref(m_pSettingsPortal); } GtkWidget *pEventWidget = getMouseEventWidget(); @@ -901,6 +907,8 @@ void GtkSalFrame::InitCommon() m_pSurface = nullptr; m_nGrabLevel = 0; m_bSalObjectSetPosSize = false; + m_nPortalSettingChangedSignalId = 0; + m_pSettingsPortal = nullptr; m_aDamageHandler.handle = this; m_aDamageHandler.damaged = ::damaged; @@ -1244,6 +1252,91 @@ void GtkSalFrame::AllowCycleFocusOut() #endif } +namespace +{ + enum ColorScheme + { + DEFAULT, + PREFER_DARK, + PREFER_LIGHT + }; + + bool ReadColorScheme(GDBusProxy* proxy, GVariant** out) + { + g_autoptr (GVariant) ret = + g_dbus_proxy_call_sync(proxy, "Read", + g_variant_new ("(ss)", "org.freedesktop.appearance", "color-scheme"), + G_DBUS_CALL_FLAGS_NONE, G_MAXINT, nullptr, nullptr); + if (!ret) + return false; + + g_autoptr (GVariant) child = nullptr; + g_variant_get(ret, "(v)", &child); + g_variant_get(child, "v", out); + + return true; + } +} + +void GtkSalFrame::SetColorScheme(GVariant* variant) +{ + if (!m_pWindow) + return; + + guint32 color_scheme = g_variant_get_uint32(variant); + if (color_scheme > PREFER_LIGHT) + color_scheme = DEFAULT; + + bool bDarkIconTheme(color_scheme == PREFER_DARK); + GtkSettings* pSettings = gtk_widget_get_settings(m_pWindow); + g_object_set(pSettings, "gtk-application-prefer-dark-theme", bDarkIconTheme, nullptr); +} + +static void settings_portal_changed_cb(GDBusProxy*, const char*, const char* signal_name, + GVariant* parameters, gpointer frame) +{ + if (g_strcmp0(signal_name, "SettingChanged")) + return; + + g_autoptr (GVariant) value = nullptr; + const char *name_space; + const char *name; + g_variant_get(parameters, "(&s&sv)", &name_space, &name, &value); + + if (g_strcmp0(name_space, "org.freedesktop.appearance") || + g_strcmp0(name, "color-scheme")) + return; + + GtkSalFrame* pThis = static_cast<GtkSalFrame*>(frame); + pThis->SetColorScheme(value); +} + +void GtkSalFrame::ListenPortalSettings() +{ + EnsureSessionBus(); + + if (!pSessionBus) + return; + + m_pSettingsPortal = g_dbus_proxy_new_sync(pSessionBus, + G_DBUS_PROXY_FLAGS_NONE, + nullptr, + "org.freedesktop.portal.Desktop", + "/org/freedesktop/portal/desktop", + "org.freedesktop.portal.Settings", + nullptr, + nullptr); + if (!m_pSettingsPortal) + return; + + g_autoptr (GVariant) value = nullptr; + + if (!ReadColorScheme(m_pSettingsPortal, &value)) + return; + + SetColorScheme(value); + m_nPortalSettingChangedSignalId = g_signal_connect(m_pSettingsPortal, "g-signal", G_CALLBACK(settings_portal_changed_cb), this); +} void GtkSalFrame::Init( SalFrame* pParent, SalFrameStyleFlags nStyle ) { @@ -1404,6 +1497,9 @@ void GtkSalFrame::Init( SalFrame* pParent, SalFrameStyleFlags nStyle ) { // Enable GMenuModel native menu attach_menu_model(this); + + // Listen to portal settings for e.g. prefer dark theme + ListenPortalSettings(); } }