[gtk/wip/otte/dnd: 3/9] dragicon: Change how to acquire drag icons



commit 03882e1f960a738f1289db3747223dfc7cc2db1e
Author: Benjamin Otte <otte redhat com>
Date:   Mon Mar 2 02:55:38 2020 +0100

    dragicon: Change how to acquire drag icons
    
    Before, gtk_drag_icon_new_for_drag() allowed creating new drag icons.
    This could cause multiple drag icons to exist for a single drag.
    
    Now, gtk_drag_icon_get_for_drag() makes sure that only one drag icon is
    created.

 docs/reference/gtk/gtk4-sections.txt |  2 +-
 gtk/gtkdragicon.c                    | 66 +++++++++++++++++-------------------
 gtk/gtkdragicon.h                    |  2 +-
 gtk/gtkdragiconprivate.h             | 42 -----------------------
 gtk/gtkdragsource.c                  |  2 +-
 5 files changed, 35 insertions(+), 79 deletions(-)
---
diff --git a/docs/reference/gtk/gtk4-sections.txt b/docs/reference/gtk/gtk4-sections.txt
index 769926af47..419b28193c 100644
--- a/docs/reference/gtk/gtk4-sections.txt
+++ b/docs/reference/gtk/gtk4-sections.txt
@@ -6880,7 +6880,7 @@ gtk_drop_controller_motion_get_type
 <SECTION>
 <FILE>gtkdragicon</FILE>
 GtkDragIcon
-gtk_drag_icon_new_for_drag
+gtk_drag_icon_get_for_drag
 gtk_drag_icon_set_child
 gtk_drag_icon_get_child
 gtk_drag_icon_set_from_paintable
diff --git a/gtk/gtkdragicon.c b/gtk/gtkdragicon.c
index c217ab6b92..4e1afa522a 100644
--- a/gtk/gtkdragicon.c
+++ b/gtk/gtkdragicon.c
@@ -17,7 +17,7 @@
 
 #include "config.h"
 
-#include "gtkdragiconprivate.h"
+#include "gtkdragicon.h"
 
 #include "gtkprivate.h"
 #include "gtkintl.h"
@@ -35,15 +35,17 @@
  * @Short_description: A toplevel to use as drag icon
  * @Title: GtkDragIcon
  *
- * GtkDragIcon is a #GtkNative implementation with the sole purpose
+ * GtkDragIcon is a #GtkRoot implementation with the sole purpose
  * to serve as a drag icon during DND operations. A drag icon moves
  * with the pointer during a drag operation and is destroyed when
  * the drag ends.
  *
  * To set up a drag icon and associate it with an ongoing drag operation,
