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 @@ 60 60 10 + + + + + none + + + + 0 + + + 40 + + + Drag and hold here + start + baseline + 0.0 + + + + + 1 + end + baseline + end + 1 + + + + + + + + + + + + + + +