[gnome-builder] app: improve night-mode/follow-night-light/style-scheme-name tracking



commit 4e792dd49832033abec393f0a283573bb09b47ae
Author: Christian Hergert <chergert redhat com>
Date:   Fri Sep 28 16:45:33 2018 -0700

    app: improve night-mode/follow-night-light/style-scheme-name tracking
    
    This tries to handle a number of corner cases better in settings tracking
    for the night-mode and follow-night-light settings. We had a number of
    scenarios where things would startup with the wrong value now that we
    try to apply different style schemes with day/night settings.
    
    Fixes #648

 src/libide/application/ide-application-color.c | 152 ++++++++++++++++++++++++-
 src/libide/application/ide-application.c       | 134 ----------------------
 2 files changed, 147 insertions(+), 139 deletions(-)
---
diff --git a/src/libide/application/ide-application-color.c b/src/libide/application/ide-application-color.c
index 86cbfab95..5ff3d5ae6 100644
--- a/src/libide/application/ide-application-color.c
+++ b/src/libide/application/ide-application-color.c
@@ -16,32 +16,159 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include "config.h"
+
 #define G_LOG_DOMAIN "ide-application-color"
 
-#include "config.h"
+#include <gtksourceview/gtksource.h>
 
 #include "application/ide-application.h"
 #include "application/ide-application-private.h"
 
