[gnome-text-editor] sourceview: use page settings to plumb font description



commit a727808c63fa7f0a57a0d833309fafdb04413560
Author: Christian Hergert <chergert redhat com>
Date:   Wed Jul 28 18:31:50 2021 -0700

    sourceview: use page settings to plumb font description
    
    This is better than using the application global css provider because we
    can eventually use it to tweak zoom on a per-view basis.

 src/editor-application.c    |  50 -------------------
 src/editor-page-gsettings.c |   9 ++++
 src/editor-page.c           |  20 ++++++++
 src/editor-source-view.c    | 117 ++++++++++++++++++++++++++++++++++++++++++++
 src/editor-source-view.h    |   4 ++
 5 files changed, 150 insertions(+), 50 deletions(-)
---
diff --git a/src/editor-application.c b/src/editor-application.c
index f1031b2..2919e5d 100644
--- a/src/editor-application.c
+++ b/src/editor-application.c
@@ -29,40 +29,6 @@
 
 G_DEFINE_TYPE (EditorApplication, editor_application, GTK_TYPE_APPLICATION)
 
-static void
-editor_application_update_font_cb (GSettings      *settings,
-                                   const gchar    *key,
-                                   GtkCssProvider *font_css_provider)
-{
-  g_autoptr(GString) css = NULL;
-
-  g_assert (G_IS_SETTINGS (settings));
-  g_assert (GTK_IS_CSS_PROVIDER (font_css_provider));
-
-  css = g_string_new ("textview.editor {\n");
-
-  if (!g_settings_get_boolean (settings, "use-system-font"))
-    {
-      PangoFontDescription *font_desc = NULL;
-      g_autofree gchar *custom_font = NULL;
-      g_autofree gchar *font_css = NULL;
-
-      if ((custom_font = g_settings_get_string (settings, "custom-font")) &&
-          (font_desc = pango_font_description_from_string (custom_font)) &&
-          (font_css = _editor_font_description_to_css (font_desc)))
-        {
-          g_string_append (css, font_css);
-          g_string_append_c (css, '\n');
-        }
-
-      pango_font_description_free (font_desc);
-    }
-
-  g_string_append (css, "}\n");
-
-  gtk_css_provider_load_from_data (font_css_provider, css->str, css->len);
-}
-
 static void
 editor_application_restore_cb (GObject      *object,
                                GAsyncResult *result,
@@ -174,7 +140,6 @@ editor_application_startup (GApplication *application)
 {
   EditorApplication *self = (EditorApplication *)application;
   g_autoptr(GtkCssProvider) css_provider = NULL;
-  g_autoptr(GtkCssProvider) font_css_provider = NULL;
   GtkSettings *gtk_settings;
   static const gchar *quit_accels[] = { "<Primary>Q", NULL };
   static const gchar *help_accels[] = { "F1", NULL };
@@ -209,21 +174,6 @@ editor_application_startup (GApplication *application)
                                               GTK_STYLE_PROVIDER (css_provider),
                                               GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
 
-  /* Setup CSS for custom fonts */
-  font_css_provider = gtk_css_provider_new ();
-  g_signal_connect_object (self->settings,
-                           "changed::use-system-font",
-                           G_CALLBACK (editor_application_update_font_cb),
-                           font_css_provider, 0);
-  g_signal_connect_object (self->settings,
-                           "changed::custom-font",
-                           G_CALLBACK (editor_application_update_font_cb),
-                           font_css_provider, 0);
-  gtk_style_context_add_provider_for_display (gdk_display_get_default (),
-                                              GTK_STYLE_PROVIDER (font_css_provider),
-                                              GTK_STYLE_PROVIDER_PRIORITY_APPLICATION+1);
-  editor_application_update_font_cb (self->settings, NULL, font_css_provider);
-
   gtk_window_set_default_icon_name (PACKAGE_ICON_NAME);
 }
 
diff --git a/src/editor-page-gsettings.c b/src/editor-page-gsettings.c
index 9ae459e..435bdb3 100644
--- a/src/editor-page-gsettings.c
+++ b/src/editor-page-gsettings.c
@@ -135,6 +135,14 @@ editor_page_gsettings_get_style_variant (EditorPageSettingsProvider  *provider,
   return TRUE;
 }
 
+static gboolean
+editor_page_gsettings_get_custom_font (EditorPageSettingsProvider  *provider,
+                                       gchar                      **custom_font)
+{
+  *custom_font = g_settings_get_string (EDITOR_PAGE_GSETTINGS (provider)->settings, "custom-font");
+  return TRUE;
+}
+
 static void
 editor_page_gsettings_changed_cb (EditorPageGsettings *self,
                                   const gchar         *key,
@@ -149,6 +157,7 @@ editor_page_gsettings_changed_cb (EditorPageGsettings *self,
 static void
 page_settings_provider_iface_init (EditorPageSettingsProviderInterface *iface)
 {
+  iface->get_custom_font = editor_page_gsettings_get_custom_font;
   iface->get_insert_spaces_instead_of_tabs = editor_page_gsettings_get_insert_spaces_instead_of_tabs;
   iface->get_right_margin_position = editor_page_gsettings_get_right_margin_position;
   iface->get_show_line_numbers = editor_page_gsettings_get_show_line_numbers;
diff --git a/src/editor-page.c b/src/editor-page.c
index 315ec85..ca7a4ef 100644
--- a/src/editor-page.c
+++ b/src/editor-page.c
@@ -252,6 +252,22 @@ boolean_to_left_margin (GBinding     *binding,
   return TRUE;
 }
 
+static gboolean
+font_desc_from_string (GBinding     *binding,
+                       const GValue *from_value,
+                       GValue       *to_value,
+                       gpointer      user_data)
+{
+  const char *str = g_value_get_string (from_value);
+
+  if (str)
+    g_value_take_boxed (to_value, pango_font_description_from_string (str));
+  else
+    g_value_set_boxed (to_value, NULL);
+
+  return TRUE;
+}
+
 static void
 editor_page_constructed (GObject *object)
 {
@@ -263,6 +279,10 @@ editor_page_constructed (GObject *object)
 
   self->settings_bindings = editor_binding_group_new ();
 
+  editor_binding_group_bind_full (self->settings_bindings, "custom-font",
+                                  self->view, "font-desc",
+                                  G_BINDING_SYNC_CREATE,
+                                  font_desc_from_string, NULL, NULL, NULL);
   editor_binding_group_bind (self->settings_bindings, "insert-spaces-instead-of-tabs",
                              self->view, "insert-spaces-instead-of-tabs",
                              G_BINDING_SYNC_CREATE);
diff --git a/src/editor-source-view.c b/src/editor-source-view.c
index a802990..481305c 100644
--- a/src/editor-source-view.c
+++ b/src/editor-source-view.c
@@ -24,16 +24,27 @@
 #include "editor-source-view.h"
 #include "editor-joined-menu-private.h"
 #include "editor-spell-menu.h"
+#include "editor-utils-private.h"
 
 struct _EditorSourceView
 {
   GtkSourceView parent_instance;
+  GtkCssProvider *css_provider;
+  PangoFontDescription *font_desc;
   GMenuModel *spelling_menu;
   char *spelling_word;
 };
 
 G_DEFINE_TYPE (EditorSourceView, editor_source_view, GTK_SOURCE_TYPE_VIEW)
 
+enum {
+  PROP_0,
+  PROP_FONT_DESC,
+  N_PROPS
+};
+
+static GParamSpec *properties [N_PROPS];
+
 static gboolean
 on_key_pressed_cb (GtkEventControllerKey *key,
                    guint                  keyval,
@@ -270,12 +281,51 @@ editor_source_view_finalize (GObject *object)
 {
   EditorSourceView *self = (EditorSourceView *)object;
 
+  g_clear_object (&self->css_provider);
   g_clear_object (&self->spelling_menu);
   g_clear_pointer (&self->spelling_word, g_free);
 
   G_OBJECT_CLASS (editor_source_view_parent_class)->finalize (object);
 }
 
+static void
+editor_source_view_get_property (GObject    *object,
+                                 guint       prop_id,
+                                 GValue     *value,
+                                 GParamSpec *pspec)
+{
+  EditorSourceView *self = EDITOR_SOURCE_VIEW (object);
+
+  switch (prop_id)
+    {
+    case PROP_FONT_DESC:
+      g_value_set_boxed (value, editor_source_view_get_font_desc (self));
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+editor_source_view_set_property (GObject      *object,
+                                 guint         prop_id,
+                                 const GValue *value,
+                                 GParamSpec   *pspec)
+{
+  EditorSourceView *self = EDITOR_SOURCE_VIEW (object);
+
+  switch (prop_id)
+    {
+    case PROP_FONT_DESC:
+      editor_source_view_set_font_desc (self, g_value_get_boxed (value));
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
 static void
 editor_source_view_class_init (EditorSourceViewClass *klass)
 {
@@ -283,6 +333,17 @@ editor_source_view_class_init (EditorSourceViewClass *klass)
   GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
 
   object_class->finalize = editor_source_view_finalize;
+  object_class->get_property = editor_source_view_get_property;
+  object_class->set_property = editor_source_view_set_property;
+
+  properties [PROP_FONT_DESC] =
+    g_param_spec_boxed ("font-desc",
+                         "Font Description",
+                         "The font to use for text within the editor",
+                         PANGO_TYPE_FONT_DESCRIPTION,
+                         (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_properties (object_class, N_PROPS, properties);
 
   gtk_widget_class_install_action (widget_class, "spelling.add", NULL, 
editor_source_view_action_spelling_add);
   gtk_widget_class_install_action (widget_class, "spelling.ignore", NULL, 
editor_source_view_action_spelling_ignore);
@@ -296,12 +357,19 @@ editor_source_view_init (EditorSourceView *self)
   g_autoptr(GMenu) gsv_section = NULL;
   g_autoptr(GMenu) spell_section = NULL;
   GtkEventController *controller;
+  GtkStyleContext *style_context;
   GMenuModel *extra_menu;
 
   gtk_widget_action_set_enabled (GTK_WIDGET (self), "spelling.add", FALSE);
   gtk_widget_action_set_enabled (GTK_WIDGET (self), "spelling.ignore", FALSE);
   gtk_widget_action_set_enabled (GTK_WIDGET (self), "spelling.correct", FALSE);
 
+  self->css_provider = gtk_css_provider_new ();
+  style_context = gtk_widget_get_style_context (GTK_WIDGET (self));
+  gtk_style_context_add_provider (style_context,
+                                  GTK_STYLE_PROVIDER (self->css_provider),
+                                  GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
+
   g_signal_connect (self,
                     "notify::buffer",
                     G_CALLBACK (on_notify_buffer_cb),
@@ -338,3 +406,52 @@ editor_source_view_init (EditorSourceView *self)
 
   gtk_text_view_set_extra_menu (GTK_TEXT_VIEW (self), G_MENU_MODEL (joined));
 }
+
+static void
+editor_source_view_update_css (EditorSourceView *self)
+{
+  g_autoptr(GString) str = NULL;
+  g_autofree char *font_css = NULL;
+
+  g_assert (EDITOR_IS_SOURCE_VIEW (self));
+
+  str = g_string_new ("textview {\n");
+  if (self->font_desc)
+    {
+      font_css = _editor_font_description_to_css (self->font_desc);
+      g_string_append (str, font_css);
+      g_string_append_c (str, '\n');
+    }
+  g_string_append (str, "}\n");
+
+  gtk_css_provider_load_from_data (self->css_provider, str->str, -1);
+}
+
+const PangoFontDescription *
+editor_source_view_get_font_desc (EditorSourceView *self)
+{
+  g_return_val_if_fail (EDITOR_IS_SOURCE_VIEW (self), NULL);
+
+  return self->font_desc;
+}
+
+void
+editor_source_view_set_font_desc (EditorSourceView           *self,
+                                  const PangoFontDescription *font_desc)
+{
+  g_return_if_fail (EDITOR_IS_SOURCE_VIEW (self));
+
+  if (self->font_desc == font_desc ||
+      (self->font_desc != NULL && font_desc != NULL &&
+       pango_font_description_equal (self->font_desc, font_desc)))
+    return;
+
+  g_clear_pointer (&self->font_desc, pango_font_description_free);
+
+  if (font_desc)
+    self->font_desc = pango_font_description_copy (font_desc);
+
+  editor_source_view_update_css (self);
+
+  g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_FONT_DESC]);
+}
diff --git a/src/editor-source-view.h b/src/editor-source-view.h
index e7fb0d2..8a0cac2 100644
--- a/src/editor-source-view.h
+++ b/src/editor-source-view.h
@@ -28,4 +28,8 @@ G_BEGIN_DECLS
 
 G_DECLARE_FINAL_TYPE (EditorSourceView, editor_source_view, EDITOR, SOURCE_VIEW, GtkSourceView)
 
+const PangoFontDescription *editor_source_view_get_font_desc (EditorSourceView           *self);
+void                        editor_source_view_set_font_desc (EditorSourceView           *self,
+                                                              const PangoFontDescription *font_desc);
+
 G_END_DECLS


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