- * use gtk_drag_icon_set_from_paintable(). It is also possible to create
- * a GtkDragIcon with gtk_drag_icon_new_for_drag(() and populate it
- * with widgets yourself.
+ * use gtk_drag_icon_get_for_drag() to get the icon for a drag. You can
+ * then use it like any other widget and use gtk_drag_icon_set_child() to
+ * set whatever widget should be used for the drag icon.
+ *
+ * Keep in mind that drag icons do not allow user input.
  */
 struct _GtkDragIcon
 {
@@ -385,32 +387,41 @@ gtk_drag_icon_init (GtkDragIcon *self)
 {
 }
 
-GtkWidget *
-gtk_drag_icon_new (void)
-{
-  return g_object_new (GTK_TYPE_DRAG_ICON, NULL);
-}
-
 /**
- * gtk_drag_icon_new_for_drag:
- * @drag: a #GtkDrag
+ * gtk_drag_icon_get_for_drag:
+ * @drag: a #GdkDrag
+ *
+ * Gets the #GtkDragIcon in use with @drag.
  *
- * Creates a #GtkDragIcon and associates it with the drag operation.
+ * If no drag icon exists yet, a new one will be created
+ * and shown.
  *
- * Returns: the new #GtkDragIcon
+ * Returns: (transfer none) the #GtkDragIcon
  */
 GtkWidget *
-gtk_drag_icon_new_for_drag (GdkDrag *drag)
+gtk_drag_icon_get_for_drag (GdkDrag *drag)
 {
-  GtkWidget *icon;
+  static GQuark drag_icon_quark = 0;
+  GtkWidget *self;
 
   g_return_val_if_fail (GDK_IS_DRAG (drag), NULL);
 
-  icon = g_object_new (GTK_TYPE_DRAG_ICON, NULL);
+  if (G_UNLIKELY (drag_icon_quark == 0))
+    drag_icon_quark = g_quark_from_static_string ("-gtk-drag-icon");
+
+  self = g_object_get_qdata (G_OBJECT (drag), drag_icon_quark);
+  if (self == NULL)
+    {
+      self = g_object_new (GTK_TYPE_DRAG_ICON, NULL);
+
+      GTK_DRAG_ICON (self)->surface = g_object_ref (gdk_drag_get_drag_surface (drag));
 
-  gtk_drag_icon_set_surface (GTK_DRAG_ICON (icon), gdk_drag_get_drag_surface (drag));
+      g_object_set_qdata_full (G_OBJECT (drag), drag_icon_quark, g_object_ref_sink (self), g_object_unref);
 
-  return icon;
+      gtk_widget_show (self);
+    }
+
+  return self;
 }
 
 /**
@@ -435,24 +446,11 @@ gtk_drag_icon_set_from_paintable (GdkDrag      *drag,
 
   gdk_drag_set_hotspot (drag, hot_x, hot_y);
 
-  icon = gtk_drag_icon_new_for_drag (drag);
+  icon = gtk_drag_icon_get_for_drag (drag);
 
   picture = gtk_picture_new_for_paintable (paintable);
   gtk_picture_set_can_shrink (GTK_PICTURE (picture), FALSE);
   gtk_drag_icon_set_child (GTK_DRAG_ICON (icon), picture);
-
-  g_object_set_data_full (G_OBJECT (drag),
-                          "icon",
-                          g_object_ref_sink (icon),
-                          (GDestroyNotify)gtk_widget_destroy);
-  gtk_widget_show (icon);
-}
-
-void
-gtk_drag_icon_set_surface (GtkDragIcon *icon,
-                           GdkSurface  *surface)
-{
-  g_set_object (&icon->surface, surface);
 }
 
 /**
diff --git a/gtk/gtkdragicon.h b/gtk/gtkdragicon.h
index 873e564942..b8c70d6f86 100644
--- a/gtk/gtkdragicon.h
+++ b/gtk/gtkdragicon.h
@@ -38,7 +38,7 @@ GDK_AVAILABLE_IN_ALL
 G_DECLARE_FINAL_TYPE (GtkDragIcon, gtk_drag_icon, GTK, DRAG_ICON, GtkContainer)
 
 GDK_AVAILABLE_IN_ALL
-GtkWidget *     gtk_drag_icon_new_for_drag (GdkDrag *drag);
+GtkWidget *     gtk_drag_icon_get_for_drag                      (GdkDrag                *drag);
 
 GDK_AVAILABLE_IN_ALL
 void            gtk_drag_icon_set_child                         (GtkDragIcon            *self,
diff --git a/gtk/gtkdragsource.c b/gtk/gtkdragsource.c
index 155c7cc84a..6b6c4d38de 100644
--- a/gtk/gtkdragsource.c
+++ b/gtk/gtkdragsource.c
@@ -34,7 +34,7 @@
 #include "gtkintl.h"
 #include "gtkstylecontext.h"
 #include "gtkimageprivate.h"
-#include "gtkdragiconprivate.h"
+#include "gtkdragicon.h"
 #include "gtkprivate.h"
 #include "gtkmarshalers.h"
 #include "gtkicontheme.h"


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