gtk: Bubble drag events like motion events
Emit crossing events - with a new GTK_CROSSING_DROP type - like we do for motion events. There is no more special casing for them. Note that the gesture has not been updated yet, so some obscure behavior may occur.
This commit is contained in:
@@ -24,7 +24,8 @@
|
||||
|
||||
typedef enum {
|
||||
GTK_CROSSING_FOCUS,
|
||||
GTK_CROSSING_POINTER
|
||||
GTK_CROSSING_POINTER,
|
||||
GTK_CROSSING_DROP
|
||||
} GtkCrossingType;
|
||||
|
||||
typedef enum {
|
||||
@@ -47,11 +48,12 @@ typedef struct _GtkCrossingData GtkCrossingData;
|
||||
* @new_descendent: the direct child of the receiving widget that
|
||||
* is an ancestor of @new_target, or %NULL if @new_target is not
|
||||
* a descendent of the receiving widget
|
||||
* @drop: the #GdkDrop if this is info for a drop operation
|
||||
*
|
||||
* The struct that is passed to gtk_event_controller_handle_crossing().
|
||||
*
|
||||
* The @old_target and @new_target fields are set to the old or new
|
||||
* focus or hover location.
|
||||
* focus, drop or hover location.
|
||||
*/
|
||||
struct _GtkCrossingData {
|
||||
GtkCrossingType type;
|
||||
@@ -61,6 +63,7 @@ struct _GtkCrossingData {
|
||||
GtkWidget *old_descendent;
|
||||
GtkWidget *new_target;
|
||||
GtkWidget *new_descendent;
|
||||
GdkDrop *drop;
|
||||
};
|
||||
|
||||
struct _GtkEventController
|
||||
|
||||
@@ -1304,12 +1304,14 @@ translate_event_coordinates (GdkEvent *event,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
gtk_synthesize_crossing_events (GtkRoot *toplevel,
|
||||
GtkCrossingType crossing_type,
|
||||
GtkWidget *old_target,
|
||||
GtkWidget *new_target,
|
||||
GdkEvent *event,
|
||||
GdkCrossingMode mode)
|
||||
GdkCrossingMode mode,
|
||||
GdkDrop *drop)
|
||||
{
|
||||
GtkCrossingData crossing;
|
||||
GtkWidget *ancestor;
|
||||
@@ -1324,12 +1326,13 @@ gtk_synthesize_crossing_events (GtkRoot *toplevel,
|
||||
else
|
||||
ancestor = NULL;
|
||||
|
||||
crossing.type = GTK_CROSSING_POINTER;
|
||||
crossing.type = crossing_type;
|
||||
crossing.mode = mode;
|
||||
crossing.old_target = old_target;
|
||||
crossing.old_descendent = NULL;
|
||||
crossing.new_target = new_target;
|
||||
crossing.new_descendent = NULL;
|
||||
crossing.drop = drop;
|
||||
|
||||
crossing.direction = GTK_CROSSING_OUT;
|
||||
|
||||
@@ -1360,7 +1363,8 @@ gtk_synthesize_crossing_events (GtkRoot *toplevel,
|
||||
check_crossing_invariants (widget, &crossing);
|
||||
translate_event_coordinates (event, &x, &y, widget);
|
||||
gtk_widget_handle_crossing (widget, &crossing, x, y);
|
||||
gtk_widget_unset_state_flags (widget, GTK_STATE_FLAG_PRELIGHT);
|
||||
if (crossing_type == GTK_CROSSING_POINTER)
|
||||
gtk_widget_unset_state_flags (widget, GTK_STATE_FLAG_PRELIGHT);
|
||||
widget = gtk_widget_get_parent (widget);
|
||||
}
|
||||
|
||||
@@ -1399,7 +1403,8 @@ gtk_synthesize_crossing_events (GtkRoot *toplevel,
|
||||
|
||||
translate_event_coordinates (event, &x, &y, widget);
|
||||
gtk_widget_handle_crossing (widget, &crossing, x, y);
|
||||
gtk_widget_set_state_flags (widget, GTK_STATE_FLAG_PRELIGHT, FALSE);
|
||||
if (crossing_type == GTK_CROSSING_POINTER)
|
||||
gtk_widget_set_state_flags (widget, GTK_STATE_FLAG_PRELIGHT, FALSE);
|
||||
}
|
||||
|
||||
g_list_free (list);
|
||||
@@ -1445,8 +1450,12 @@ is_pointing_event (GdkEvent *event)
|
||||
case GDK_TOUCH_CANCEL:
|
||||
case GDK_TOUCHPAD_PINCH:
|
||||
case GDK_TOUCHPAD_SWIPE:
|
||||
case GDK_DRAG_ENTER:
|
||||
case GDK_DRAG_LEAVE:
|
||||
case GDK_DRAG_MOTION:
|
||||
case GDK_DROP_START:
|
||||
return TRUE;
|
||||
break;
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
@@ -1479,21 +1488,6 @@ is_focus_event (GdkEvent *event)
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_dnd_event (GdkEvent *event)
|
||||
{
|
||||
switch ((guint) gdk_event_get_event_type (event))
|
||||
{
|
||||
case GDK_DRAG_ENTER:
|
||||
case GDK_DRAG_LEAVE:
|
||||
case GDK_DRAG_MOTION:
|
||||
case GDK_DROP_START:
|
||||
return TRUE;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
set_widget_active_state (GtkWidget *target,
|
||||
const gboolean release)
|
||||
@@ -1549,14 +1543,22 @@ handle_pointing_event (GdkEvent *event)
|
||||
case GDK_TOUCH_CANCEL:
|
||||
old_target = update_pointer_focus_state (toplevel, event, NULL);
|
||||
if (type == GDK_LEAVE_NOTIFY)
|
||||
gtk_synthesize_crossing_events (GTK_ROOT (toplevel), old_target, NULL,
|
||||
event, gdk_crossing_event_get_mode (event));
|
||||
gtk_synthesize_crossing_events (GTK_ROOT (toplevel), GTK_CROSSING_POINTER, old_target, NULL,
|
||||
event, gdk_crossing_event_get_mode (event), NULL);
|
||||
break;
|
||||
case GDK_DRAG_LEAVE:
|
||||
old_target = update_pointer_focus_state (toplevel, event, NULL);
|
||||
gtk_synthesize_crossing_events (GTK_ROOT (toplevel), GTK_CROSSING_DROP, old_target, NULL,
|
||||
event, GDK_CROSSING_NORMAL, gdk_drag_event_get_drop (event));
|
||||
break;
|
||||
case GDK_ENTER_NOTIFY:
|
||||
if (gdk_crossing_event_get_mode (event) == GDK_CROSSING_GRAB ||
|
||||
gdk_crossing_event_get_mode (event) == GDK_CROSSING_UNGRAB)
|
||||
break;
|
||||
G_GNUC_FALLTHROUGH;
|
||||
case GDK_DRAG_ENTER:
|
||||
case GDK_DRAG_MOTION:
|
||||
case GDK_DROP_START:
|
||||
case GDK_TOUCH_BEGIN:
|
||||
case GDK_TOUCH_UPDATE:
|
||||
case GDK_MOTION_NOTIFY:
|
||||
@@ -1575,14 +1577,18 @@ handle_pointing_event (GdkEvent *event)
|
||||
if (!gtk_window_lookup_pointer_focus_implicit_grab (toplevel, device,
|
||||
sequence))
|
||||
{
|
||||
gtk_synthesize_crossing_events (GTK_ROOT (toplevel), old_target, target,
|
||||
event, GDK_CROSSING_NORMAL);
|
||||
gtk_synthesize_crossing_events (GTK_ROOT (toplevel), GTK_CROSSING_POINTER, old_target, target,
|
||||
event, GDK_CROSSING_NORMAL, NULL);
|
||||
}
|
||||
|
||||
gtk_window_maybe_update_cursor (toplevel, NULL, device);
|
||||
}
|
||||
|
||||
if (type == GDK_TOUCH_BEGIN)
|
||||
else if (type == GDK_DRAG_ENTER || type == GDK_DRAG_MOTION || type == GDK_DROP_START)
|
||||
{
|
||||
gtk_synthesize_crossing_events (GTK_ROOT (toplevel), GTK_CROSSING_DROP, old_target, target,
|
||||
event, GDK_CROSSING_NORMAL, gdk_drag_event_get_drop (event));
|
||||
}
|
||||
else if (type == GDK_TOUCH_BEGIN)
|
||||
gtk_window_set_pointer_focus_grab (toplevel, device, sequence, target);
|
||||
|
||||
/* Let it take the effective pointer focus anyway, as it may change due
|
||||
@@ -1605,8 +1611,8 @@ handle_pointing_event (GdkEvent *event)
|
||||
new_target = gtk_widget_pick (GTK_WIDGET (native), x, y, GTK_PICK_DEFAULT);
|
||||
if (new_target == NULL)
|
||||
new_target = GTK_WIDGET (toplevel);
|
||||
gtk_synthesize_crossing_events (GTK_ROOT (toplevel), target, new_target,
|
||||
event, GDK_CROSSING_UNGRAB);
|
||||
gtk_synthesize_crossing_events (GTK_ROOT (toplevel), GTK_CROSSING_POINTER, target, new_target,
|
||||
event, GDK_CROSSING_UNGRAB, NULL);
|
||||
gtk_window_maybe_update_cursor (toplevel, NULL, device);
|
||||
}
|
||||
|
||||
@@ -1640,23 +1646,6 @@ handle_key_event (GdkEvent *event)
|
||||
return focus_widget ? focus_widget : event_widget;
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
handle_dnd_event (GdkEvent *event)
|
||||
{
|
||||
GtkWidget *event_widget;
|
||||
GtkWidget *target;
|
||||
gdouble x, y;
|
||||
GtkWidget *native;
|
||||
|
||||
event_widget = gtk_get_event_widget (event);
|
||||
|
||||
gdk_event_get_position (event, &x, &y);
|
||||
native = GTK_WIDGET (gtk_widget_get_native (event_widget));
|
||||
target = gtk_widget_pick (native, x, y, GTK_PICK_DEFAULT);
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_main_do_event (GdkEvent *event)
|
||||
{
|
||||
@@ -1715,8 +1704,6 @@ gtk_main_do_event (GdkEvent *event)
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
else if (is_dnd_event (event))
|
||||
target_widget = handle_dnd_event (event);
|
||||
|
||||
if (!target_widget)
|
||||
goto cleanup;
|
||||
@@ -1812,14 +1799,15 @@ gtk_main_do_event (GdkEvent *event)
|
||||
/* Crossing event propagation happens during picking */
|
||||
break;
|
||||
|
||||
case GDK_DRAG_ENTER:
|
||||
case GDK_DRAG_MOTION:
|
||||
case GDK_DROP_START:
|
||||
if (gtk_propagate_event (target_widget, event))
|
||||
break;
|
||||
G_GNUC_FALLTHROUGH;
|
||||
|
||||
case GDK_DRAG_ENTER:
|
||||
case GDK_DRAG_LEAVE:
|
||||
/* Crossing event propagation happens during picking */
|
||||
gtk_drag_dest_handle_event (target_widget, event);
|
||||
break;
|
||||
|
||||
|
||||
@@ -259,12 +259,6 @@ GdkSurface * _gtk_widget_get_device_surface (GtkWidget *widget,
|
||||
GdkDevice *device);
|
||||
GList * _gtk_widget_list_devices (GtkWidget *widget);
|
||||
|
||||
void gtk_synthesize_crossing_events (GtkRoot *toplevel,
|
||||
GtkWidget *from,
|
||||
GtkWidget *to,
|
||||
GdkEvent *source,
|
||||
GdkCrossingMode mode);
|
||||
|
||||
void _gtk_widget_synthesize_crossing (GtkWidget *from,
|
||||
GtkWidget *to,
|
||||
GdkDevice *device,
|
||||
|
||||
Reference in New Issue
Block a user