[gimp/wip/nielsdg/follow-xdg-color-scheme] themes: Add option to follow system color scheme




commit 1409c197cee1f43a1f57052d57c25d47abceefd6
Author: Niels De Graef <nielsdegraef gmail com>
Date:   Sat Apr 2 14:22:16 2022 +0200

    themes: Add option to follow system color scheme
    
    Now that the XDG Settings portal has started exposing a "color-scheme"
    property in the latest versions, we can follow this property and switch
    from dark to light theme (or vice versa) with the rest of the system.

 app/config/gimpguiconfig.c       | 14 ++++++
 app/config/gimpguiconfig.h       |  1 +
 app/dialogs/preferences-dialog.c | 15 ++++++-
 app/gui/themes.c                 | 95 ++++++++++++++++++++++++++++++++++++++++
 4 files changed, 123 insertions(+), 2 deletions(-)
---
diff --git a/app/config/gimpguiconfig.c b/app/config/gimpguiconfig.c
index c49e6897ab..2adb34879b 100644
--- a/app/config/gimpguiconfig.c
+++ b/app/config/gimpguiconfig.c
@@ -70,6 +70,7 @@ enum
   PROP_TOOLBOX_GROUPS,
   PROP_THEME_PATH,
   PROP_THEME,
+  PROP_FOLLOW_SYSTEM_COLORSCHEME,
   PROP_PREFER_DARK_THEME,
   PROP_ICON_THEME_PATH,
   PROP_ICON_THEME,
@@ -303,6 +304,13 @@ gimp_gui_config_class_init (GimpGuiConfigClass *klass)
                            GIMP_CONFIG_DEFAULT_THEME,
                            GIMP_PARAM_STATIC_STRINGS);
 
+  GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_FOLLOW_SYSTEM_COLORSCHEME,
+                            "follow-system-colorscheme",
+                            "Follow system color scheme",
+                            THEME_BLURB,
+                            TRUE,
+                            GIMP_PARAM_STATIC_STRINGS);
+
   GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_PREFER_DARK_THEME,
                             "prefer-dark-theme",
                             "Prefer Dark Theme",
