[gtk/wip/otte/for-main] inspector: Add dnd inspection support




commit 6da952100c830df0a97d2b76fc8c9f4430ac9cad
Author: Benjamin Otte <otte redhat com>
Date:   Mon Dec 27 05:57:05 2021 +0100

    inspector: Add dnd inspection support
    
    This has lots of issues:
     * It randomly crashes when data is loading while the dnd goes away.
     * The data gets randomly reset at the wrong time
     * Can't scroll the window on Wayland
     * ...
    
    But it's better than nothing, so better get it committed.

 gtk/inspector/clipboard.c  | 169 +++++++++++++++++++++++++++++++++++----------
 gtk/inspector/clipboard.ui |  44 ++++++++++++
 2 files changed, 175 insertions(+), 38 deletions(-)
---
diff --git a/gtk/inspector/clipboard.c b/gtk/inspector/clipboard.c
index b27eec2187..155862474f 100644
--- a/gtk/inspector/clipboard.c
+++ b/gtk/inspector/clipboard.c
@@ -25,6 +25,7 @@
 #include "gtkbinlayout.h"
 #include "gtkbox.h"
 #include "gtkdebug.h"
+#include "gtkdropcontrollermotion.h"
 #include "gtklabel.h"
 #include "gtklistbox.h"
 #include "gtktogglebutton.h"
@@ -37,6 +38,9 @@ struct _GtkInspectorClipboard
 
   GtkWidget *swin;
 
+  GtkWidget *dnd_formats;
+  GtkWidget *dnd_info;
+
   GtkWidget *clipboard_formats;
   GtkWidget *clipboard_info;
 
