[gnome-builder/wip/exalm/dark: 7/7] Support dark style preference




commit cb82b43c6ad20f731ae527e39f11536f5dab0a34
Author: Alexander Mikhaylenko <alexm gnome org>
Date:   Fri Jan 7 06:17:26 2022 +0500

    Support dark style preference
    
    Reorganize and unify how styles are handled:
    
    - Introduce a single style-variant setting, same as in gnome-text-editor
    - Replace night-mode and follow-night-light with it
    - Switch the style scheme along with it, like with follow-night-light
    - Make dayhack and nightback toggle it instead of doing their own thing
    
    Link to libhandy, so it can follow the system preference in GNOME 42.

 build-aux/flatpak/org.gnome.Builder.json     |   1 -
 data/gsettings/org.gnome.builder.gschema.xml |  18 ++--
 meson.build                                  |   1 +
 src/libide/gui/ide-application-actions.c     |  29 +-----
 src/libide/gui/ide-application-color.c       | 138 ++++++++-------------------
 src/libide/gui/ide-application-private.h     |   3 -
 src/libide/gui/ide-application.c             |   5 +-
 src/libide/gui/ide-preferences-builtin.c     |  18 ++--
 src/libide/gui/meson.build                   |   1 +
 9 files changed, 70 insertions(+), 144 deletions(-)
---
diff --git a/build-aux/flatpak/org.gnome.Builder.json b/build-aux/flatpak/org.gnome.Builder.json
index 9d42e5238..25ee42071 100644
--- a/build-aux/flatpak/org.gnome.Builder.json
+++ b/build-aux/flatpak/org.gnome.Builder.json
@@ -43,7 +43,6 @@
         "--talk-name=org.gnome.CodeAssist.v1.*",
         "--system-talk-name=org.freedesktop.Avahi",
         "--talk-name=org.freedesktop.FileManager1",
-        "--talk-name=org.gnome.SettingsDaemon.Color",
         "--talk-name=org.freedesktop.PackageKit",
         "--talk-name=org.freedesktop.secrets",
         "--filesystem=xdg-run/gvfsd",
diff --git a/data/gsettings/org.gnome.builder.gschema.xml b/data/gsettings/org.gnome.builder.gschema.xml
index 24fa95836..58a8453df 100644
--- a/data/gsettings/org.gnome.builder.gschema.xml
+++ b/data/gsettings/org.gnome.builder.gschema.xml
@@ -15,15 +15,15 @@
       <summary>Window maximized</summary>
       <description>Window maximized state</description>
     </key>
-    <key name="night-mode" type="b">
-      <default>false</default>
-      <summary>Night Mode</summary>
-      <description>Prefer dark application chrome.</description>
-    </key>
-    <key name="follow-night-light" type="b">
-      <default>false</default>
-      <summary>Follow system night light</summary>
-      <description>Use GNOME night light setting to activate night-mode.</description>
+    <key name="style-variant" type="s">
+      <choices>
+        <choice value="follow"/>
+        <choice value="light"/>
+        <choice value="dark"/>
+      </choices>
+      <default>'follow'</default>
+      <summary>Style Variant</summary>
+      <description>Use the light or dark variant of the GTK theme and/or GtkSourceView style 
scheme.</description>
     </key>
     <key name="projects-directory" type="s">
       <!-- Translators: This is the default directory name for user’s
diff --git a/meson.build b/meson.build
index ae96f7cb7..c0342b8d0 100644
--- a/meson.build
+++ b/meson.build
@@ -279,6 +279,7 @@ libgio_dep = dependency('gio-2.0', version: glib_req)
 libgiounix_dep = dependency('gio-unix-2.0', version: glib_req)
 libgtk_dep = dependency('gtk+-3.0', version: gtk_req)
 libgtksource_dep = dependency('gtksourceview-4', version: '>= 4.0.0')
+libhandy_dep = dependency('libhandy-1', version: '>= 1.5.0')
 libjson_glib_dep = dependency('json-glib-1.0', version: '>= 1.2.0')
 libjsonrpc_glib_dep = dependency('jsonrpc-glib-1.0', version: '>= 3.41.0')
 libm_dep = cc.find_library('m', required: false)
