[gnome-text-editor] app: manage style-scheme from EditorApplication



commit 0541b43ef08b960a57d89882c998fb7e81e7f3e2
Author: Christian Hergert <chergert redhat com>
Date:   Fri Nov 19 17:22:17 2021 -0800

    app: manage style-scheme from EditorApplication
    
    This all needs continuing work as we start to support a "follow system
    scheme" for dark mode. In particular we still need recoloring support so
    that we can make the window track the style scheme itself.
    
    Related #139

 src/editor-application-actions.c |  52 +--------------
 src/editor-application.c         | 141 +++++++++++++++++++++++++++++++++++++++
 src/editor-application.h         |   3 +
 src/editor-page-gsettings.c      |  73 ++++++--------------
 4 files changed, 166 insertions(+), 103 deletions(-)
---
diff --git a/src/editor-application-actions.c b/src/editor-application-actions.c
index 5631cc9..ac9b096 100644
--- a/src/editor-application-actions.c
+++ b/src/editor-application-actions.c
@@ -194,44 +194,6 @@ editor_application_actions_quit (GSimpleAction *action,
                              g_object_ref (self));
 }
 
-static void
-editor_application_actions_style_scheme_cb (GSimpleAction *action,
-                                            GVariant      *param,
-                                            gpointer       user_data)
-{
-  EditorApplication *self = user_data;
-  const char *name;
-
-  g_assert (G_IS_SIMPLE_ACTION (action));
-  g_assert (EDITOR_IS_APPLICATION (self));
-  g_assert (g_variant_is_of_type (param, G_VARIANT_TYPE_STRING));
-
-  name = g_variant_get_string (param, NULL);
-
-  g_settings_set_string (self->settings, "style-scheme", name);
-
-  if (g_str_has_suffix (name, "-dark"))
-    g_settings_set_string (self->settings, "style-variant", "dark");
-  else
-    g_settings_set_string (self->settings, "style-variant", "light");
-}
-
-static void
-editor_application_actions_settings_changed_cb (GSettings     *settings,
-                                                const char    *key,
-                                                GSimpleAction *action)
-{
-  g_assert (G_IS_SETTINGS (settings));
-  g_assert (G_IS_SIMPLE_ACTION (action));
-
-  if (g_strcmp0 (key, "style-scheme") == 0 ||
-      g_strcmp0 (key, "style-variant") == 0)
-    {
-      g_autoptr(GVariant) v = g_settings_get_value (settings, "style-scheme");
-      g_simple_action_set_state (action, v);
-    }
-}
-
 static void
 editor_application_actions_remove_recent_cb (GSimpleAction *action,
                                              GVariant      *param,
@@ -263,23 +225,15 @@ _editor_application_actions_init (EditorApplication *self)
     { "about", editor_application_actions_about_cb },
     { "help", editor_application_actions_help_cb },
     { "quit", editor_application_actions_quit },
-    { "style-scheme", NULL, "s", "''", editor_application_actions_style_scheme_cb },
     { "remove-recent", editor_application_actions_remove_recent_cb, "(ss)" },
   };
-  GAction *action;
+  g_autoptr(GPropertyAction) style_scheme = NULL;
 
   g_action_map_add_action_entries (G_ACTION_MAP (self),
                                    actions,
                                    G_N_ELEMENTS (actions),
                                    self);
 
-  action = g_action_map_lookup_action (G_ACTION_MAP (self), "style-scheme");
-  g_signal_connect_object (self->settings,
-                           "changed",
-                           G_CALLBACK (editor_application_actions_settings_changed_cb),
-                           action,
-                           0);
-  editor_application_actions_settings_changed_cb (self->settings,
-                                                  "style-scheme",
-                                                  G_SIMPLE_ACTION (action));
+  style_scheme = g_property_action_new ("style-scheme", self, "style-scheme");
+  g_action_map_add_action (G_ACTION_MAP (self), G_ACTION (style_scheme));
 }
diff --git a/src/editor-application.c b/src/editor-application.c
index a8fc599..4528734 100644
--- a/src/editor-application.c
+++ b/src/editor-application.c
@@ -31,6 +31,14 @@
 
 G_DEFINE_TYPE (EditorApplication, editor_application, GTK_TYPE_APPLICATION)
 
+enum {
+  PROP_0,
+  PROP_STYLE_SCHEME,
+  N_PROPS
+};
+
+static GParamSpec *properties[N_PROPS];
+
 static void
 editor_application_restore_cb (GObject      *object,
                                GAsyncResult *result,
@@ -177,6 +185,8 @@ on_style_manager_notify_dark (EditorApplication *self,
       if (EDITOR_IS_WINDOW (window))
         update_dark (window);
     }
+
+  g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_STYLE_SCHEME]);
 }
 
 static void
@@ -284,6 +294,44 @@ editor_application_window_added (GtkApplication *application,
   GTK_APPLICATION_CLASS (editor_application_parent_class)->window_added (application, window);
 }
 
