[gtk+] GtkWidget: Improve drag-leave and drag-data-received docs.
- From: Murray Cumming <murrayc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] GtkWidget: Improve drag-leave and drag-data-received docs.
- Date: Mon, 16 Sep 2013 12:11:57 +0000 (UTC)
commit 98ca9a865fd22ad817fd735642f66867106682a4
Author: Murray Cumming <murrayc murrayc com>
Date: Mon Sep 16 14:04:24 2013 +0200
GtkWidget: Improve drag-leave and drag-data-received docs.
* gtk/gtkwidget.c: drag-leave signal: Document that it is called before
drag-drop.
drag-data-received signal: Document that it is up to the application
to know why the data was requested (e.g. drag motion or drop).
* demos/gtk-demo/toolpalette.c: interactive_canvas_drag_drop():
Do not transform the drop_item created in the drag-motion handler.
Instead caused drag-data-received to be called, remembering why,
and create a new item there.
interactive_canvas_drag_leave(): Remove the idle-handler hack,
now that we do not need to keep the drag-motion drop_item alive until
the drop.
I noticed that this patch was sitting in bug #605611 from 2009
though it had been approved. I do not remember much about why I
created it.
demos/gtk-demo/toolpalette.c | 71 +++++++++++++++++++++--------------------
gtk/gtkwidget.c | 10 +++++-
2 files changed, 45 insertions(+), 36 deletions(-)
---
diff --git a/demos/gtk-demo/toolpalette.c b/demos/gtk-demo/toolpalette.c
index 812013c..dd011ed 100644
--- a/demos/gtk-demo/toolpalette.c
+++ b/demos/gtk-demo/toolpalette.c
@@ -21,6 +21,7 @@ struct _CanvasItem
gdouble x, y;
};
+static gboolean drag_data_requested_for_drop = FALSE;
static CanvasItem *drop_item = NULL;
static GList *canvas_items = NULL;
@@ -273,6 +274,7 @@ interactive_canvas_drag_motion (GtkWidget *widget,
if (!target)
return FALSE;
+ drag_data_requested_for_drop = FALSE;
gtk_drag_get_data (widget, context, target, time);
}
@@ -302,16 +304,36 @@ interactive_canvas_drag_data_received (GtkWidget *widget,
tool_item = gtk_tool_palette_get_drag_item (GTK_TOOL_PALETTE (palette),
selection);
- /* create a drop indicator when a tool button was found */
+ /* create a canvas item when a tool button was found */
g_assert (NULL == drop_item);
- if (GTK_IS_TOOL_ITEM (tool_item))
+ if (!GTK_IS_TOOL_ITEM (tool_item))
+ return;
+
+ if (drop_item)
+ {
+ canvas_item_free (drop_item);
+ drop_item = NULL;
+ }
+
+ CanvasItem *item = canvas_item_new (widget, GTK_TOOL_BUTTON (tool_item), x, y);
+
+ /* Either create a new item or just create a preview item,
+ depending on why the drag data was requested. */
+ if(drag_data_requested_for_drop)
+ {
+ canvas_items = g_list_append (canvas_items, item);
+ drop_item = NULL;
+
+ gtk_drag_finish (context, TRUE, FALSE, time);
+ } else
{
- drop_item = canvas_item_new (widget, GTK_TOOL_BUTTON (tool_item), x, y);
+ drop_item = item;
gdk_drag_status (context, GDK_ACTION_COPY, time);
- gtk_widget_queue_draw (widget);
}
+
+ gtk_widget_queue_draw (widget);
}
static gboolean
@@ -322,29 +344,19 @@ interactive_canvas_drag_drop (GtkWidget *widget,
guint time,
gpointer data)
{
- if (drop_item)
- {
- /* turn the drop indicator into a real canvas item */
+ GdkAtom target = gtk_drag_dest_find_target (widget, context, NULL);
- drop_item->x = x;
- drop_item->y = y;
-
- canvas_items = g_list_append (canvas_items, drop_item);
- drop_item = NULL;
-
- /* signal the item was accepted and redraw */
+ if (!target)
+ return FALSE;
- gtk_drag_finish (context, TRUE, FALSE, time);
- gtk_widget_queue_draw (widget);
-
- return TRUE;
- }
+ drag_data_requested_for_drop = TRUE;
+ gtk_drag_get_data (widget, context, target, time);
return FALSE;
}
-static gboolean
-interactive_canvas_real_drag_leave (gpointer data)
+static void
+interactive_canvas_drag_leave (gpointer data)
{
if (drop_item)
{
@@ -353,20 +365,9 @@ interactive_canvas_real_drag_leave (gpointer data)
canvas_item_free (drop_item);
drop_item = NULL;
- gtk_widget_queue_draw (widget);
+ if (widget)
+ gtk_widget_queue_draw (widget);
}
-
- return G_SOURCE_REMOVE;
-}
-
-static void
-interactive_canvas_drag_leave (GtkWidget *widget,
- GdkDragContext *context,
- guint time,
- gpointer data)
-{
- /* defer cleanup until a potential "drag-drop" signal was received */
- g_idle_add (interactive_canvas_real_drag_leave, widget);
}
static void
@@ -598,7 +599,7 @@ do_toolpalette (GtkWidget *do_widget)
"signal::draw", canvas_draw, NULL,
"signal::drag-motion", interactive_canvas_drag_motion, NULL,
"signal::drag-data-received", interactive_canvas_drag_data_received, NULL,
- "signal::drag-leave", interactive_canvas_drag_leave, NULL,
+ "signal::drag-leave", interactive_canvas_drag_leave, contents,
"signal::drag-drop", interactive_canvas_drag_drop, NULL,
NULL);
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index a2e5e3c..6ee8409 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -2774,7 +2774,12 @@ G_GNUC_END_IGNORE_DEPRECATIONS
* The ::drag-leave signal is emitted on the drop site when the cursor
* leaves the widget. A typical reason to connect to this signal is to
* undo things done in #GtkWidget::drag-motion, e.g. undo highlighting
- * with gtk_drag_unhighlight()
+ * with gtk_drag_unhighlight().
+ *
+ *
+ * Likewise, the #GtkWidget::drag-leave signal is also emitted before the
+ * ::drag-drop signal, for instance to allow cleaning up of a preview item
+ * created in the #GtkWidget::drag-motion signal handler.
*/
widget_signals[DRAG_LEAVE] =
g_signal_new (I_("drag-leave"),
@@ -3066,6 +3071,9 @@ G_GNUC_END_IGNORE_DEPRECATIONS
* gtk_drag_finish(), setting the @success parameter depending on
* whether the data was processed successfully.
*
+ * Applications must create some means to determine why the signal was emitted
+ * and therefore whether to call gdk_drag_status() or gtk_drag_finish().
+ *
* The handler may inspect the selected action with
* gdk_drag_context_get_selected_action() before calling
* gtk_drag_finish(), e.g. to implement %GDK_ACTION_ASK as
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]