diff --git a/src/libide/gui/ide-application-actions.c b/src/libide/gui/ide-application-actions.c
index 36b87308f..ca12a7e0c 100644
--- a/src/libide/gui/ide-application-actions.c
+++ b/src/libide/gui/ide-application-actions.c
@@ -24,6 +24,7 @@
 #include "config.h"
 
 #include <glib/gi18n.h>
+#include <handy.h>
 #include <ide-build-ident.h>
 #include <libide-projects.h>
 
@@ -298,19 +299,9 @@ ide_application_actions_nighthack (GSimpleAction *action,
                                    gpointer       user_data)
 {
   g_autoptr(GSettings) settings = NULL;
-  g_autofree gchar *name = NULL;
 
-  g_object_set (gtk_settings_get_default (),
-                "gtk-application-prefer-dark-theme", TRUE,
-                NULL);
-
-  settings = g_settings_new ("org.gnome.builder.editor");
-  name = g_settings_get_string (settings, "style-scheme-name");
-
-  if (g_str_has_prefix (name, "Adwaita"))
-    g_settings_set_string (settings, "style-scheme-name", "Adwaita-dark");
-  else
-    g_settings_set_string (settings, "style-scheme-name", "builder-dark");
+  settings = g_settings_new ("org.gnome.builder");
+  g_settings_set_string (settings, "style-variant", "dark");
 }
 
 static void
@@ -319,19 +310,9 @@ ide_application_actions_dayhack (GSimpleAction *action,
                                  gpointer       user_data)
 {
   g_autoptr(GSettings) settings = NULL;
-  g_autofree gchar *name = NULL;
 
-  g_object_set (gtk_settings_get_default (),
-                "gtk-application-prefer-dark-theme", FALSE,
-                NULL);
-
-  settings = g_settings_new ("org.gnome.builder.editor");
-  name = g_settings_get_string (settings, "style-scheme-name");
-
-  if (g_str_has_prefix (name, "Adwaita"))
-    g_settings_set_string (settings, "style-scheme-name", "Adwaita");
-  else
-    g_settings_set_string (settings, "style-scheme-name", "builder");
+  settings = g_settings_new ("org.gnome.builder");
+  g_settings_set_string (settings, "style-variant", "light");
 }
 
 static void
diff --git a/src/libide/gui/ide-application-color.c b/src/libide/gui/ide-application-color.c
index 50c3b42b8..ff5e8c1d5 100644
--- a/src/libide/gui/ide-application-color.c
+++ b/src/libide/gui/ide-application-color.c
@@ -23,6 +23,7 @@
 #include "config.h"
 
 #include <gtksourceview/gtksource.h>
+#include <handy.h>
 
 #include "ide-application.h"
 #include "ide-application-private.h"
