[gnome-builder] app: switch light/dark style schemes when night-mode changes



commit 1c68e3d49a54b2339493c393790354793d31efef
Author: Christian Hergert <chergert redhat com>
Date:   Fri Sep 21 11:49:59 2018 -0700

    app: switch light/dark style schemes when night-mode changes
    
    This helps by switching between the -light and -dark variants of style
    schemes when we detect changes to night-mode.
    
    This should make "Follow Night Light" more useful since it's less annoying
    to have to change your style scheme.

 src/libide/application/ide-application.c | 118 +++++++++++++++++++++++++++++--
 1 file changed, 113 insertions(+), 5 deletions(-)
---
diff --git a/src/libide/application/ide-application.c b/src/libide/application/ide-application.c
index 976b9bb99..82cdcd5ff 100644
--- a/src/libide/application/ide-application.c
+++ b/src/libide/application/ide-application.c
@@ -366,6 +366,114 @@ 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 (key != NULL);
+  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)
 {
@@ -375,11 +483,11 @@ ide_application_register_settings (IdeApplication *self)
 
   if (g_getenv ("GTK_THEME") == NULL)
     {
-      GtkSettings *gtk_settings = gtk_settings_get_default ();
-
-      g_settings_bind (self->settings, "night-mode",
-                       gtk_settings, "gtk-application-prefer-dark-theme",
-                       G_SETTINGS_BIND_DEFAULT);
+      g_signal_connect_object (self->settings,
+                               "changed::night-mode",
+                               G_CALLBACK (on_night_mode_changed),
+                               self,
+                               G_CONNECT_SWAPPED);
     }
 
   IDE_EXIT;


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