summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gtk/gtkgesture.c7
-rw-r--r--gtk/gtkwidget.c92
2 files changed, 71 insertions, 28 deletions
diff --git a/gtk/gtkgesture.c b/gtk/gtkgesture.c
index 420ad9ffa3..e738e61c1c 100644
--- a/gtk/gtkgesture.c
+++ b/gtk/gtkgesture.c
@@ -510,7 +510,10 @@ gtk_gesture_handle_event (GtkEventController *controller,
PointData *data;
data = g_hash_table_lookup (priv->points, sequence);
- data->press_handled = TRUE;
+
+ /* If the sequence was claimed early, the press event will be consumed */
+ if (gtk_gesture_get_sequence_state (gesture, sequence) == GTK_EVENT_SEQUENCE_CLAIMED)
+ data->press_handled = TRUE;
}
break;
@@ -820,7 +823,7 @@ gtk_gesture_set_sequence_state (GtkGesture *gesture,
return FALSE;
if (data->state == state)
- return TRUE;
+ return FALSE;
/* denied sequences remain denied */
if (data->state == GTK_EVENT_SEQUENCE_DENIED)
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index 87ac87396d..18eed60716 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -4181,31 +4181,65 @@ _gtk_widget_get_emulating_sequence (GtkWidget *widget,
}
static gboolean
+gtk_widget_needs_press_emulation (GtkWidget *widget,
+ GdkEventSequence *sequence)
+{
+ GtkWidgetPrivate *priv = widget->priv;
+ gboolean sequence_press_handled = FALSE;
+ GList *l;
+
+ /* Check whether there is any remaining gesture in
+ * the capture phase that handled the press event
+ */
+ for (l = priv->event_controllers; l; l = l->next)
+ {
+ EventControllerData *data;
+ GtkGesture *gesture;
+
+ data = l->data;
+
+ if (data->phase != GTK_PHASE_CAPTURE)
+ continue;
+ if (!GTK_IS_GESTURE (data->controller))
+ continue;
+
+ gesture = GTK_GESTURE (data->controller);
+ sequence_press_handled |=
+ (gtk_gesture_handles_sequence (gesture, sequence) &&
+ _gtk_gesture_handled_sequence_press (gesture, sequence));
+ }
+
+ return !sequence_press_handled;
+}
+
+static gint
_gtk_widget_set_sequence_state_internal (GtkWidget *widget,
GdkEventSequence *sequence,
GtkEventSequenceState state,
- GList *group)
+ GtkGesture *emitter)
{
+ gboolean emulates_pointer, sequence_handled = FALSE;
GtkWidgetPrivate *priv = widget->priv;
const GdkEvent *mimic_event;
- gboolean send_event = FALSE;
- gboolean emulates_pointer;
+ GList *group = NULL, *l;
GdkEventSequence *seq;
- gboolean handled = FALSE;
- GList *l;
+ gint n_handled = 0;
if (!priv->event_controllers && state != GTK_EVENT_SEQUENCE_CLAIMED)
return TRUE;
+ if (emitter)
+ group = gtk_gesture_get_group (emitter);
+
emulates_pointer = _gtk_widget_get_emulating_sequence (widget, sequence, &seq);
mimic_event = _gtk_widget_get_last_event (widget, seq);
for (l = priv->event_controllers; l; l = l->next)
{
GtkEventSequenceState gesture_state;
- gboolean sequence_handled, retval;
EventControllerData *data;
GtkGesture *gesture;
+ gboolean retval;
seq = sequence;
data = l->data;
@@ -4216,6 +4250,14 @@ _gtk_widget_set_sequence_state_internal (GtkWidget *widget,
gesture = GTK_GESTURE (data->controller);
+ if (gesture == emitter)
+ {
+ sequence_handled |=
+ _gtk_gesture_handled_sequence_press (gesture, sequence);
+ n_handled++;
+ continue;
+ }
+
if (seq && emulates_pointer &&
!gtk_gesture_handles_sequence (gesture, seq))
seq = NULL;
@@ -4233,29 +4275,30 @@ _gtk_widget_set_sequence_state_internal (GtkWidget *widget,
}
g_signal_handler_block (data->controller, data->sequence_state_changed_id);
-
- sequence_handled =
- _gtk_gesture_handled_sequence_press (gesture, seq);
retval = gtk_gesture_set_sequence_state (gesture, seq, gesture_state);
- handled |= retval;
-
g_signal_handler_unblock (data->controller, data->sequence_state_changed_id);
- /* If the sequence goes denied, check whether this is a controller attached
- * to the capture phase, that additionally handled the button/touch press (ie.
- * it was consumed), the corresponding press will be emulated for widgets
- * beneath, so the widgets beneath get a coherent stream of events from now on.
- */
- if (retval && sequence_handled &&
- data->phase == GTK_PHASE_CAPTURE &&
- state == GTK_EVENT_SEQUENCE_DENIED)
- send_event = TRUE;
+ if (retval || gesture == emitter)
+ {
+ sequence_handled |=
+ _gtk_gesture_handled_sequence_press (gesture, seq);
+ n_handled++;
+ }
}
- if (send_event && mimic_event)
+ /* If the sequence goes denied, check whether this is a controller attached
+ * to the capture phase, that additionally handled the button/touch press (ie.
+ * it was consumed), the corresponding press will be emulated for widgets
+ * beneath, so the widgets beneath get a coherent stream of events from now on.
+ */
+ if (n_handled > 0 && sequence_handled &&
+ state == GTK_EVENT_SEQUENCE_DENIED &&
+ gtk_widget_needs_press_emulation (widget, sequence))
_gtk_widget_emulate_press (widget, mimic_event);
- return handled;
+ g_list_free (group);
+
+ return n_handled;
}
static gboolean
@@ -16683,12 +16726,9 @@ event_controller_sequence_state_changed (GtkGesture *gesture,
GtkWidget *event_widget;
gboolean cancel = TRUE;
const GdkEvent *event;
- GList *group;
- group = gtk_gesture_get_group (gesture);
handled = _gtk_widget_set_sequence_state_internal (widget, sequence,
- state, group);
- g_list_free (group);
+ state, gesture);
if (!handled || state != GTK_EVENT_SEQUENCE_CLAIMED)
return;