@@ -92,141 +93,82 @@ static void
 _ide_application_update_color (IdeApplication *self)
 {
   static gboolean ignore_reentrant = FALSE;
-  GtkSettings *gtk_settings;
-  gboolean prefer_dark_theme;
-  gboolean follow;
-  gboolean night_mode;
+  HdyStyleManager *manager;
+  g_autofree char *style_variant = NULL;
 
   g_assert (IDE_IS_APPLICATION (self));
 
   if (ignore_reentrant)
     return;
 
-  if (self->color_proxy == NULL || self->settings == NULL)
+  if (self->settings == NULL)
     return;
 
   ignore_reentrant = TRUE;
 
   g_assert (G_IS_SETTINGS (self->settings));
-  g_assert (G_IS_DBUS_PROXY (self->color_proxy));
 
-  follow = g_settings_get_boolean (self->settings, "follow-night-light");
-  night_mode = g_settings_get_boolean (self->settings, "night-mode");
+  style_variant = g_settings_get_string (self->settings, "style-variant");
+  manager = hdy_style_manager_get_default ();
 
-  /*
-   * If we are using the Follow Night Light feature, then we want to update
-   * the application color based on the D-Bus NightLightActive property from
-   * GNOME Shell.
-   */
-
-  if (follow)
-    {
-      g_autoptr(GVariant) activev = NULL;
-      g_autoptr(GSettings) editor_settings = NULL;
-      g_autofree gchar *old_name = NULL;
-      g_autofree gchar *new_name = NULL;
-      gboolean active;
-
-      /*
-       * Update our internal night-mode setting based on the GNOME Shell
-       * Night Light setting.
-       */
-
-      activev = g_dbus_proxy_get_cached_property (self->color_proxy, "NightLightActive");
-      active = g_variant_get_boolean (activev);
-
-      if (active != night_mode)
-        {
-          night_mode = active;
-          g_settings_set_boolean (self->settings, "night-mode", night_mode);
-        }
-
-      /*
-       * Now that we have our color up to date, we need to possibly update the
-       * color scheme to match the setting. We always do this (and not just when
-       * the night-mode changes) so that we pick up changes at startup.
-       *
-       * Try to locate a corresponding style-scheme for the light/dark switch
-       * based on some naming conventions. If found, switch the current style
-       * scheme to match.
-       */
-
-      editor_settings = g_settings_new ("org.gnome.builder.editor");
-      old_name = g_settings_get_string (editor_settings, "style-scheme-name");
-      new_name = find_similar_style_scheme (old_name, night_mode);
-
-      if (new_name != NULL)
-        g_settings_set_string (editor_settings, "style-scheme-name", new_name);
-    }
-
-  gtk_settings = gtk_settings_get_default ();
-
-  g_object_get (gtk_settings,
-                "gtk-application-prefer-dark-theme", &prefer_dark_theme,
-                NULL);
-
-  if (prefer_dark_theme != night_mode)
-    g_object_set (gtk_settings,
-                  "gtk-application-prefer-dark-theme", night_mode,
-                  NULL);
+  if (!g_strcmp0 (style_variant, "follow"))
+    hdy_style_manager_set_color_scheme (manager, HDY_COLOR_SCHEME_PREFER_LIGHT);
+  else if (!g_strcmp0 (style_variant, "dark"))
+    hdy_style_manager_set_color_scheme (manager, HDY_COLOR_SCHEME_FORCE_DARK);
+  else
+    hdy_style_manager_set_color_scheme (manager, HDY_COLOR_SCHEME_FORCE_LIGHT);
 
   ignore_reentrant = FALSE;
 }
 
 static void
-ide_application_color_properties_changed (IdeApplication      *self,
-                                          GVariant            *properties,
-                                          const gchar * const *invalidated,
-                                          GDBusProxy          *proxy)
+_ide_application_update_style_scheme (IdeApplication *self)
 {
-  g_assert (IDE_IS_APPLICATION (self));
-  g_assert (G_IS_DBUS_PROXY (proxy));
+  HdyStyleManager *manager;
+  g_autoptr(GSettings) editor_settings = NULL;
+  g_autofree gchar *old_name = NULL;
+  g_autofree gchar *new_name = NULL;
 
-  _ide_application_update_color (self);
+  manager = hdy_style_manager_get_default ();
+
+  /*
+   * Now that we have our color up to date, we need to possibly update the
+   * color scheme to match the setting. We always do this (and not just when
+   * the style-variant changes) so that we pick up changes at startup.
+   *
+   * Try to locate a corresponding style-scheme for the light/dark switch
+   * based on some naming conventions. If found, switch the current style
+   * scheme to match.
+   */
+
+  editor_settings = g_settings_new ("org.gnome.builder.editor");
+  old_name = g_settings_get_string (editor_settings, "style-scheme-name");
+  new_name = find_similar_style_scheme (old_name, hdy_style_manager_get_dark (manager));
+
+  if (new_name != NULL)
+    g_settings_set_string (editor_settings, "style-scheme-name", new_name);
 }
 
 void
 _ide_application_init_color (IdeApplication *self)
 {
-  g_autoptr(GDBusConnection) conn = NULL;
-  g_autoptr(GDBusProxy) proxy = NULL;
-
   g_return_if_fail (IDE_IS_APPLICATION (self));
   g_return_if_fail (G_IS_SETTINGS (self->settings));
 
   if (g_getenv ("GTK_THEME") == NULL)
     {
       g_signal_connect_object (self->settings,
-                               "changed::follow-night-light",
+                               "changed::style-variant",
                                G_CALLBACK (_ide_application_update_color),
                                self,
                                G_CONNECT_SWAPPED);
-      g_signal_connect_object (self->settings,
-                               "changed::night-mode",
-                               G_CALLBACK (_ide_application_update_color),
+      g_signal_connect_object (hdy_style_manager_get_default (),
+                               "notify::dark",
+                               G_CALLBACK (_ide_application_update_style_scheme),
                                self,
                                G_CONNECT_SWAPPED);
     }
 
-  if (NULL == (conn = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL)))
-    return;
-
-  if (NULL == (proxy = g_dbus_proxy_new_sync (conn,
-                                              G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES,
-                                              NULL,
-                                              "org.gnome.SettingsDaemon.Color",
-                                              "/org/gnome/SettingsDaemon/Color",
-                                              "org.gnome.SettingsDaemon.Color",
-                                              NULL, NULL)))
-    return;
-
-  g_signal_connect_object (proxy,
-                           "g-properties-changed",
-                           G_CALLBACK (ide_application_color_properties_changed),
-                           self,
-                           G_CONNECT_SWAPPED);
-
-  self->color_proxy = g_steal_pointer (&proxy);
-
   _ide_application_update_color (self);
+  _ide_application_update_style_scheme (self);
 }
