[gnome-builder] xml-pack: remove use of weak pointers



commit bbb1770741b614b00c4a632ad292b7f6560f2cf9
Author: Christian Hergert <chergert redhat com>
Date:   Sat Jun 16 17:16:03 2018 -0700

    xml-pack: remove use of weak pointers
    
    We really don't want to be in the game of adding/removing weak pointers
    when we can't reliably clear them (due to some design issues in GObject)
    when second-degree (or more) objects are used.
    
    So instead try to avoid using them altogether.
    
    This might be related to #531

 src/plugins/xml-pack/ide-xml-highlighter.c | 219 ++++++++++-------------------
 1 file changed, 74 insertions(+), 145 deletions(-)
---
diff --git a/src/plugins/xml-pack/ide-xml-highlighter.c b/src/plugins/xml-pack/ide-xml-highlighter.c
index 266473c6d..3e8656459 100644
--- a/src/plugins/xml-pack/ide-xml-highlighter.c
+++ b/src/plugins/xml-pack/ide-xml-highlighter.c
@@ -16,6 +16,10 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include "config.h"
+
+#define G_LOG_DOMAIN "ide-xml-highlighter"
+
 #include <dazzle.h>
 #include <glib/gi18n.h>
 
@@ -28,11 +32,8 @@
 struct _IdeXmlHighlighter
 {
   IdeObject           parent_instance;
-
-  DzlSignalGroup     *signal_group;
-  GtkTextMark        *iter_mark;
   IdeHighlightEngine *engine;
-  GtkTextBuffer      *buffer;
+  DzlSignalGroup     *buffer_signals;
   guint               highlight_timeout;
   guint               has_tags : 1;
 };
@@ -48,18 +49,20 @@ static gboolean
 ide_xml_highlighter_highlight_timeout_handler (gpointer data)
 {
   IdeXmlHighlighter *self = data;
+  GtkTextBuffer *buffer;
+  GtkTextMark *insert;
   GtkTextTag *tag;
   GtkTextIter iter;
   GtkTextIter start;
   GtkTextIter end;
 
   g_assert (IDE_IS_XML_HIGHLIGHTER (self));
-  g_assert (self->buffer != NULL);
-  g_assert (self->iter_mark != NULL);
 
   if (self->engine == NULL)
     goto cleanup;
 
+  buffer = GTK_TEXT_BUFFER (ide_highlight_engine_get_buffer (self->engine));
+  insert = gtk_text_buffer_get_insert (buffer);
   tag = ide_highlight_engine_get_style (self->engine, XML_TAG_MATCH_STYLE_NAME);
 
   /*
@@ -69,51 +72,40 @@ ide_xml_highlighter_highlight_timeout_handler (gpointer data)
    */
   if (self->has_tags)
     {
-      gtk_text_buffer_get_bounds (self->buffer, &start, &end);
-      gtk_text_buffer_remove_tag (self->buffer, tag, &start, &end);
+      gtk_text_buffer_get_bounds (buffer, &start, &end);
+      gtk_text_buffer_remove_tag (buffer, tag, &start, &end);
 
       self->has_tags = FALSE;
     }
 
+  gtk_text_buffer_get_iter_at_mark (buffer, &iter, insert);
 
-  gtk_text_buffer_get_iter_at_mark (self->buffer, &iter, self->iter_mark);
-  if (ide_xml_in_element (&iter) && ide_xml_get_current_element (&iter,
-                                                                 &start,
-                                                                 &end))
+  if (ide_xml_in_element (&iter) && ide_xml_get_current_element (&iter, &start, &end))
     {
+      IdeXmlElementTagType tag_type = ide_xml_get_element_tag_type (&start, &end);
       GtkTextIter next_start;
       GtkTextIter next_end;
-      IdeXmlElementTagType tag_type = ide_xml_get_element_tag_type (&start,
-                                                                    &end);
 
       if ((tag_type == IDE_XML_ELEMENT_TAG_START &&
-          ide_xml_find_closing_element (&start,&end,
-                                      &next_start,&next_end)) ||
+          ide_xml_find_closing_element (&start, &end, &next_start, &next_end)) ||
           (tag_type == IDE_XML_ELEMENT_TAG_END &&
-          ide_xml_find_opening_element (&start,&end,
-                                      &next_start,&next_end)) ||
+          ide_xml_find_opening_element (&start, &end, &next_start, &next_end)) ||
           tag_type == IDE_XML_ELEMENT_TAG_START_END)
         {
 
           /*
-           * All iters point to the begining of < char and the
-           * beginning of > char.In our case we want to highlight everything that is
-           * between those two chars.This is the reason we move one char forward
-           * from the start iter
+           * All iters point to the begining of < char and the beginning of >
+           * char. In our case we want to highlight everything that is between
+           * those two chars.This is the reason we move one char forward from
+           * the start iter.
            */
           gtk_text_iter_forward_char (&start);
-          gtk_text_buffer_apply_tag (GTK_TEXT_BUFFER (self->buffer),
-                                     tag,
-                                     &start,
-                                     &end);
+          gtk_text_buffer_apply_tag (buffer, tag, &start, &end);
 
           if (tag_type != IDE_XML_ELEMENT_TAG_START_END)
             {
               gtk_text_iter_forward_char (&next_start);
-              gtk_text_buffer_apply_tag (GTK_TEXT_BUFFER (self->buffer),
-                                         tag,
-                                         &next_start,
-                                         &next_end);
+              gtk_text_buffer_apply_tag (buffer, tag, &next_start, &next_end);
             }
 
           self->has_tags = TRUE;
@@ -127,84 +119,53 @@ cleanup:
 }
 
 static void
