[gtksourceview] assistant: queue reposition handler to frame callback



commit d9cf55f4beba19c0866bf73369deb814d203f6f9
Author: Christian Hergert <chergert redhat com>
Date:   Thu Sep 1 12:57:50 2022 -0700

    assistant: queue reposition handler to frame callback
    
    Instead of trying to reposition a popover synchronously from the popover's
    frame-clock, try to perform that work from the beginning of the view's
    next frame clock. That way, we are less likely to mess up any sort of
    allocation/state used by the view.

 gtksourceview/gtksourceassistant-private.h | 28 +++++++--------
 gtksourceview/gtksourceassistant.c         | 56 ++++++++++++++++++++++++++++--
 gtksourceview/gtksourcecompletionlist.c    |  2 +-
 gtksourceview/gtksourceview-snippets.c     |  2 +-
 4 files changed, 69 insertions(+), 19 deletions(-)
---
diff --git a/gtksourceview/gtksourceassistant-private.h b/gtksourceview/gtksourceassistant-private.h
index d8d2084b..568e0d7d 100644
--- a/gtksourceview/gtksourceassistant-private.h
+++ b/gtksourceview/gtksourceassistant-private.h
@@ -42,19 +42,19 @@ struct _GtkSourceAssistantClass
                                     GdkRectangle       *rect);
 };
 
-GtkSourceAssistant *_gtk_source_assistant_new        (void);
-void                _gtk_source_assistant_attach     (GtkSourceAssistant *assistant,
-                                                      GtkSourceAssistant *attached_to);
-void                _gtk_source_assistant_detach     (GtkSourceAssistant *assistant);
-void                _gtk_source_assistant_get_offset (GtkSourceAssistant *assistant,
-                                                      int                *x,
-                                                      int                *y);
-GtkTextMark        *_gtk_source_assistant_get_mark   (GtkSourceAssistant *assistant);
-void                _gtk_source_assistant_set_mark   (GtkSourceAssistant *assistant,
-                                                      GtkTextMark        *mark);
-void                _gtk_source_assistant_set_child  (GtkSourceAssistant *assistant,
-                                                      GtkWidget          *child);
-void                _gtk_source_assistant_reposition (GtkSourceAssistant *assistant);
-void                _gtk_source_assistant_destroy    (GtkSourceAssistant *assistant);
+GtkSourceAssistant *_gtk_source_assistant_new                (void);
+void                _gtk_source_assistant_attach             (GtkSourceAssistant *assistant,
+                                                              GtkSourceAssistant *attached_to);
+void                _gtk_source_assistant_detach             (GtkSourceAssistant *assistant);
+void                _gtk_source_assistant_get_offset         (GtkSourceAssistant *assistant,
+                                                              int                *x,
+                                                              int                *y);
+GtkTextMark        *_gtk_source_assistant_get_mark           (GtkSourceAssistant *assistant);
+void                _gtk_source_assistant_set_mark           (GtkSourceAssistant *assistant,
+                                                              GtkTextMark        *mark);
+void                _gtk_source_assistant_set_child          (GtkSourceAssistant *assistant,
+                                                              GtkWidget          *child);
+void                _gtk_source_assistant_set_needs_position (GtkSourceAssistant *assistant);
+void                _gtk_source_assistant_destroy            (GtkSourceAssistant *assistant);
 
 G_END_DECLS
diff --git a/gtksourceview/gtksourceassistant.c b/gtksourceview/gtksourceassistant.c
index 200b4f93..0ef889b7 100644
--- a/gtksourceview/gtksourceassistant.c
+++ b/gtksourceview/gtksourceassistant.c
@@ -29,6 +29,7 @@ typedef struct
 {
        GtkTextMark             *mark;
        GtkSourceAssistantChild *child;
+       guint                    reposition_handler;
 } GtkSourceAssistantPrivate;
 
 static void buildable_iface_init (GtkBuildableIface *iface);
@@ -161,12 +162,48 @@ _gtk_source_assistant_update_position (GtkSourceAssistant *assistant)
        }
 }
 
