[gtksourceview] hover: keep GSource around for re-use



commit 75a97f3e7a4cf3cd8bc46305070fbbc899470168
Author: Christian Hergert <chergert redhat com>
Date:   Wed Aug 31 12:15:24 2022 -0700

    hover: keep GSource around for re-use
    
    One minor value of this is that we can set the name without incurring the
    GMainContext/Source locks multiple times. Just set it (without those locks)
    after creation so long as we have a GSource pointer.
    
    Additionally, and more importantly, if we keep the GSource around, we can
    change the ready time on the GTimeoutSource instead of remove/add flows
    which are not ideal when you do as many updates as we do.

 gtksourceview/gtksourcehover.c | 62 ++++++++++++++++++++++++++++--------------
 1 file changed, 41 insertions(+), 21 deletions(-)
---
diff --git a/gtksourceview/gtksourcehover.c b/gtksourceview/gtksourcehover.c
index ec964fda..b7125813 100644
--- a/gtksourceview/gtksourcehover.c
+++ b/gtksourceview/gtksourcehover.c
@@ -65,7 +65,8 @@ struct _GtkSourceHover
        double              motion_y;
 
        guint               hover_delay;
-       guint               settle_source;
+
+       GSource            *settle_source;
 };
 
 G_DEFINE_TYPE (GtkSourceHover, gtk_source_hover, G_TYPE_OBJECT)
@@ -79,14 +80,26 @@ enum {
 static GParamSpec *properties [N_PROPS];
 
 static void
-cursor_moved_cb (GtkSourceHover  *hover,
+gtk_source_hover_dismiss (GtkSourceHover *self)
+{
+       g_assert (GTK_SOURCE_IS_HOVER (self));
+
+       g_clear_pointer (&self->settle_source, g_source_destroy);
+
+       if (self->assistant != NULL)
+       {
+               _gtk_source_hover_assistant_dismiss (GTK_SOURCE_HOVER_ASSISTANT (self->assistant));
+       }
+}
+
+static void
+cursor_moved_cb (GtkSourceHover  *self,
                 GtkSourceBuffer *buffer)
 {
-       g_assert (GTK_SOURCE_IS_HOVER (hover));
+       g_assert (GTK_SOURCE_IS_HOVER (self));
        g_assert (GTK_SOURCE_IS_BUFFER (buffer));
 
-       g_clear_handle_id (&hover->settle_source, g_source_remove);
-       _gtk_source_hover_assistant_dismiss (GTK_SOURCE_HOVER_ASSISTANT (hover->assistant));
+       gtk_source_hover_dismiss (self);
 }
 
 static void
@@ -211,7 +224,7 @@ gtk_source_hover_settled_cb (GtkSourceHover *self)
 
        g_assert (GTK_SOURCE_IS_HOVER (self));
 
-       self->settle_source = 0;
+       g_clear_pointer (&self->settle_source, g_source_destroy);
 
        if (gtk_source_hover_get_bounds (self, &begin, &end, &location))
        {
@@ -229,10 +242,18 @@ gtk_source_hover_queue_settle (GtkSourceHover *self)
 {
        g_assert (GTK_SOURCE_IS_HOVER (self));
 
-       g_clear_handle_id (&self->settle_source, g_source_remove);
-       self->settle_source = g_timeout_add (self->hover_delay,
-                                            (GSourceFunc) gtk_source_hover_settled_cb,
-                                            self);
+       if G_LIKELY (self->settle_source != NULL)
+       {
+               gint64 ready_time = g_get_monotonic_time () + (1000L * self->hover_delay);
+               g_source_set_ready_time (self->settle_source, ready_time);
+               return;
+       }
+
+       self->settle_source = g_timeout_source_new (self->hover_delay);
+       g_source_set_callback (self->settle_source, (GSourceFunc)gtk_source_hover_settled_cb, self, NULL);
+       g_source_set_name (self->settle_source, "gtk-source-hover-settle");
+       g_source_attach (self->settle_source, g_main_context_default ());
+       g_source_unref (self->settle_source);
 }
 
 static gboolean
@@ -245,13 +266,11 @@ gtk_source_hover_key_pressed_cb (GtkSourceHover        *self,
        g_assert (GTK_SOURCE_IS_HOVER (self));
        g_assert (GTK_IS_EVENT_CONTROLLER_KEY (controller));
 
-       g_clear_handle_id (&self->settle_source, g_source_remove);
-       _gtk_source_hover_assistant_dismiss (GTK_SOURCE_HOVER_ASSISTANT (self->assistant));
+       gtk_source_hover_dismiss (self);
 
        return GDK_EVENT_PROPAGATE;
 }
 
-
 static void
 gtk_source_hover_motion_cb (GtkSourceHover           *self,
                             double                    x,
@@ -280,7 +299,7 @@ gtk_source_hover_leave_cb (GtkSourceHover           *self,
        g_assert (GTK_SOURCE_IS_HOVER (self));
        g_assert (GTK_IS_EVENT_CONTROLLER_MOTION (controller));
 
-       g_clear_handle_id (&self->settle_source, g_source_remove);
+       g_clear_pointer (&self->settle_source, g_source_destroy);
 }
 
 static gboolean
@@ -292,8 +311,7 @@ gtk_source_hover_scroll_cb (GtkSourceHover           *self,
        g_assert (GTK_SOURCE_IS_HOVER (self));
        g_assert (GTK_IS_EVENT_CONTROLLER_SCROLL (controller));
 
-       g_clear_handle_id (&self->settle_source, g_source_remove);
-       _gtk_source_hover_assistant_dismiss (GTK_SOURCE_HOVER_ASSISTANT (self->assistant));
+       gtk_source_hover_dismiss (self);
 
        return GDK_EVENT_PROPAGATE;
 }
@@ -303,16 +321,18 @@ gtk_source_hover_dispose (GObject *object)
 {
        GtkSourceHover *self = (GtkSourceHover *)object;
 
-       g_clear_handle_id (&self->settle_source, g_source_remove);
-       g_clear_pointer (&self->assistant, _gtk_source_assistant_destroy);
-       g_clear_weak_pointer (&self->view);
-       g_clear_weak_pointer (&self->buffer);
 
        if (self->providers->len > 0)
        {
                g_ptr_array_remove_range (self->providers, 0, self->providers->len);
        }
 
+       g_clear_pointer (&self->settle_source, g_source_destroy);
+       g_clear_pointer (&self->assistant, _gtk_source_assistant_destroy);
+
+       g_clear_weak_pointer (&self->view);
+       g_clear_weak_pointer (&self->buffer);
+
        G_OBJECT_CLASS (gtk_source_hover_parent_class)->dispose (object);
 }
 
@@ -324,7 +344,7 @@ gtk_source_hover_finalize (GObject *object)
        g_clear_pointer (&self->providers, g_ptr_array_unref);
 
        g_assert (self->assistant == NULL);
-       g_assert (self->settle_source == 0);
+       g_assert (self->settle_source == NULL);
 
        G_OBJECT_CLASS (gtk_source_hover_parent_class)->finalize (object);
 }


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