-ide_xml_highlighter_bind_buffer_cb (IdeXmlHighlighter  *self,
-                                    IdeBuffer          *buffer,
-                                    DzlSignalGroup     *group)
+ide_xml_highlighter_cursor_moved (IdeXmlHighlighter *self,
+                                  const GtkTextIter *iter,
+                                  IdeBuffer         *buffer)
 {
-  GtkTextIter begin;
-
   g_assert (IDE_IS_XML_HIGHLIGHTER (self));
+  g_assert (iter != NULL);
   g_assert (IDE_IS_BUFFER (buffer));
-  g_assert (DZL_IS_SIGNAL_GROUP (group));
-
-  dzl_set_weak_pointer (&self->buffer, GTK_TEXT_BUFFER (buffer));
-
-  gtk_text_buffer_get_start_iter (self->buffer, &begin);
-  self->iter_mark = gtk_text_buffer_create_mark (self->buffer, NULL, &begin, TRUE);
-}
-
-static void
-ide_xml_highlighter_unbind_buffer_cb (IdeXmlHighlighter  *self,
-                                      DzlSignalGroup     *group)
-{
-  g_assert (IDE_IS_XML_HIGHLIGHTER (self));
-  g_assert (DZL_IS_SIGNAL_GROUP (group));
-  g_assert (self->buffer != NULL);
-
-  if (self->highlight_timeout != 0)
-    {
-      g_source_remove (self->highlight_timeout);
-      self->highlight_timeout = 0;
-    }
 
-  gtk_text_buffer_delete_mark (self->buffer, self->iter_mark);
-  self->iter_mark = NULL;
+  dzl_clear_source (&self->highlight_timeout);
 
-  dzl_clear_weak_pointer (&self->buffer);
+  self->highlight_timeout =
+    gdk_threads_add_timeout_full (G_PRIORITY_LOW,
+                                  HIGHLIGH_TIMEOUT_MSEC,
+                                  ide_xml_highlighter_highlight_timeout_handler,
+                                  g_object_ref (self),
+                                  g_object_unref);
 }
 
-
 static void
-ide_xml_highlighter_cursor_moved_cb (GtkTextBuffer     *buffer,
-                                     GtkTextIter       *iter,
-                                     IdeXmlHighlighter *self)
+ide_xml_highlighter_dispose (GObject *object)
 {
-  g_assert (IDE_IS_HIGHLIGHTER (self));
-  g_assert (GTK_IS_TEXT_BUFFER (buffer) && self->buffer == buffer);
+  IdeXmlHighlighter *self = (IdeXmlHighlighter *)object;
 
-  if (self->highlight_timeout != 0)
-    g_source_remove (self->highlight_timeout);
+  dzl_clear_source (&self->highlight_timeout);
+  g_clear_object (&self->buffer_signals);
 
-  gtk_text_buffer_move_mark (buffer, self->iter_mark, iter);
-  self->highlight_timeout = g_timeout_add (HIGHLIGH_TIMEOUT_MSEC,
-                                           ide_xml_highlighter_highlight_timeout_handler,
-                                           self);
+  G_OBJECT_CLASS (ide_xml_highlighter_parent_class)->dispose (object);
 }
 
 static void
-ide_xml_highlighter_set_buffer (IdeXmlHighlighter *highlighter,
-                                IdeBuffer         *buffer)
+ide_xml_highlighter_class_init (IdeXmlHighlighterClass *klass)
 {
-  IdeXmlHighlighter *self = (IdeXmlHighlighter *)highlighter;
-
-  g_assert (IDE_IS_HIGHLIGHTER (self));
-  g_assert (!buffer || IDE_IS_BUFFER (buffer));
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
-  dzl_signal_group_set_target (self->signal_group, buffer);
+  object_class->dispose = ide_xml_highlighter_dispose;
 }
 
 static void