+static void
+editor_application_get_property (GObject    *object,
+                                 guint       prop_id,
+                                 GValue     *value,
+                                 GParamSpec *pspec)
+{
+  EditorApplication *self = EDITOR_APPLICATION (object);
+
+  switch (prop_id)
+    {
+    case PROP_STYLE_SCHEME:
+      g_value_set_string (value, editor_application_get_style_scheme (self));
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+editor_application_set_property (GObject      *object,
+                                 guint         prop_id,
+                                 const GValue *value,
+                                 GParamSpec   *pspec)
+{
+  EditorApplication *self = EDITOR_APPLICATION (object);
+
+  switch (prop_id)
+    {
+    case PROP_STYLE_SCHEME:
+      editor_application_set_style_scheme (self, g_value_get_string (value));
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
 static void
 editor_application_class_init (EditorApplicationClass *klass)
 {
@@ -292,6 +340,8 @@ editor_application_class_init (EditorApplicationClass *klass)
   GtkApplicationClass *gtk_application_class = GTK_APPLICATION_CLASS (klass);
 
   object_class->constructed = editor_application_constructed;
+  object_class->get_property = editor_application_get_property;
+  object_class->set_property = editor_application_set_property;
 
   application_class->activate = editor_application_activate;
   application_class->open = editor_application_open;
@@ -300,6 +350,15 @@ editor_application_class_init (EditorApplicationClass *klass)
   application_class->handle_local_options = editor_application_handle_local_options;
 
   gtk_application_class->window_added = editor_application_window_added;
+
+  properties [PROP_STYLE_SCHEME] =
+    g_param_spec_string ("style-scheme",
+                         "Style Scheme",
+                         "The style scheme for the editor",
+                         NULL,
+                         (G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_properties (object_class, N_PROPS, properties);
 }
 
 static const GOptionEntry entries[] = {
@@ -369,3 +428,85 @@ editor_application_get_current_window (EditorApplication *self)
 
   return NULL;
 }
+
+static GtkSourceStyleScheme *
+_gtk_source_style_scheme_get_variant (GtkSourceStyleScheme *scheme,
+                                      const char           *variant)
+{
+  GtkSourceStyleSchemeManager *style_scheme_manager;
+  GtkSourceStyleScheme *ret;
+  g_autoptr(GString) str = NULL;
+
+  g_return_val_if_fail (GTK_SOURCE_IS_STYLE_SCHEME (scheme), NULL);
+  g_return_val_if_fail (g_strcmp0 (variant, "light") == 0 ||
+                        g_strcmp0 (variant, "dark") == 0, NULL);
+
+  style_scheme_manager = gtk_source_style_scheme_manager_get_default ();
+  str = g_string_new (gtk_source_style_scheme_get_id (scheme));
+
+  if (g_str_has_suffix (str->str, "-light"))
+    g_string_truncate (str, str->len - strlen ("-light"));
+  else if (g_str_has_suffix (str->str, "-dark"))
+    g_string_truncate (str, str->len - strlen ("-dark"));
+
+  g_string_append_printf (str, "-%s", variant);
+
+  /* Look for "Foo-variant" directly */
+  if ((ret = gtk_source_style_scheme_manager_get_scheme (style_scheme_manager, str->str)))
+    return ret;
+
+  /* Look for "Foo" */
+  g_string_truncate (str, str->len - strlen (variant) - 1);
+  if ((ret = gtk_source_style_scheme_manager_get_scheme (style_scheme_manager, str->str)))
+    return ret;
+
+  /* Fallback to what we were provided */
+  return ret;
+}
+
+const char *
+editor_application_get_style_scheme (EditorApplication *self)
+{
+  GtkSourceStyleSchemeManager *style_scheme_manager;
+  GtkSourceStyleScheme *style_scheme;
+  AdwStyleManager *style_manager;
+  g_autofree char *style_scheme_id = NULL;
+  const char *variant;
+
+  g_return_val_if_fail (EDITOR_IS_APPLICATION (self), NULL);
+
+  style_manager = adw_style_manager_get_default ();
+  style_scheme_manager = gtk_source_style_scheme_manager_get_default ();
+  style_scheme_id = g_settings_get_string (self->settings, "style-scheme");
+
+  /* Fallback to Adwaita if we don't find a match */
+  if (gtk_source_style_scheme_manager_get_scheme (style_scheme_manager, style_scheme_id) == NULL)
+    {
+      g_free (style_scheme_id);
+      style_scheme_id = g_strdup ("Adwaita");
+    }
+
+  if (adw_style_manager_get_dark (style_manager))
+    variant = "dark";
+  else
+    variant = "light";
+
+  style_scheme = gtk_source_style_scheme_manager_get_scheme (style_scheme_manager, style_scheme_id);
+  style_scheme = _gtk_source_style_scheme_get_variant (style_scheme, variant);
+
+  return gtk_source_style_scheme_get_id (style_scheme);
+}
+
+void
+editor_application_set_style_scheme (EditorApplication *self,
+                                     const char        *style_scheme)
+{
+  g_return_if_fail (EDITOR_IS_APPLICATION (self));
+
+  if (style_scheme == NULL)
+    style_scheme = "Adwaita";
+
+  g_object_freeze_notify (G_OBJECT (self));
+  g_settings_set_string (self->settings, "style-scheme", style_scheme);
+  g_object_thaw_notify (G_OBJECT (self));
+}
diff --git a/src/editor-application.h b/src/editor-application.h
index e8fcfad..057d435 100644
--- a/src/editor-application.h
+++ b/src/editor-application.h
@@ -31,5 +31,8 @@ G_DECLARE_FINAL_TYPE (EditorApplication, editor_application, EDITOR, APPLICATION
 
 EditorSession *editor_application_get_session        (EditorApplication *self);
 EditorWindow  *editor_application_get_current_window (EditorApplication *self);
+const char    *editor_application_get_style_scheme   (EditorApplication *self);
+void           editor_application_set_style_scheme   (EditorApplication *self,
+                                                      const char        *style_scheme);
 
 G_END_DECLS
diff --git a/src/editor-page-gsettings.c b/src/editor-page-gsettings.c
index 46de5a3..e6ee90d 100644
--- a/src/editor-page-gsettings.c
+++ b/src/editor-page-gsettings.c
@@ -22,6 +22,7 @@
 
 #include "config.h"
 
+#include "editor-application.h"
 #include "editor-page-gsettings-private.h"
 
 struct _EditorPageGsettings
@@ -72,60 +73,7 @@ static gboolean
 editor_page_gsettings_get_style_scheme (EditorPageSettingsProvider  *provider,
                                         gchar                      **style_scheme)
 {
-  EditorPageGsettings *self = EDITOR_PAGE_GSETTINGS (provider);
-  GtkSourceStyleSchemeManager *sm;
-  GtkSourceStyleScheme *scheme;
-  g_autofree gchar *light = NULL;
-  g_autofree gchar *dark = NULL;
-  g_autofree gchar *regular = NULL;
-  g_autofree gchar *style_variant = NULL;
-
-  sm = gtk_source_style_scheme_manager_get_default ();
-  regular = g_settings_get_string (self->settings, "style-scheme");
-
-  if (g_str_has_suffix (regular, "-dark"))
-    {
-      regular[strlen(regular)-5] = 0;
-      dark = g_strdup_printf ("%s-dark", regular);
-      light = g_strdup_printf ("%s-light", regular);
-    }
-  else if (g_str_has_suffix (regular, "-light"))
-    {
-      regular[strlen(regular)-6] = 0;
-      dark = g_strdup_printf ("%s-dark", regular);
-      light = g_strdup_printf ("%s-light", regular);
-    }
-  else
-    {
-      dark = g_strdup_printf ("%s-dark", regular);
-      light = g_strdup_printf ("%s-light", regular);
-    }
-
-  style_variant = g_settings_get_string (self->settings, "style-variant");
-
-  if (g_strcmp0 (style_variant, "dark") == 0)
-    {
-      if (!(scheme = gtk_source_style_scheme_manager_get_scheme (sm, dark)) &&
-          !(scheme = gtk_source_style_scheme_manager_get_scheme (sm, regular)) &&
-          !(scheme = gtk_source_style_scheme_manager_get_scheme (sm, light)))
-        scheme = gtk_source_style_scheme_manager_get_scheme (sm, "Adwaita-dark");
-    }
-  else
-    {
-      if (!(scheme = gtk_source_style_scheme_manager_get_scheme (sm, light)) &&
-          !(scheme = gtk_source_style_scheme_manager_get_scheme (sm, regular)) &&
-          !(scheme = gtk_source_style_scheme_manager_get_scheme (sm, dark)))
-        scheme = gtk_source_style_scheme_manager_get_scheme (sm, "Adwaita");
-    }
-
-  if (style_scheme)
-    {
-      if (scheme)
-        *style_scheme = g_strdup (gtk_source_style_scheme_get_id (scheme));
-      else
-        *style_scheme = NULL;
-    }
-
+  *style_scheme = g_strdup (editor_application_get_style_scheme (EDITOR_APPLICATION_DEFAULT));
   return TRUE;
 }
 
@@ -215,6 +163,17 @@ editor_page_gsettings_init (EditorPageGsettings *self)
 {
 }
 
+static void
+editor_page_gsettings_notify_style_scheme_cb (EditorPageGsettings *self,
+                                              GParamSpec          *pspec,
+                                              EditorApplication   *app)
+{
+  g_assert (EDITOR_IS_PAGE_GSETTINGS (self));
+  g_assert (EDITOR_IS_APPLICATION (app));
+
+  g_object_notify (G_OBJECT (self), "style-scheme");
+}
+
 EditorPageSettingsProvider *
 _editor_page_gsettings_new (GSettings *settings)
 {
@@ -231,5 +190,11 @@ _editor_page_gsettings_new (GSettings *settings)
                            self,
                            G_CONNECT_SWAPPED);
 
+  g_signal_connect_object (EDITOR_APPLICATION_DEFAULT,
+                           "notify::style-scheme",
+                           G_CALLBACK (editor_page_gsettings_notify_style_scheme_cb),
+                           self,
+                           G_CONNECT_SWAPPED);
+
   return EDITOR_PAGE_SETTINGS_PROVIDER (self);
 }


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