widget: Improve hack to ignore drags from widgets using motion events

Postpone until the last moment whether the target widget still
potentially uses updates from this sequence, or window dragging
actually applies because all gestures on the target went to denied
state.

This fixes window dragging on empty space in a headerbar that is
contained in a paned (as in e.g. gedit).

https://bugzilla.gnome.org/show_bug.cgi?id=745562
This commit is contained in:
Carlos Garnacho 2015-03-03 22:17:58 +01:00 committed by Matthias Clasen
parent 768e6a4579
commit 08494f86a0
3 changed files with 26 additions and 18 deletions

View File

@ -17284,7 +17284,8 @@ _gtk_widget_list_controllers (GtkWidget *widget,
} }
gboolean gboolean
_gtk_widget_consumes_motion (GtkWidget *widget) _gtk_widget_consumes_motion (GtkWidget *widget,
GdkEventSequence *sequence)
{ {
EventControllerData *data; EventControllerData *data;
GtkWidgetPrivate *priv; GtkWidgetPrivate *priv;
@ -17301,10 +17302,11 @@ _gtk_widget_consumes_motion (GtkWidget *widget)
if (data->controller == NULL) if (data->controller == NULL)
continue; continue;
if (!GTK_IS_GESTURE_SINGLE (data->controller)) if ((!GTK_IS_GESTURE_SINGLE (data->controller) ||
return TRUE; GTK_IS_GESTURE_DRAG (data->controller) ||
else if (GTK_IS_GESTURE_DRAG (data->controller) || GTK_IS_GESTURE_SWIPE (data->controller)) &&
GTK_IS_GESTURE_SWIPE (data->controller)) gtk_gesture_get_sequence_state (GTK_GESTURE (data->controller),
sequence) != GTK_EVENT_SEQUENCE_DENIED)
return TRUE; return TRUE;
} }

View File

@ -160,7 +160,8 @@ void _gtk_widget_remove_controller (GtkWidget
GtkEventController *controller); GtkEventController *controller);
GList * _gtk_widget_list_controllers (GtkWidget *widget, GList * _gtk_widget_list_controllers (GtkWidget *widget,
GtkPropagationPhase phase); GtkPropagationPhase phase);
gboolean _gtk_widget_consumes_motion (GtkWidget *widget); gboolean _gtk_widget_consumes_motion (GtkWidget *widget,
GdkEventSequence *sequence);
gboolean gtk_widget_has_tick_callback (GtkWidget *widget); gboolean gtk_widget_has_tick_callback (GtkWidget *widget);

View File

@ -1509,7 +1509,6 @@ drag_gesture_begin_cb (GtkGestureDrag *gesture,
GdkEventSequence *sequence; GdkEventSequence *sequence;
GtkWindowRegion region; GtkWindowRegion region;
const GdkEvent *event; const GdkEvent *event;
GtkWidget *event_widget;
sequence = gtk_gesture_single_get_current_sequence (GTK_GESTURE_SINGLE (gesture)); sequence = gtk_gesture_single_get_current_sequence (GTK_GESTURE_SINGLE (gesture));
event = gtk_gesture_get_last_event (GTK_GESTURE (gesture), sequence); event = gtk_gesture_get_last_event (GTK_GESTURE (gesture), sequence);
@ -1517,19 +1516,10 @@ drag_gesture_begin_cb (GtkGestureDrag *gesture,
if (!event) if (!event)
return; return;
event_widget = gtk_get_event_widget ((GdkEvent *) event); region = get_active_region_type (window, (GdkEventAny*) event, x, y);
if (event_widget != GTK_WIDGET (window) && if (region != GTK_WINDOW_REGION_TITLE)
!gtk_widget_has_grab (event_widget) &&
_gtk_widget_consumes_motion (event_widget))
gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_DENIED); gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_DENIED);
else
{
region = get_active_region_type (window, (GdkEventAny*) event, x, y);
if (region != GTK_WINDOW_REGION_TITLE)
gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_DENIED);
}
} }
static void static void
@ -1549,8 +1539,23 @@ drag_gesture_update_cb (GtkGestureDrag *gesture,
if (ABS (offset_x) > double_click_distance || if (ABS (offset_x) > double_click_distance ||
ABS (offset_y) > double_click_distance) ABS (offset_y) > double_click_distance)
{ {
GdkEventSequence *sequence;
gdouble start_x, start_y; gdouble start_x, start_y;
gint x_root, y_root; gint x_root, y_root;
const GdkEvent *event;
GtkWidget *event_widget;
sequence = gtk_gesture_single_get_current_sequence (GTK_GESTURE_SINGLE (gesture));
event = gtk_gesture_get_last_event (GTK_GESTURE (gesture), sequence);
event_widget = gtk_get_event_widget ((GdkEvent *) event);
if (event_widget != GTK_WIDGET (window) &&
!gtk_widget_has_grab (event_widget) &&
_gtk_widget_consumes_motion (event_widget, sequence))
{
gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_DENIED);
return;
}
gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_CLAIMED); gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_CLAIMED);