@@ -643,6 +651,9 @@ gimp_gui_config_set_property (GObject      *object,
       g_free (gui_config->theme);
       gui_config->theme = g_value_dup_string (value);
       break;
+    case PROP_FOLLOW_SYSTEM_COLORSCHEME:
+      gui_config->follow_system_colorscheme = g_value_get_boolean (value);
+      break;
     case PROP_PREFER_DARK_THEME:
       gui_config->prefer_dark_theme = g_value_get_boolean (value);
       break;
@@ -813,6 +824,9 @@ gimp_gui_config_get_property (GObject    *object,
     case PROP_THEME:
       g_value_set_string (value, gui_config->theme);
       break;
+    case PROP_FOLLOW_SYSTEM_COLORSCHEME:
+      g_value_set_boolean (value, gui_config->follow_system_colorscheme);
+      break;
     case PROP_PREFER_DARK_THEME:
       g_value_set_boolean (value, gui_config->prefer_dark_theme);
       break;
diff --git a/app/config/gimpguiconfig.h b/app/config/gimpguiconfig.h
index ce0997443c..e5b6e4ec88 100644
--- a/app/config/gimpguiconfig.h
+++ b/app/config/gimpguiconfig.h
@@ -65,6 +65,7 @@ struct _GimpGuiConfig
   gboolean             toolbox_groups;
   gchar               *theme_path;
   gchar               *theme;
+  gboolean             follow_system_colorscheme;
   gboolean             prefer_dark_theme;
   gchar               *icon_theme_path;
   gchar               *icon_theme;
diff --git a/app/dialogs/preferences-dialog.c b/app/dialogs/preferences-dialog.c
index f83be9ab06..64d5043554 100644
--- a/app/dialogs/preferences-dialog.c
+++ b/app/dialogs/preferences-dialog.c
@@ -2030,9 +2030,20 @@ prefs_dialog_new (Gimp       *gimp,
                       gimp);
   }
 
-  prefs_check_button_add (object, "prefer-dark-theme",
-                          _("Use dark theme variant if available"),
+#ifdef G_OS_UNIX
+  prefs_check_button_add (object, "follow-system-colorscheme",
+                          _("Follow system color scheme"),
                           GTK_BOX (vbox2));
+#endif
+
+  button = prefs_check_button_add (object, "prefer-dark-theme",
+                                   _("Use dark theme variant if available"),
+                                   GTK_BOX (vbox2));
+#ifdef G_OS_UNIX
+  g_object_bind_property (object, "follow-system-colorscheme",
+                          button, "sensitive",
+                          G_BINDING_INVERT_BOOLEAN | G_BINDING_SYNC_CREATE);
+#endif
 
   hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
   gtk_box_pack_start (GTK_BOX (vbox2), hbox, FALSE, FALSE, 0);
diff --git a/app/gui/themes.c b/app/gui/themes.c
index 885be271bc..db6b0435eb 100644
--- a/app/gui/themes.c
+++ b/app/gui/themes.c
@@ -51,12 +51,18 @@ static void   themes_theme_change_notify (GimpGuiConfig          *config,
 static void   themes_theme_paths_notify  (GimpExtensionManager   *manager,
                                           GParamSpec             *pspec,
                                           Gimp                   *gimp);
+static void   xdg_settings_portal_changed (GDBusProxy            *proxy,
+                                           const gchar           *sender_name,
+                                           const gchar           *signal_name,
+                                           GVariant              *parameters,
+                                           Gimp                  *gimp);
 
 
 /*  private variables  */
 
 static GHashTable       *themes_hash           = NULL;
 static GtkStyleProvider *themes_style_provider = NULL;
+static GDBusProxy       *xdg_settings_portal   = NULL;
 
 
 /*  public functions  */
@@ -65,6 +71,7 @@ void
 themes_init (Gimp *gimp)
 {
   GimpGuiConfig *config;
+  GError        *error = NULL;
 
   g_return_if_fail (GIMP_IS_GIMP (gimp));
 
@@ -87,9 +94,35 @@ themes_init (Gimp *gimp)
 
   g_object_unref (themes_style_provider);
 
+  if (config->follow_system_colorscheme)
+    {
+      xdg_settings_portal = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
+                                                           G_DBUS_PROXY_FLAGS_NONE,
+                                                           NULL,
+                                                           "org.freedesktop.portal.Desktop",
+                                                           "/org/freedesktop/portal/desktop",
+                                                           "org.freedesktop.portal.Settings",
+                                                           NULL,
+                                                           &error);
+      if (error)
+        {
+          g_debug ("Settings portal not found: %s", error->message);
+          g_clear_error (&error);
+        }
+      else
+        {
+          g_signal_connect (xdg_settings_portal, "g-signal",
+                            G_CALLBACK (xdg_settings_portal_changed),
+                            gimp);
+        }
+    }
+
   g_signal_connect (config, "notify::theme",
                     G_CALLBACK (themes_theme_change_notify),
                     gimp);
+  g_signal_connect (config, "notify::follow-system-colorscheme",
+                    G_CALLBACK (themes_theme_change_notify),
+                    gimp);
   g_signal_connect (config, "notify::prefer-dark-theme",
                     G_CALLBACK (themes_theme_change_notify),
                     gimp);
@@ -116,6 +149,7 @@ themes_exit (Gimp *gimp)
     }
 
   g_clear_object (&themes_style_provider);
+  g_clear_object (&xdg_settings_portal);
 }
 
 gchar **
@@ -371,6 +405,42 @@ themes_theme_change_notify (GimpGuiConfig *config,
   GFile  *theme_css;
   GError *error = NULL;
 
+  if (config->follow_system_colorscheme)
+    {
+      GVariant *ret = NULL;
+      guint32 color_scheme;
+
+      ret = g_dbus_proxy_call_sync (xdg_settings_portal,
+                                    "Read",
+                                    g_variant_new ("(ss)",
+                                                   "org.freedesktop.appearance",
+                                                   "color-scheme"),
+                                    G_DBUS_CALL_FLAGS_NONE,
+                                    G_MAXINT,
+                                    NULL,
+                                    &error);
+      if (error)
+        {
+          g_warning ("Error trying to read out XDG color-scheme: %s",
+                     error->message);
+        }
+      else
+        {
+          GVariant *child = NULL, *child2 = NULL;
+
+          g_variant_get (ret, "(v)", &child);
+          g_variant_get (child, "v", &child2);
+          color_scheme = g_variant_get_uint32 (child2);
+
+          config->prefer_dark_theme = (color_scheme == 1);
+
+          g_variant_unref (child2);
+          g_variant_unref (child);
+        }
+
+        g_clear_pointer (&ret, g_variant_unref);
+    }
+
   g_object_set (gtk_settings_get_for_screen (gdk_screen_get_default ()),
                 "gtk-application-prefer-dark-theme", config->prefer_dark_theme,
                 NULL);
@@ -474,3 +544,28 @@ themes_theme_paths_notify (GimpExtensionManager *manager,
       g_list_free_full (path, (GDestroyNotify) g_object_unref);
     }
 }
+
+static void
+xdg_settings_portal_changed (GDBusProxy  *proxy,
+                             const gchar *sender_name,
+                             const gchar *signal_name,
+                             GVariant    *parameters,
+                             Gimp        *gimp)
+{
+  const char *namespace;
+  const char *name;
+  GVariant   *value = NULL;
+
+  if (g_strcmp0 (signal_name, "SettingChanged"))
+    return;
+
+  g_variant_get (parameters, "(&s&sv)", &namespace, &name, &value);
+
+  if (g_strcmp0 (namespace, "org.freedesktop.appearance") == 0 &&
+      g_strcmp0 (name, "color-scheme") == 0)
+    {
+      themes_theme_change_notify (GIMP_GUI_CONFIG (gimp->config), NULL, gimp);
+    }
+
+  g_variant_unref (value);
+}


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]