@@ -56,12 +60,17 @@ load_gtype_value (GObject      *source,
                   GAsyncResult *res,
                   gpointer      data)
 {
-  GdkClipboard *clipboard = GDK_CLIPBOARD (source);
   GtkDataViewer *viewer = data;
   const GValue *value;
   GError *error = NULL;
 
-  value = gdk_clipboard_read_value_finish (clipboard, res, &error);
+  if (GDK_IS_CLIPBOARD (source))
+    value = gdk_clipboard_read_value_finish (GDK_CLIPBOARD (source), res, &error);
+  else if (GDK_IS_DROP (source))
+    value = gdk_drop_read_value_finish (GDK_DROP (source), res, &error);
+  else
+    g_assert_not_reached ();
+
   if (value == NULL)
     gtk_data_viewer_load_error (viewer, error);
   else
@@ -75,14 +84,30 @@ load_gtype (GtkDataViewer *viewer,
             GCancellable  *cancellable,
             gpointer       gtype)
 {
-  GdkClipboard *clipboard = g_object_get_data (G_OBJECT (viewer), "clipboard");
+  GObject *data_source = g_object_get_data (G_OBJECT (viewer), "data-source");
 
-  gdk_clipboard_read_value_async (clipboard,
-                                  GPOINTER_TO_SIZE (gtype),
-                                  G_PRIORITY_DEFAULT,
-                                  cancellable,
-                                  load_gtype_value,
-                                  g_object_ref (viewer));
+  if (GDK_IS_CLIPBOARD (data_source))
+    {
+      gdk_clipboard_read_value_async (GDK_CLIPBOARD (data_source),
+                                      GPOINTER_TO_SIZE (gtype),
+                                      G_PRIORITY_DEFAULT,
+                                      cancellable,
+                                      load_gtype_value,
+                                      g_object_ref (viewer));
+    }
+  else if (GDK_IS_DROP (data_source))
+    {
+      gdk_drop_read_value_async (GDK_DROP (data_source),
+                                 GPOINTER_TO_SIZE (gtype),
+                                 G_PRIORITY_DEFAULT,
+                                 cancellable,
+                                 load_gtype_value,
+                                 g_object_ref (viewer));
+    }
+  else
+    {
+      g_assert_not_reached ();
+    }
 
   return TRUE;
 }
@@ -92,13 +117,18 @@ load_mime_type_stream (GObject      *source,
                        GAsyncResult *res,
                        gpointer      data)
 {
-  GdkClipboard *clipboard = GDK_CLIPBOARD (source);
   GtkDataViewer *viewer = data;
   GInputStream *stream;
   GError *error = NULL;
   const char *mime_type;
 
-  stream = gdk_clipboard_read_finish (clipboard, res, &mime_type, &error);
+  if (GDK_IS_CLIPBOARD (source))
+    stream = gdk_clipboard_read_finish (GDK_CLIPBOARD (source), res, &mime_type, &error);
+  else if (GDK_IS_DROP (source))
+    stream = gdk_drop_read_finish (GDK_DROP (source), res, &mime_type, &error);
+  else
+    g_assert_not_reached ();
+
   if (stream == NULL)
     gtk_data_viewer_load_error (viewer, error);
   else
@@ -112,23 +142,48 @@ load_mime_type (GtkDataViewer *viewer,
                 GCancellable  *cancellable,
                 gpointer       mime_type)
 {
-  GdkClipboard *clipboard = g_object_get_data (G_OBJECT (viewer), "clipboard");
+  GObject *data_source = g_object_get_data (G_OBJECT (viewer), "data-source");
 
-  gdk_clipboard_read_async (clipboard,
-                            (const char *[2]) { mime_type, NULL },
-                            G_PRIORITY_DEFAULT,
-                            cancellable,
-                            load_mime_type_stream,
-                            g_object_ref (viewer));
+  if (GDK_IS_CLIPBOARD (data_source))
+    {
+      gdk_clipboard_read_async (GDK_CLIPBOARD (data_source),
+                                (const char *[2]) { mime_type, NULL },
+                                G_PRIORITY_DEFAULT,
+                                cancellable,
+                                load_mime_type_stream,
+                                g_object_ref (viewer));
+    }
+  else if (GDK_IS_DROP (data_source))
+    {
+      gdk_drop_read_async (GDK_DROP (data_source),
+                           (const char *[2]) { mime_type, NULL },
+                           G_PRIORITY_DEFAULT,
+                           cancellable,
+                           load_mime_type_stream,
+                           g_object_ref (viewer));
+    }
+  else
+    {
+      g_assert_not_reached ();
+    }
 
   return TRUE;
 }
 
+static void
+on_drop_row_enter (GtkDropControllerMotion *motion,
+                   double                   x,
+                   double                   y,
+                   GtkWidget               *viewer)
+{
+  gtk_widget_set_visible (viewer, TRUE);
+}
+
 static void
 add_content_type_row (GtkInspectorClipboard *self,
                       GtkListBox            *list,
                       const char            *type_name,
-                      GdkClipboard          *clipboard,
+                      GObject               *data_source,
                       GCallback              load_func,
                       gpointer               load_func_data)
 {
@@ -146,19 +201,39 @@ add_content_type_row (GtkInspectorClipboard *self,
   gtk_widget_set_hexpand (label, TRUE);
   gtk_box_append (GTK_BOX (hbox), label);
 
-  button = gtk_toggle_button_new_with_label (_("Show"));
-  gtk_widget_set_halign (button, GTK_ALIGN_END);
-  gtk_widget_set_valign (button, GTK_ALIGN_BASELINE);
-  gtk_box_append (GTK_BOX (hbox), button);
-
   viewer = gtk_data_viewer_new ();
   g_signal_connect (viewer, "load", load_func, load_func_data);
-  g_object_set_data (G_OBJECT (viewer), "clipboard", clipboard);
-  g_object_bind_property (G_OBJECT (button), "active",
-                          G_OBJECT (viewer), "visible",
-                          G_BINDING_SYNC_CREATE);
+  g_object_set_data (G_OBJECT (viewer), "data-source", data_source);
   gtk_box_append (GTK_BOX (vbox), viewer);
 
+  if (GDK_IS_CLIPBOARD (data_source))
+    {
+      button = gtk_toggle_button_new_with_label (_("Show"));
+      gtk_widget_set_halign (button, GTK_ALIGN_END);
+      gtk_widget_set_valign (button, GTK_ALIGN_BASELINE);
+      gtk_box_append (GTK_BOX (hbox), button);
+
+      g_object_bind_property (G_OBJECT (button), "active",
+                              G_OBJECT (viewer), "visible",
+                              G_BINDING_SYNC_CREATE);
+    }
+  else
+    {
+      GtkEventController *controller = gtk_drop_controller_motion_new ();
+      g_signal_connect (controller, "enter", G_CALLBACK (on_drop_row_enter), viewer);
+      gtk_widget_add_controller (vbox, controller); 
+
+      gtk_widget_set_visible (viewer, FALSE);
+
+      label = gtk_label_new (_("Hover to load"));
+      g_object_bind_property (G_OBJECT (viewer), "visible",
+                              G_OBJECT (label), "visible",
+                              G_BINDING_SYNC_CREATE | G_BINDING_INVERT_BOOLEAN);
+      gtk_widget_set_halign (label, GTK_ALIGN_END);
+      gtk_widget_set_valign (label, GTK_ALIGN_BASELINE);
+      gtk_box_append (GTK_BOX (hbox), label);
+    }
+
   row = gtk_list_box_row_new ();
   gtk_list_box_row_set_child (GTK_LIST_BOX_ROW (row), vbox);
   gtk_list_box_row_set_activatable (GTK_LIST_BOX_ROW (row), FALSE);
@@ -169,10 +244,10 @@ add_content_type_row (GtkInspectorClipboard *self,
 static void
 init_formats (GtkInspectorClipboard *self,
               GtkListBox            *list,
-              GdkClipboard          *clipboard)
+              GdkContentFormats     *formats,
+              GObject               *data_source)
 {
   GtkListBoxRow *row;
-  GdkContentFormats *formats;
   const char * const *mime_types;
   const GType *gtypes;
   gsize i, n;
@@ -180,15 +255,13 @@ init_formats (GtkInspectorClipboard *self,
   while ((row = gtk_list_box_get_row_at_index (list, 1)))
     gtk_list_box_remove (list, GTK_WIDGET (row));
 
-  formats = gdk_clipboard_get_formats (clipboard);
-
   gtypes = gdk_content_formats_get_gtypes (formats, &n);
   for (i = 0; i < n; i++)
-    add_content_type_row (self, list, g_type_name (gtypes[i]), clipboard, G_CALLBACK (load_gtype), 
GSIZE_TO_POINTER (gtypes[i]));
+    add_content_type_row (self, list, g_type_name (gtypes[i]), data_source, G_CALLBACK (load_gtype), 
GSIZE_TO_POINTER (gtypes[i]));
 
   mime_types = gdk_content_formats_get_mime_types (formats, &n);
   for (i = 0; i < n; i++)
-    add_content_type_row (self, list, mime_types[i], clipboard, G_CALLBACK (load_mime_type), (gpointer) 
mime_types[i]);
+    add_content_type_row (self, list, mime_types[i], data_source, G_CALLBACK (load_mime_type), (gpointer) 
mime_types[i]);
 }
 
 static void
@@ -219,7 +292,7 @@ clipboard_notify (GdkClipboard          *clipboard,
 {
   if (g_str_equal (pspec->name, "formats"))
     {
-      init_formats (self, GTK_LIST_BOX (self->clipboard_formats), clipboard);
+      init_formats (self, GTK_LIST_BOX (self->clipboard_formats), gdk_clipboard_get_formats (clipboard), 
G_OBJECT (clipboard));
     }
 
   init_info (self, GTK_LABEL (self->clipboard_info), clipboard);
@@ -232,12 +305,28 @@ primary_notify (GdkClipboard          *clipboard,
 {
   if (g_str_equal (pspec->name, "formats"))
     {
-      init_formats (self, GTK_LIST_BOX (self->primary_formats), clipboard);
+      init_formats (self, GTK_LIST_BOX (self->primary_formats), gdk_clipboard_get_formats (clipboard), 
G_OBJECT (clipboard));
     }
 
   init_info (self, GTK_LABEL (self->primary_info), clipboard);
 }
 
+static void
+on_drop_enter (GtkDropControllerMotion *motion,
+               double                   x,
+               double                   y,
+               GtkInspectorClipboard   *self)
+{
+  GdkDrop *drop = gtk_drop_controller_motion_get_drop (motion);
+
+  init_formats (self, GTK_LIST_BOX (self->dnd_formats), gdk_drop_get_formats (drop), G_OBJECT (drop));
+
+  if (gdk_drop_get_drag (drop))
+    gtk_label_set_text (GTK_LABEL (self->dnd_info), C_("clipboard", "local"));
+  else
+    gtk_label_set_text (GTK_LABEL (self->dnd_info), C_("clipboard", "remote"));
+}
+
 static void
 gtk_inspector_clipboard_unset_display (GtkInspectorClipboard *self)
 {
@@ -281,11 +370,15 @@ gtk_inspector_clipboard_class_init (GtkInspectorClipboardClass *klass)
 
   gtk_widget_class_set_template_from_resource (widget_class, "/org/gtk/libgtk/inspector/clipboard.ui");
   gtk_widget_class_bind_template_child (widget_class, GtkInspectorClipboard, swin);
+  gtk_widget_class_bind_template_child (widget_class, GtkInspectorClipboard, dnd_formats);
+  gtk_widget_class_bind_template_child (widget_class, GtkInspectorClipboard, dnd_info);
   gtk_widget_class_bind_template_child (widget_class, GtkInspectorClipboard, clipboard_formats);
   gtk_widget_class_bind_template_child (widget_class, GtkInspectorClipboard, clipboard_info);
   gtk_widget_class_bind_template_child (widget_class, GtkInspectorClipboard, primary_formats);
   gtk_widget_class_bind_template_child (widget_class, GtkInspectorClipboard, primary_info);
 
+  gtk_widget_class_bind_template_callback (widget_class, on_drop_enter);
+
   gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
 }
 
@@ -304,12 +397,12 @@ gtk_inspector_clipboard_set_display (GtkInspectorClipboard *self,
 
   clipboard = gdk_display_get_clipboard (display);
   g_signal_connect (clipboard, "notify", G_CALLBACK (clipboard_notify), self);
-  init_formats (self, GTK_LIST_BOX (self->clipboard_formats), clipboard);
+  init_formats (self, GTK_LIST_BOX (self->clipboard_formats), gdk_clipboard_get_formats (clipboard), 
G_OBJECT (clipboard));
   init_info (self, GTK_LABEL (self->clipboard_info), clipboard);
 
   clipboard = gdk_display_get_primary_clipboard (display);
   g_signal_connect (clipboard, "notify", G_CALLBACK (primary_notify), self);
-  init_formats (self, GTK_LIST_BOX (self->primary_formats), clipboard);
+  init_formats (self, GTK_LIST_BOX (self->primary_formats), gdk_clipboard_get_formats (clipboard), G_OBJECT 
(clipboard));
   init_info (self, GTK_LABEL (self->primary_info), clipboard);
 }
 
diff --git a/gtk/inspector/clipboard.ui b/gtk/inspector/clipboard.ui
index ef83f037e9..bc9647f0bf 100644
--- a/gtk/inspector/clipboard.ui
+++ b/gtk/inspector/clipboard.ui
@@ -12,6 +12,50 @@
             <property name="margin-top">60</property>
             <property name="margin-bottom">60</property>
             <property name="spacing">10</property>
+            <child>
+              <object class="GtkFrame">
+                <child>
+                  <object class="GtkListBox" id="dnd_formats">
+                    <property name="selection-mode">none</property>
+                    <style>
+                      <class name="rich-list"/>
+                    </style>
+                    <child>
+                      <object class="GtkListBoxRow">
+                        <property name="activatable">0</property>
+                        <child>
+                          <object class="GtkBox">
+                            <property name="spacing">40</property>
+                            <child>
+                              <object class="GtkLabel">
+                                <property name="label" translatable="yes">Drag and hold here</property>
+                                <property name="halign">start</property>
+                                <property name="valign">baseline</property>
+                                <property name="xalign">0.0</property>
+                              </object>
+                            </child>
+                            <child>
+                              <object class="GtkLabel" id="dnd_info">
+                                <property name="selectable">1</property>
+                                <property name="halign">end</property>
+                                <property name="valign">baseline</property>
+                                <property name="ellipsize">end</property>
+                                <property name="hexpand">1</property>
+                              </object>
+                            </child>
+                          </object>
+                        </child>
+                        <child>
+                          <object class="GtkDropControllerMotion">
+                            <signal name="enter" handler="on_drop_enter" swapped="no"/>
+                          </object>
+                        </child>
+                      </object>
+                    </child>
+                  </object>
+                </child>
+              </object>
+            </child>
             <child>
               <object class="GtkFrame">
                 <child>


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