dragdest: Steps towards allowing nested drop sites

This commit is contained in:
Matthias Clasen 2020-01-08 00:25:51 -05:00
parent 0297039b38
commit d5f4579384

View File

@ -514,15 +514,9 @@ gtk_drop_target_drag_motion (GtkDropTarget *dest,
target = gtk_drop_target_match (dest, drop);
if (actions && target)
{
gdk_drop_status (drop, dest_actions);
gtk_drop_target_set_contains (dest, TRUE);
}
gdk_drop_status (drop, dest_actions);
else
{
gdk_drop_status (drop, 0);
gtk_drop_target_set_contains (dest, FALSE);
}
gdk_drop_status (drop, 0);
return TRUE;
}
@ -550,7 +544,6 @@ gtk_drop_target_emit_drag_leave (GtkDropTarget *dest,
set_drop (dest, drop);
g_signal_emit (dest, signals[DRAG_LEAVE], 0, drop, time);
set_drop (dest, NULL);
gtk_drop_target_set_contains (dest, FALSE);
}
static gboolean
@ -561,14 +554,9 @@ gtk_drop_target_emit_drag_motion (GtkDropTarget *dest,
{
gboolean result = FALSE;
dest->contains_pending = TRUE;
set_drop (dest, drop);
g_signal_emit (dest, signals[DRAG_MOTION], 0, drop, x, y, &result);
if (dest->contains_pending)
gtk_drop_target_set_contains (dest, result);
return result;
}
@ -590,22 +578,11 @@ static void
gtk_drop_target_set_contains (GtkDropTarget *dest,
gboolean contains)
{
GtkWidget *widget;
widget = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (dest));
dest->contains_pending = FALSE;
if (dest->contains == contains)
return;
dest->contains = contains;
if (contains)
gtk_widget_set_state_flags (widget, GTK_STATE_FLAG_DROP_ACTIVE, FALSE);
else
gtk_widget_unset_state_flags (widget, GTK_STATE_FLAG_DROP_ACTIVE);
g_object_notify_by_pspec (G_OBJECT (dest), properties[PROP_CONTAINS]);
}
@ -639,27 +616,55 @@ clear_current_dest (gpointer data, GObject *former_object)
g_object_set_data (G_OBJECT (data), "current-dest", NULL);
}
static void
unset_current_dest (gpointer data)
{
GtkDropTarget *dest = data;
GtkWidget *widget = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (dest));
gtk_drop_target_set_contains (dest, FALSE);
if (widget)
gtk_widget_unset_state_flags (widget, GTK_STATE_FLAG_DROP_ACTIVE);
}
static void
gtk_drop_set_current_dest (GdkDrop *drop,
GtkDropTarget *dest)
{
GtkDropTarget *old_dest;
GtkWidget *widget;
old_dest = g_object_get_data (G_OBJECT (drop), "current-dest");
if (old_dest)
g_object_weak_unref (G_OBJECT (old_dest), clear_current_dest, drop);
if (old_dest == dest)
return;
g_object_set_data (G_OBJECT (drop), "current-dest", dest);
g_print ("set current dest %p\n", dest);
if (old_dest)
{
gtk_drop_target_set_contains (old_dest, FALSE);
widget = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (old_dest));
if (widget)
gtk_widget_unset_state_flags (widget, GTK_STATE_FLAG_DROP_ACTIVE);
gtk_drop_target_emit_drag_leave (old_dest, drop);
g_object_weak_unref (G_OBJECT (old_dest), clear_current_dest, drop);
}
g_object_set_data_full (G_OBJECT (drop), "current-dest", dest, unset_current_dest);
if (dest)
g_object_weak_ref (G_OBJECT (dest), clear_current_dest, drop);
}
{
g_object_weak_ref (G_OBJECT (dest), clear_current_dest, drop);
static GtkDropTarget *
gtk_drop_get_current_dest (GdkDrop *drop)
{
return g_object_get_data (G_OBJECT (drop), "current-dest");
widget = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (dest));
if (widget)
gtk_widget_set_state_flags (widget, GTK_STATE_FLAG_DROP_ACTIVE, FALSE);
gtk_drop_target_set_contains (dest, TRUE);
}
}
static gboolean
@ -668,14 +673,12 @@ gtk_drop_target_handle_event (GtkEventController *controller,
{
GtkDropTarget *dest = GTK_DROP_TARGET (controller);
GdkDrop *drop;
GtkDropTarget *old_dest;
double x, y;
gboolean found = FALSE;
gdk_event_get_coords (event, &x, &y);
drop = gdk_event_get_drop (event);
old_dest = gtk_drop_get_current_dest (drop);
switch ((int)gdk_event_get_event_type (event))
{
@ -684,14 +687,6 @@ gtk_drop_target_handle_event (GtkEventController *controller,
break;
case GDK_DROP_START:
/* We send a leave before the drop so that the widget unhighlights properly.
*/
if (old_dest)
{
gtk_drop_target_emit_drag_leave (old_dest, drop);
gtk_drop_set_current_dest (drop, NULL);
}
found = gtk_drop_target_emit_drag_drop (dest, drop, x, y);
break;
@ -701,12 +696,7 @@ gtk_drop_target_handle_event (GtkEventController *controller,
if (found)
{
if (old_dest && old_dest != dest)
{
gtk_drop_target_emit_drag_leave (old_dest, drop);
gtk_drop_set_current_dest (drop, NULL);
}
g_print ("setting dest from event controller handle_event\n");
gtk_drop_set_current_dest (drop, dest);
}
@ -721,7 +711,6 @@ void
gtk_drag_dest_handle_event (GtkWidget *toplevel,
GdkEvent *event)
{
GtkDropTarget *dest;
GdkDrop *drop;
GdkEventType event_type;
@ -737,16 +726,14 @@ gtk_drag_dest_handle_event (GtkWidget *toplevel,
break;
case GDK_DRAG_LEAVE:
dest = gtk_drop_get_current_dest (drop);
if (dest)
{
gtk_drop_target_emit_drag_leave (dest, drop);
gtk_drop_set_current_dest (drop, NULL);
}
g_print ("setting dest from fallback handle_event for LEAVE\n");
gtk_drop_set_current_dest (drop, NULL);
break;
case GDK_DRAG_MOTION:
case GDK_DROP_START:
g_print ("setting dest from fallback handle_event for MOTION or START\n");
gtk_drop_set_current_dest (drop, NULL);
gdk_drop_status (drop, 0);
break;