[gnome-builder/wip/gtk4-port: 1369/1774] libide/webkit: add page variant to track buffer changes




commit d4c94988e3dfcb9bb452aa1a227c091f9efc1a07
Author: Christian Hergert <chergert redhat com>
Date:   Mon Jun 6 12:04:11 2022 -0700

    libide/webkit: add page variant to track buffer changes
    
    This will react to changes in a GtkTextBuffer and display them. We will
    probably want to add a variant of this to do transforms so that we can
    use them with new plugins which want something other than 1:1 mapping
    of buffer content to HTML.

 src/libide/webkit/ide-webkit-page.c | 72 +++++++++++++++++++++++++++++++++++++
 src/libide/webkit/ide-webkit-page.h |  2 ++
 2 files changed, 74 insertions(+)
---
diff --git a/src/libide/webkit/ide-webkit-page.c b/src/libide/webkit/ide-webkit-page.c
index 0f7652777..3647effb4 100644
--- a/src/libide/webkit/ide-webkit-page.c
+++ b/src/libide/webkit/ide-webkit-page.c
@@ -27,6 +27,8 @@
 #include "ide-webkit-page.h"
 #include "ide-url-bar.h"
 
+#define UPDATE_DELAY_MSEC 250
+
 typedef struct
 {
   GtkStack           *reload_stack;
@@ -36,6 +38,10 @@ typedef struct
   WebKitWebView      *web_view;
 
   GSimpleActionGroup *actions;
+
+  /* Used for pages linked to buffers */
+  GtkTextBuffer      *buffer;
+  guint               queued_update_source;
 } IdeWebkitPagePrivate;
 
 enum {
@@ -335,6 +341,8 @@ ide_webkit_page_dispose (GObject *object)
   IdeWebkitPagePrivate *priv = ide_webkit_page_get_instance_private (self);
 
   g_clear_object (&priv->actions);
+  g_clear_object (&priv->buffer);
+  g_clear_handle_id (&priv->queued_update_source, g_source_remove);
 
   G_OBJECT_CLASS (ide_webkit_page_parent_class)->dispose (object);
 }
@@ -573,3 +581,67 @@ ide_webkit_page_reload_ignoring_cache (IdeWebkitPage *self)
 
   webkit_web_view_reload_bypass_cache (priv->web_view);
 }
+
+static gboolean
+ide_webkit_page_do_update_cb (gpointer user_data)
+{
+  IdeWebkitPage *self = user_data;
+  IdeWebkitPagePrivate *priv = ide_webkit_page_get_instance_private (self);
+  g_autofree char *base_uri = NULL;
+  g_autofree char *text = NULL;
+  GtkTextIter begin, end;
+
+  g_assert (IDE_IS_MAIN_THREAD ());
+  g_assert (IDE_IS_WEBKIT_PAGE (self));
+  g_assert (GTK_IS_TEXT_BUFFER (priv->buffer));
+
+  priv->queued_update_source = 0;
+
+  gtk_text_buffer_get_bounds (priv->buffer, &begin, &end);
+  text = gtk_text_iter_get_slice (&begin, &end);
+
+  if (IDE_IS_BUFFER (priv->buffer))
+    base_uri = g_file_get_uri (ide_buffer_get_file (IDE_BUFFER (priv->buffer)));
+
+  webkit_web_view_load_html (priv->web_view, text, base_uri);
+
+  return G_SOURCE_REMOVE;
+}
+
+static void
+ide_webkit_page_buffer_changed_cb (IdeWebkitPage *self,
+                                   GtkTextBuffer *buffer)
+{
+  IdeWebkitPagePrivate *priv = ide_webkit_page_get_instance_private (self);
+
+  g_assert (IDE_IS_MAIN_THREAD ());
+  g_assert (IDE_IS_WEBKIT_PAGE (self));
+  g_assert (GTK_IS_TEXT_BUFFER (buffer));
+
+  if (priv->queued_update_source == 0)
+    priv->queued_update_source = g_timeout_add (UPDATE_DELAY_MSEC,
+                                                ide_webkit_page_do_update_cb,
+                                                self);
+}
+
+IdeWebkitPage *
+ide_webkit_page_new_for_buffer (GtkTextBuffer *buffer)
+{
+  IdeWebkitPage *self;
+  IdeWebkitPagePrivate *priv;
+
+  g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), NULL);
+
+  self = ide_webkit_page_new ();
+  priv = ide_webkit_page_get_instance_private (self);
+
+  priv->buffer = g_object_ref (buffer);
+  g_signal_connect_object (buffer,
+                           "changed",
+                           G_CALLBACK (ide_webkit_page_buffer_changed_cb),
+                           self,
+                           G_CONNECT_SWAPPED);
+  ide_webkit_page_buffer_changed_cb (self, buffer);
+
+  return self;
+}
diff --git a/src/libide/webkit/ide-webkit-page.h b/src/libide/webkit/ide-webkit-page.h
index 0608b4ae3..5b704e46a 100644
--- a/src/libide/webkit/ide-webkit-page.h
+++ b/src/libide/webkit/ide-webkit-page.h
@@ -37,6 +37,8 @@ struct _IdeWebkitPageClass
 IDE_AVAILABLE_IN_ALL
 IdeWebkitPage *ide_webkit_page_new                   (void);
 IDE_AVAILABLE_IN_ALL
+IdeWebkitPage *ide_webkit_page_new_for_buffer        (GtkTextBuffer *buffer);
+IDE_AVAILABLE_IN_ALL
 void           ide_webkit_page_load_uri              (IdeWebkitPage *self,
                                                       const char    *uri);
 IDE_AVAILABLE_IN_ALL


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