+static void
+add_style_name (GPtrArray   *ar,
+                const gchar *base,
+                gboolean     dark)
+{
+  g_ptr_array_add (ar, g_strdup_printf ("%s-%s", base, dark ? "dark" : "light"));
+}
+
+static gchar *
+find_similar_style_scheme (const gchar *name,
+                           gboolean     is_dark_mode)
+{
+  g_autoptr(GPtrArray) attempts = NULL;
+  GtkSourceStyleSchemeManager *mgr;
+  const gchar * const *scheme_ids;
+  const gchar *dash;
+
+  g_assert (name != NULL);
+
+  attempts = g_ptr_array_new_with_free_func (g_free);
+
+  mgr = gtk_source_style_scheme_manager_get_default ();
+  scheme_ids = gtk_source_style_scheme_manager_get_scheme_ids (mgr);
+
+  add_style_name (attempts, name, is_dark_mode);
+
+  if ((dash = strrchr (name, '-')))
+    {
+      if (g_str_equal (dash, "-light") ||
+          g_str_equal (dash, "-dark"))
+        {
+          g_autofree gchar *base = NULL;
+
+          base = g_strndup (name, dash - name);
+          add_style_name (attempts, base, is_dark_mode);
+
+          /* Add the base name last so light/dark matches first */
+          g_ptr_array_add (attempts, g_steal_pointer (&base));
+        }
+    }
+
+  /*
+   * Instead of using gtk_source_style_scheme_manager_get_scheme(), we get the
+   * IDs and look using case insensitive search so that its more likely we get
+   * a match when something is named Dark or Light in the id.
+   */
+
+  for (guint i = 0; i < attempts->len; i++)
+    {
+      const gchar *attempt = g_ptr_array_index (attempts, i);
+
+      for (guint j = 0; scheme_ids[j] != NULL; j++)
+        {
+          if (strcasecmp (attempt, scheme_ids[j]) == 0)
+            return g_strdup (scheme_ids[j]);
+        }
+    }
+
+  return NULL;
+}
+
 void
 _ide_application_update_color (IdeApplication *self)
 {
+  static gboolean ignore_reentrant = FALSE;
+  GtkSettings *gtk_settings;
+  gboolean prefer_dark_theme;
+  gboolean follow;
+  gboolean night_mode;
+
   g_assert (IDE_IS_APPLICATION (self));
 
+  if (ignore_reentrant)
+    return;
+
   if (self->color_proxy == NULL || self->settings == NULL)
     return;
 
-  if (g_settings_get_boolean (self->settings, "follow-night-light"))
+  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");
+
+  /*
+   * If we are using the Follow Night Light feature, then we want to update
+   * the application color based on the DBus 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 != g_settings_get_boolean (self->settings, "night-mode"))
-        g_settings_set_boolean (self->settings, "night-mode", active);
+      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);
+
+  ignore_reentrant = FALSE;
 }
 
 static void
@@ -63,6 +190,21 @@ _ide_application_init_color (IdeApplication *self)
   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",
+                               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),
+                               self,
+                               G_CONNECT_SWAPPED);
+    }
 
   if (NULL == (conn = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL)))
     return;
@@ -84,5 +226,5 @@ _ide_application_init_color (IdeApplication *self)
 
   self->color_proxy = g_steal_pointer (&proxy);
 
-  ide_application_color_properties_changed (self, NULL, NULL, self->color_proxy);
+  _ide_application_update_color (self);
 }
diff --git a/src/libide/application/ide-application.c b/src/libide/application/ide-application.c
index 9c51dd24a..f5de0d5bd 100644
--- a/src/libide/application/ide-application.c
+++ b/src/libide/application/ide-application.c
@@ -366,139 +366,6 @@ ide_application_language_defaults_cb (GObject      *object,
     }
 }
 
-static void
-add_style_name (GPtrArray   *ar,
-                const gchar *base,
-                gboolean     dark)
-{
-  g_ptr_array_add (ar, g_strdup_printf ("%s-%s", base, dark ? "dark" : "light"));
-}
-
-static gchar *
-find_similar_style_scheme (const gchar *name,
-                           gboolean     is_dark_mode)
-{
-  g_autoptr(GPtrArray) attempts = NULL;
-  GtkSourceStyleSchemeManager *mgr;
-  const gchar * const *scheme_ids;
-  const gchar *dash;
-
-  g_assert (name != NULL);
-
-  attempts = g_ptr_array_new_with_free_func (g_free);
-
-  mgr = gtk_source_style_scheme_manager_get_default ();
-  scheme_ids = gtk_source_style_scheme_manager_get_scheme_ids (mgr);
-
-  add_style_name (attempts, name, is_dark_mode);
-
-  if ((dash = strrchr (name, '-')))
-    {
-      if (g_str_equal (dash, "-light") ||
-          g_str_equal (dash, "-dark"))
-        {
-          g_autofree gchar *base = NULL;
-
-          base = g_strndup (name, dash - name);
-          add_style_name (attempts, base, is_dark_mode);
-
-          /* Add the base name last so light/dark matches first */
-          g_ptr_array_add (attempts, g_steal_pointer (&base));
-        }
-    }
-
-  /*
-   * Instead of using gtk_source_style_scheme_manager_get_scheme(), we get the
-   * IDs and look using case insensitive search so that its more likely we get
-   * a match when something is named Dark or Light in the id.
-   */
-
-  for (guint i = 0; i < attempts->len; i++)
-    {
-      const gchar *attempt = g_ptr_array_index (attempts, i);
-
-      for (guint j = 0; scheme_ids[j] != NULL; j++)
-        {
-          if (strcasecmp (attempt, scheme_ids[j]) == 0)
-            return g_strdup (scheme_ids[j]);
-        }
-    }
-
-  return NULL;
-}
-
-static void
-on_night_mode_changed (IdeApplication *self,
-                       const gchar    *key,
-                       GSettings      *settings)
-{
-  g_autoptr(GSettings) editor_settings = NULL;
-  g_autofree gchar *new_name = NULL;
-  g_autofree gchar *old_name = NULL;
-  GtkSettings *gtk_settings;
-  gboolean is_dark_mode = FALSE;
-
-  IDE_ENTRY;
-
-  g_assert (IDE_IS_APPLICATION (self));
-  g_assert (dzl_str_equal0 (key, "night-mode"));
-  g_assert (G_IS_SETTINGS (settings));
-
-  gtk_settings = gtk_settings_get_default ();
-
-  g_object_get (gtk_settings,
-                "gtk-application-prefer-dark-theme", &is_dark_mode,
-                NULL);
-
-  /* Short-circuit if there is nothing to change */
-  if (is_dark_mode == g_settings_get_boolean (settings, "night-mode"))
-    return;
-
-  is_dark_mode = !is_dark_mode;
-
-  /* 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, is_dark_mode);
-
-  if (new_name)
-    g_settings_set_string (editor_settings, "style-scheme-name", new_name);
-
-  g_object_set (gtk_settings,
-                "gtk-application-prefer-dark-theme", is_dark_mode,
-                NULL);
-
-  IDE_EXIT;
-}
-
-static void
-ide_application_register_settings (IdeApplication *self)
-{
-  IDE_ENTRY;
-
-  g_assert (IDE_IS_APPLICATION (self));
-
-  if (g_getenv ("GTK_THEME") == NULL)
-    {
-      g_signal_connect_object (self->settings,
-                               "changed::night-mode",
-                               G_CALLBACK (on_night_mode_changed),
-                               self,
-                               G_CONNECT_SWAPPED);
-      g_signal_connect_object (self->settings,
-                               "changed::follow-night-light",
-                               G_CALLBACK (_ide_application_update_color),
-                               self,
-                               G_CONNECT_SWAPPED);
-      on_night_mode_changed (self, "night-mode", self->settings);
-    }
-
-  IDE_EXIT;
-}
-
 static void
 projects_directory_changed_cb (IdeApplication *self,
                                const gchar    *key,
@@ -542,7 +409,6 @@ ide_application_startup (GApplication *application)
 
       ide_application_make_skeleton_dirs (self);
       ide_language_defaults_init_async (NULL, ide_application_language_defaults_cb, NULL);
-      ide_application_register_settings (self);
       ide_application_register_keybindings (self);
       ide_application_actions_init (self);
       _ide_application_init_shortcuts (self);


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