[gtksourceview/wip/chergert/fix-262: 1/2] gutter: notify gutter renderers of buffer changes
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtksourceview/wip/chergert/fix-262: 1/2] gutter: notify gutter renderers of buffer changes
- Date: Wed, 6 Apr 2022 21:36:05 +0000 (UTC)
commit 66d9f2a2b45b48328c9dee92a9342ef225df3699
Author: Christian Hergert <chergert redhat com>
Date: Wed Apr 6 14:33:44 2022 -0700
gutter: notify gutter renderers of buffer changes
This adds a vfunc to GtkSourceGutterRenderer to be notified of changes to
the underlying buffer. Some effort is made to only call this once even
if a bunch of changes are batched up together in buffer processing by
handling it from an idle callback.
Fixes #262
gtksourceview/gtksourcegutter-private.h | 2 +
gtksourceview/gtksourcegutter.c | 13 ++++++
gtksourceview/gtksourcegutterrenderer-private.h | 18 +++++----
gtksourceview/gtksourcegutterrenderer.c | 13 ++++++
gtksourceview/gtksourcegutterrenderer.h | 15 ++++++-
gtksourceview/gtksourceview.c | 53 +++++++++++++++++++++++++
6 files changed, 105 insertions(+), 9 deletions(-)
---
diff --git a/gtksourceview/gtksourcegutter-private.h b/gtksourceview/gtksourcegutter-private.h
index 030cfffc..2d626c0e 100644
--- a/gtksourceview/gtksourcegutter-private.h
+++ b/gtksourceview/gtksourcegutter-private.h
@@ -33,6 +33,8 @@ GtkSourceGutterLines *_gtk_source_gutter_get_lines (GtkSourceGutter *g
G_GNUC_INTERNAL
void _gtk_source_gutter_queue_draw (GtkSourceGutter *gutter);
G_GNUC_INTERNAL
+void _gtk_source_gutter_buffer_changed (GtkSourceGutter *gutter);
+G_GNUC_INTERNAL
void _gtk_source_gutter_css_changed (GtkSourceGutter *gutter,
GtkCssStyleChange *change);
G_GNUC_INTERNAL
diff --git a/gtksourceview/gtksourcegutter.c b/gtksourceview/gtksourcegutter.c
index 4cfc96f2..dcef3bad 100644
--- a/gtksourceview/gtksourcegutter.c
+++ b/gtksourceview/gtksourcegutter.c
@@ -1081,3 +1081,16 @@ _gtk_source_gutter_unapply_scheme (GtkSourceGutter *gutter,
_gtk_source_style_scheme_unapply (scheme, GTK_WIDGET (renderer->renderer));
}
}
+
+void
+_gtk_source_gutter_buffer_changed (GtkSourceGutter *gutter)
+{
+ g_return_if_fail (GTK_SOURCE_IS_GUTTER (gutter));
+
+ for (const GList *iter = gutter->renderers; iter; iter = iter->next)
+ {
+ Renderer *renderer = iter->data;
+
+ _gtk_source_gutter_renderer_buffer_changed (renderer->renderer);
+ }
+}
diff --git a/gtksourceview/gtksourcegutterrenderer-private.h b/gtksourceview/gtksourcegutterrenderer-private.h
index f6c4c99e..1ebbc4f5 100644
--- a/gtksourceview/gtksourcegutterrenderer-private.h
+++ b/gtksourceview/gtksourcegutterrenderer-private.h
@@ -26,16 +26,18 @@
G_BEGIN_DECLS
G_GNUC_INTERNAL
-void _gtk_source_gutter_renderer_set_view (GtkSourceGutterRenderer *renderer,
- GtkSourceView *view);
+void _gtk_source_gutter_renderer_buffer_changed (GtkSourceGutterRenderer *renderer);
G_GNUC_INTERNAL
-void _gtk_source_gutter_renderer_begin (GtkSourceGutterRenderer *renderer,
- GtkSourceGutterLines *lines);
+void _gtk_source_gutter_renderer_set_view (GtkSourceGutterRenderer *renderer,
+ GtkSourceView *view);
G_GNUC_INTERNAL
-void _gtk_source_gutter_renderer_snapshot (GtkSourceGutterRenderer *renderer,
- GtkSnapshot *snapshot,
- GtkSourceGutterLines *lines);
+void _gtk_source_gutter_renderer_begin (GtkSourceGutterRenderer *renderer,
+ GtkSourceGutterLines *lines);
G_GNUC_INTERNAL
-void _gtk_source_gutter_renderer_end (GtkSourceGutterRenderer *renderer);
+void _gtk_source_gutter_renderer_snapshot (GtkSourceGutterRenderer *renderer,
+ GtkSnapshot *snapshot,
+ GtkSourceGutterLines *lines);
+G_GNUC_INTERNAL
+void _gtk_source_gutter_renderer_end (GtkSourceGutterRenderer *renderer);
G_END_DECLS
diff --git a/gtksourceview/gtksourcegutterrenderer.c b/gtksourceview/gtksourcegutterrenderer.c
index a7a253f0..0017b423 100644
--- a/gtksourceview/gtksourcegutterrenderer.c
+++ b/gtksourceview/gtksourcegutterrenderer.c
@@ -1005,3 +1005,16 @@ _gtk_source_gutter_renderer_end (GtkSourceGutterRenderer *renderer)
GTK_SOURCE_GUTTER_RENDERER_GET_CLASS (renderer)->end (renderer);
g_clear_object (&priv->lines);
}
+
+void
+_gtk_source_gutter_renderer_buffer_changed (GtkSourceGutterRenderer *renderer)
+{
+ GtkSourceGutterRendererPrivate *priv = gtk_source_gutter_renderer_get_instance_private (renderer);
+
+ g_return_if_fail (GTK_SOURCE_IS_GUTTER_RENDERER (renderer));
+
+ if (GTK_SOURCE_GUTTER_RENDERER_GET_CLASS (renderer)->buffer_changed)
+ {
+ GTK_SOURCE_GUTTER_RENDERER_GET_CLASS (renderer)->buffer_changed (renderer);
+ }
+}
diff --git a/gtksourceview/gtksourcegutterrenderer.h b/gtksourceview/gtksourcegutterrenderer.h
index e394d794..a0c1f563 100644
--- a/gtksourceview/gtksourcegutterrenderer.h
+++ b/gtksourceview/gtksourcegutterrenderer.h
@@ -90,8 +90,21 @@ struct _GtkSourceGutterRendererClass
GdkModifierType state,
gint n_presses);
+ /**
+ * GtkSourceGutterRendererClass.buffer_changed:
+ *
+ * This virtual function is called when the underlying buffer changes
+ * to allow renderer implementations simplified access to invalidate
+ * any state necessary.
+ *
+ * An attempt is made to only call this once per main-loop cycle.
+ *
+ * Since: 5.6
+ */
+ void (*buffer_changed) (GtkSourceGutterRenderer *renderer);
+
/*< private >*/
- gpointer _reserved[20];
+ gpointer _reserved[19];
};
GTK_SOURCE_AVAILABLE_IN_ALL
diff --git a/gtksourceview/gtksourceview.c b/gtksourceview/gtksourceview.c
index 3d5eaa0b..1893ab11 100644
--- a/gtksourceview/gtksourceview.c
+++ b/gtksourceview/gtksourceview.c
@@ -208,6 +208,8 @@ typedef struct
GtkSourceViewSnippets snippets;
+ guint propagate_change_source;
+
guint background_pattern_color_set : 1;
guint current_line_background_color_set : 1;
guint current_line_number_bold : 1;
@@ -1683,6 +1685,46 @@ implicit_trailing_newline_changed_cb (GtkSourceBuffer *buffer,
gtk_source_view_queue_draw (view);
}
+
+static gboolean
+propagate_change_cb (gpointer data)
+{
+ GtkSourceView *view = data;
+ GtkSourceViewPrivate *priv = gtk_source_view_get_instance_private (view);
+
+ g_assert (GTK_SOURCE_IS_VIEW (view));
+
+ priv->propagate_change_source = 0;
+
+ if (priv->left_gutter)
+ {
+ _gtk_source_gutter_buffer_changed (priv->left_gutter);
+ }
+
+ if (priv->right_gutter)
+ {
+ _gtk_source_gutter_buffer_changed (priv->right_gutter);
+ }
+
+ return G_SOURCE_REMOVE;
+}
+
+static void
+changed_cb (GtkSourceBuffer *buffer,
+ GtkSourceView *view)
+{
+ GtkSourceViewPrivate *priv = gtk_source_view_get_instance_private (view);
+
+ g_assert (GTK_SOURCE_IS_BUFFER (buffer));
+ g_assert (GTK_SOURCE_IS_VIEW (view));
+
+ if (priv->propagate_change_source == 0 &&
+ (priv->left_gutter != NULL || priv->right_gutter != NULL))
+ {
+ priv->propagate_change_source = g_idle_add (propagate_change_cb, view);
+ }
+}
+
static void
remove_source_buffer (GtkSourceView *view)
{
@@ -1692,6 +1734,12 @@ remove_source_buffer (GtkSourceView *view)
{
GtkSourceBufferInternal *buffer_internal;
+ g_clear_handle_id (&priv->propagate_change_source, g_source_remove);
+
+ g_signal_handlers_disconnect_by_func (priv->source_buffer,
+ changed_cb,
+ view);
+
g_signal_handlers_disconnect_by_func (priv->source_buffer,
highlight_updated_cb,
view);
@@ -1744,6 +1792,11 @@ set_source_buffer (GtkSourceView *view,
priv->source_buffer = g_object_ref (GTK_SOURCE_BUFFER (buffer));
+ g_signal_connect (buffer,
+ "changed",
+ G_CALLBACK (changed_cb),
+ view);
+
g_signal_connect (buffer,
"highlight-updated",
G_CALLBACK (highlight_updated_cb),
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]