From 8d96b12cc7e0396366f628fcb716b2b1b2377a0f Mon Sep 17 00:00:00 2001 From: Ivan Molodetskikh Date: Wed, 15 Mar 2023 16:09:51 -0700 Subject: [PATCH] testdndresize: Add non-resizing redrawing GL surface The GL Wayland drag surface code path has a bug where it does not reset the hotspot, so if a GL-backed draw surface redraws without resizing or resetting the hotspot, it moves away. The next commit will fix that, but this commit adds a test for that. --- tests/testdndresize.c | 103 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 101 insertions(+), 2 deletions(-) diff --git a/tests/testdndresize.c b/tests/testdndresize.c index 39bcbcdc5b..5c78bf5606 100644 --- a/tests/testdndresize.c +++ b/tests/testdndresize.c @@ -5,6 +5,58 @@ static GtkRequisition size; static gint64 start_time; static gboolean stop_update_size; +// Animated paintable for testing content-invalidating drag surfaces. +#define GTK_TYPE_ANIMATED_ICON (gtk_animated_icon_get_type ()) +G_DECLARE_FINAL_TYPE (GtkAnimatedIcon, gtk_animated_icon, GTK, ANIMATED_ICON, GObject) + +struct _GtkAnimatedIcon +{ + GObject parent_instance; +}; + +struct _GtkAnimatedIconClass +{ + GObjectClass parent_class; +}; + +static void +gtk_animated_icon_snapshot (GdkPaintable *paintable, + GdkSnapshot *snapshot, + double width, + double height) +{ + gint64 now = g_get_monotonic_time (); + float t; + + t = fmodf ((now - start_time) / (float) G_TIME_SPAN_SECOND, 1); + if (t >= 0.5) + t = 1 - t; + + gtk_snapshot_append_color (snapshot, + &(GdkRGBA) { 0, t + 0.5, 0, 1 }, + &GRAPHENE_RECT_INIT (0, 0, width, height)); +} + +static void +gtk_animated_icon_paintable_init (GdkPaintableInterface *iface) +{ + iface->snapshot = gtk_animated_icon_snapshot; +} + +G_DEFINE_TYPE_WITH_CODE (GtkAnimatedIcon, gtk_animated_icon, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (GDK_TYPE_PAINTABLE, + gtk_animated_icon_paintable_init)) + +static void +gtk_animated_icon_class_init (GtkAnimatedIconClass *klass) +{ +} + +static void +gtk_animated_icon_init (GtkAnimatedIcon *nuclear) +{ +} + static gboolean update_size (GtkWidget *widget, GdkFrameClock *clock, gpointer data) { @@ -60,6 +112,30 @@ drag_end (GtkDragSource *source, stop_update_size = TRUE; } +static gboolean +invalidate_contents (GtkWidget *widget, GdkFrameClock *clock, gpointer data) +{ + GdkPaintable *paintable = data; + gdk_paintable_invalidate_contents (paintable); + return G_SOURCE_CONTINUE; +} + +static void +drag_begin_non_resizing (GtkDragSource *source, + GdkDrag *drag) +{ + GdkPaintable *paintable; + GtkWidget *widget; + int width = 64, height = 32; + + paintable = GDK_PAINTABLE (g_object_new (GTK_TYPE_ANIMATED_ICON, NULL)); + gtk_drag_icon_set_from_paintable (drag, paintable, width / 2, height / 2); + + widget = gtk_drag_icon_get_child (GTK_DRAG_ICON (gtk_drag_icon_get_for_drag (drag))); + gtk_widget_set_size_request (widget, width, height); + gtk_widget_add_tick_callback (widget, invalidate_contents, paintable, NULL); +} + static void quit_cb (GtkWidget *widget, gpointer data) @@ -76,6 +152,7 @@ main (int argc, char *argv[]) { GtkCssProvider *provider; GtkWidget *window; + GtkWidget *box; GtkWidget *label; GtkDragSource *source; GdkContentProvider *content; @@ -97,7 +174,10 @@ main (int argc, char *argv[]) window = gtk_window_new (); g_signal_connect (window, "destroy", G_CALLBACK (quit_cb), &done); - label = gtk_label_new ("Drag Me"); + box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); + + // The resizing icon label. + label = gtk_label_new ("Drag Me (Resizing)"); g_object_set (label, "margin-start", 64, "margin-end", 64, @@ -112,7 +192,26 @@ main (int argc, char *argv[]) g_signal_connect (source, "drag-end", G_CALLBACK (drag_end), NULL); gtk_widget_add_controller (label, GTK_EVENT_CONTROLLER (source)); - gtk_window_set_child (GTK_WINDOW (window), label); + gtk_box_append (GTK_BOX (box), label); + + // The non-resizing icon label. + label = gtk_label_new ("Drag Me (Non-Resizing)"); + g_object_set (label, + "margin-start", 64, + "margin-end", 64, + "margin-top", 64, + "margin-bottom", 64, + NULL); + + source = gtk_drag_source_new (); + content = gdk_content_provider_new_typed (G_TYPE_STRING, "I'm data!"); + gtk_drag_source_set_content (source, content); + g_signal_connect (source, "drag-begin", G_CALLBACK (drag_begin_non_resizing), NULL); + gtk_widget_add_controller (label, GTK_EVENT_CONTROLLER (source)); + + gtk_box_append (GTK_BOX (box), label); + + gtk_window_set_child (GTK_WINDOW (window), box); gtk_window_present (GTK_WINDOW (window)); -- 2.30.2