diff --git a/src/libide/gui/ide-application-private.h b/src/libide/gui/ide-application-private.h
index 340b84c49..c710549ad 100644
--- a/src/libide/gui/ide-application-private.h
+++ b/src/libide/gui/ide-application-private.h
@@ -50,9 +50,6 @@ struct _IdeApplication
    */
   PeasExtensionSet *addins;
 
-  /* D-Bus Proxy used to track color settings (Night Light) */
-  GDBusProxy *color_proxy;
-
   /* org.gnome.Builder GSettings object to avoid creating a bunch
    * of them (and ensuring it lives long enough to trigger signals
    * for various keys.
diff --git a/src/libide/gui/ide-application.c b/src/libide/gui/ide-application.c
index a81ba233c..ab0b6c390 100644
--- a/src/libide/gui/ide-application.c
+++ b/src/libide/gui/ide-application.c
@@ -27,6 +27,7 @@
 #endif
 
 #include <glib/gi18n.h>
+#include <handy.h>
 #include <libpeas/peas-autocleanups.h>
 #include <libide-themes.h>
 
@@ -192,6 +193,8 @@ ide_application_startup (GApplication *app)
       gtk_source_style_scheme_manager_append_search_path (styles, style_path);
       gtk_source_style_scheme_manager_append_search_path (styles, PACKAGE_DATADIR"/gtksourceview-4/styles/");
 
+      hdy_init ();
+
       /* Load color settings (Night Light, Dark Mode, etc) */
       _ide_application_init_color (self);
     }
@@ -224,7 +227,6 @@ ide_application_shutdown (GApplication *app)
 
   g_clear_pointer (&self->plugin_settings, g_hash_table_unref);
   g_clear_object (&self->addins);
-  g_clear_object (&self->color_proxy);
   g_clear_object (&self->settings);
   g_clear_object (&self->keybindings);
 
@@ -393,7 +395,6 @@ ide_application_dispose (GObject *object)
   g_clear_pointer (&self->type, g_free);
   g_clear_pointer (&self->dbus_address, g_free);
   g_clear_object (&self->addins);
-  g_clear_object (&self->color_proxy);
   g_clear_object (&self->settings);
   g_clear_object (&self->network_monitor);
   g_clear_object (&self->worker_manager);
diff --git a/src/libide/gui/ide-preferences-builtin.c b/src/libide/gui/ide-preferences-builtin.c
index c3f1f9b1f..2ad7f5f50 100644
--- a/src/libide/gui/ide-preferences-builtin.c
+++ b/src/libide/gui/ide-preferences-builtin.c
@@ -25,6 +25,7 @@
 #include <dazzle.h>
 #include <glib/gi18n.h>
 #include <gtksourceview/gtksource.h>
