[gtk/wip/otte/for-main] inspector: Add dnd inspection support
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/otte/for-main] inspector: Add dnd inspection support
- Date: Mon, 27 Dec 2021 04:59:47 +0000 (UTC)
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]