-ide_xml_highlighter_on_buffer_set (IdeXmlHighlighter  *self,
-                                   GParamSpec         *pspec,
-                                   IdeHighlightEngine *engine)
+ide_xml_highlighter_init (IdeXmlHighlighter *self)
 {
-  IdeBuffer *buffer;
+  self->buffer_signals = dzl_signal_group_new (IDE_TYPE_BUFFER);
 
-  g_assert (IDE_IS_XML_HIGHLIGHTER (self));
-  g_assert (IDE_IS_HIGHLIGHT_ENGINE (engine));
-
-  buffer = ide_highlight_engine_get_buffer (engine);
-  ide_xml_highlighter_set_buffer (self, buffer);
+  dzl_signal_group_connect_object (self->buffer_signals,
+                                   "cursor-moved",
+                                   G_CALLBACK (ide_xml_highlighter_cursor_moved),
+                                   self,
+                                   G_CONNECT_SWAPPED);
 }
 
 static void
@@ -214,77 +175,45 @@ ide_xml_highlighter_real_set_engine (IdeHighlighter     *highlighter,
   IdeXmlHighlighter *self = (IdeXmlHighlighter *)highlighter;
   IdeBuffer *buffer = NULL;
 
-  g_return_if_fail (IDE_IS_XML_HIGHLIGHTER (self));
-  g_return_if_fail (IDE_IS_HIGHLIGHT_ENGINE (engine));
-
-  if (dzl_set_weak_pointer (&self->engine, engine))
-    {
-      buffer = ide_highlight_engine_get_buffer (engine);
-      /*
-       * TODO: technically we should connect/disconnect when the
-       *       highlighter changes. but in practice, it is set only
-       *       once.
-       */
-      g_signal_connect_object (engine,
-                               "notify::buffer",
-                               G_CALLBACK (ide_xml_highlighter_on_buffer_set),
-                               self,
-                               G_CONNECT_SWAPPED);
-    }
-
-  ide_xml_highlighter_set_buffer (self, buffer);
-}
+  g_assert (IDE_IS_XML_HIGHLIGHTER (self));
+  g_assert (!engine || IDE_IS_HIGHLIGHT_ENGINE (engine));
 
-static void
-ide_xml_highlighter_dispose (GObject *object)
-{
-  IdeXmlHighlighter *self = (IdeXmlHighlighter *)object;
+  self->engine = engine;
 
-  if (self->highlight_timeout != 0)
+  if (engine != NULL)
     {
-      g_source_remove (self->highlight_timeout);
-      self->highlight_timeout = 0;
-    }
-
-  dzl_clear_weak_pointer (&self->engine);
-  g_clear_object (&self->signal_group);
+      GtkTextIter insert;
 
-  G_OBJECT_CLASS (ide_xml_highlighter_parent_class)->dispose (object);
-}
-
-static void
-ide_xml_highlighter_class_init (IdeXmlHighlighterClass *klass)
-{
-  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+      buffer = ide_highlight_engine_get_buffer (engine);
+      ide_buffer_get_selection_bounds (buffer, &insert, NULL);
+      ide_xml_highlighter_cursor_moved (self, &insert, buffer);
+    }
 
-  object_class->dispose = ide_xml_highlighter_dispose;
+  dzl_signal_group_set_target (self->buffer_signals, buffer);
 }
 
 static void
-ide_xml_highlighter_init (IdeXmlHighlighter *self)
+ide_xml_highlighter_real_update (IdeHighlighter       *highlighter,
+                                 IdeHighlightCallback  callback,
+                                 const GtkTextIter    *range_begin,
+                                 const GtkTextIter    *range_end,
+                                 GtkTextIter          *location)
 {
-  self->signal_group = dzl_signal_group_new (IDE_TYPE_BUFFER);
-  dzl_signal_group_connect_object (self->signal_group,
-                                   "cursor-moved",
-                                   G_CALLBACK (ide_xml_highlighter_cursor_moved_cb),
-                                   self,
-                                   0);
-
-  g_signal_connect_object (self->signal_group,
-                           "bind",
-                           G_CALLBACK (ide_xml_highlighter_bind_buffer_cb),
-                           self,
-                           G_CONNECT_SWAPPED);
-
-  g_signal_connect_object (self->signal_group,
-                           "unbind",
-                           G_CALLBACK (ide_xml_highlighter_unbind_buffer_cb),
-                           self,
-                           G_CONNECT_SWAPPED);
+  g_assert (IDE_IS_XML_HIGHLIGHTER (highlighter));
+  g_assert (range_begin != NULL);
+  g_assert (range_end != NULL);
+  g_assert (location != NULL);
+
+  /* We don't do any immediate processing. So let the engine thing
+   * we are done immediately. Instead, we'll introduce a delay to
+   * update the matching element.
+   */
+  *location = *range_end;
 }
 
 static void
 highlighter_iface_init (IdeHighlighterInterface *iface)
 {
   iface->set_engine = ide_xml_highlighter_real_set_engine;
+  iface->update = ide_xml_highlighter_real_update;
 }


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