+#include <handy.h>
 #include <libpeas/peas.h>
 
 #include "ide-preferences-builtin-private.h"
@@ -93,14 +94,17 @@ ide_preferences_builtin_register_appearance (DzlPreferences *preferences)
   const gchar * const *scheme_ids;
   GtkWidget *bin;
   gint i;
-  gint dark_mode;
+  gint follow_style;
 
   dzl_preferences_add_page (preferences, "appearance", _("Appearance"), 0);
 
-  dzl_preferences_add_list_group (preferences, "appearance", "basic", _("Themes"), GTK_SELECTION_NONE, 0);
-  dark_mode = dzl_preferences_add_switch (preferences, "appearance", "basic", "org.gnome.builder", 
"night-mode", NULL, NULL, _("Dark Mode"), _("Whether Builder should use a dark theme"), _("dark theme"), 0);
-  dzl_preferences_add_switch (preferences, "appearance", "basic", "org.gnome.builder", "follow-night-light", 
NULL, NULL, _("Night Light"), _("Automatically enable dark mode at night"), _("follow night light"), 5);
-  dzl_preferences_add_switch (preferences, "appearance", "basic", "org.gnome.builder.editor", 
"show-grid-lines", NULL, NULL, _("Grid Pattern"), _("Display a grid pattern underneath source code"), NULL, 
10);
+  dzl_preferences_add_list_group (preferences, "appearance", "style", _("Style"), GTK_SELECTION_NONE, 0);
+  follow_style = dzl_preferences_add_radio (preferences, "appearance", "style", "org.gnome.builder", 
"style-variant", NULL, "\"follow\"", _("System"), NULL, _("follow"), 0);
+  dzl_preferences_add_radio (preferences, "appearance", "style", "org.gnome.builder", "style-variant", NULL, 
"\"light\"", _("Light"), NULL, NULL, 0);
+  dzl_preferences_add_radio (preferences, "appearance", "style", "org.gnome.builder", "style-variant", NULL, 
"\"dark\"", _("Dark"), NULL, NULL, 0);
+
+  dzl_preferences_add_list_group (preferences, "appearance", "editor", _("Editor"), GTK_SELECTION_NONE, 0);
+  dzl_preferences_add_switch (preferences, "appearance", "editor", "org.gnome.builder.editor", 
"show-grid-lines", NULL, NULL, _("Grid Pattern"), _("Display a grid pattern underneath source code"), NULL, 
0);
 
   dzl_preferences_add_list_group (preferences, "appearance", "font", _("Font"), GTK_SELECTION_NONE, 10);
   dzl_preferences_add_font_button (preferences, "appearance", "font", "org.gnome.builder.editor", 
"font-name", _("Editor"), C_("Keywords", "editor font monospace"), 0);
@@ -124,9 +128,9 @@ ide_preferences_builtin_register_appearance (DzlPreferences *preferences)
       dzl_preferences_add_radio (preferences, "appearance", "schemes", "org.gnome.builder.editor", 
"style-scheme-name", NULL, variant_str, title, NULL, title, i);
     }
 
-  if (g_getenv ("GTK_THEME") != NULL)
+  if (!hdy_style_manager_get_system_supports_color_schemes (hdy_style_manager_get_default ()))
     {
-      bin = dzl_preferences_get_widget (preferences, dark_mode);
+      bin = dzl_preferences_get_widget (preferences, follow_style);
       gtk_widget_set_sensitive (bin, FALSE);
     }
 }
diff --git a/src/libide/gui/meson.build b/src/libide/gui/meson.build
index 5ebc9474f..104c5a74a 100644
--- a/src/libide/gui/meson.build
+++ b/src/libide/gui/meson.build
@@ -177,6 +177,7 @@ libide_gui_deps = [
   libgtk_dep,
   libgtksource_dep,
   libdazzle_dep,
+  libhandy_dep,
   libpeas_dep,
   libwebkit_dep,
   dependency('libcmark', version: '>= 0.29.0'),


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