+static gboolean
+gtk_source_assistant_reposition_tick_cb (GtkWidget     *widget,
+                                         GdkFrameClock *frame_clock,
+                                         gpointer       user_data)
+{
+       GtkSourceView *view = (GtkSourceView *)widget;
+       GtkSourceAssistant *self = user_data;
+       GtkSourceAssistantPrivate *priv = _gtk_source_assistant_get_instance_private (self);
+
+       g_assert (GTK_SOURCE_IS_VIEW (view));
+       g_assert (GDK_IS_FRAME_CLOCK (frame_clock));
+       g_assert (GTK_SOURCE_IS_ASSISTANT (self));
+
+       priv->reposition_handler = 0;
+
+       _gtk_source_assistant_update_position (self);
+
+       return G_SOURCE_REMOVE;
+}
+
 void
-_gtk_source_assistant_reposition (GtkSourceAssistant *self)
+_gtk_source_assistant_set_needs_position (GtkSourceAssistant *self)
 {
+       GtkSourceAssistantPrivate *priv = _gtk_source_assistant_get_instance_private (self);
+
        g_return_if_fail (GTK_SOURCE_IS_ASSISTANT (self));
 
-       _gtk_source_assistant_update_position (self);
+       if (priv->reposition_handler == 0)
+       {
+               GtkSourceView *view = _gtk_source_assistant_get_view (self);
+
+               if (view == NULL)
+               {
+                       return;
+               }
+
+               priv->reposition_handler =
+                       gtk_widget_add_tick_callback (GTK_WIDGET (view),
+                                                     gtk_source_assistant_reposition_tick_cb,
+                                                     g_object_ref (self),
+                                                     g_object_unref);
+       }
 }
 
 static void
@@ -176,7 +213,7 @@ _gtk_source_assistant_show (GtkWidget *widget)
 
        g_assert (GTK_SOURCE_IS_ASSISTANT (assistant));
 
-       _gtk_source_assistant_reposition (assistant);
+       _gtk_source_assistant_update_position (assistant);
 
        GTK_WIDGET_CLASS (_gtk_source_assistant_parent_class)->show (widget);
 }
@@ -232,6 +269,19 @@ _gtk_source_assistant_dispose (GObject *object)
 
        g_assert (GTK_SOURCE_IS_ASSISTANT (self));
 
+       if (priv->reposition_handler != 0)
+       {
+               GtkSourceView *view = _gtk_source_assistant_get_view (self);
+
+               if (view != NULL)
+               {
+                       gtk_widget_remove_tick_callback (GTK_WIDGET (view),
+                                                        priv->reposition_handler);
+               }
+
+               priv->reposition_handler = 0;
+       }
+
        _gtk_source_assistant_detach (self);
        g_clear_object (&priv->mark);
 
diff --git a/gtksourceview/gtksourcecompletionlist.c b/gtksourceview/gtksourcecompletionlist.c
index 2bd308ef..c97a9bdd 100644
--- a/gtksourceview/gtksourcecompletionlist.c
+++ b/gtksourceview/gtksourcecompletionlist.c
@@ -263,7 +263,7 @@ _gtk_source_completion_list_reposition_cb (GtkSourceCompletionList *self)
 {
        g_assert (GTK_SOURCE_IS_COMPLETION_LIST (self));
 
-       _gtk_source_assistant_reposition (GTK_SOURCE_ASSISTANT (self));
+       _gtk_source_assistant_set_needs_position (GTK_SOURCE_ASSISTANT (self));
 }
 
 static void
diff --git a/gtksourceview/gtksourceview-snippets.c b/gtksourceview/gtksourceview-snippets.c
index 1df21253..55195d37 100644
--- a/gtksourceview/gtksourceview-snippets.c
+++ b/gtksourceview/gtksourceview-snippets.c
@@ -363,7 +363,7 @@ gtk_source_view_snippets_update_informative (GtkSourceViewSnippets *snippets)
 
        if (gtk_widget_get_visible (GTK_WIDGET (snippets->informative)))
        {
-               _gtk_source_assistant_reposition (GTK_SOURCE_ASSISTANT (snippets->informative));
+               _gtk_source_assistant_set_needs_position (GTK_SOURCE_ASSISTANT (snippets->informative));
        }
        else
        {


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