widget: tighten the conditions at which a press event is emulated
Make it really sure that the event is only emitted after every gesture that consumed the button press is done with the sequence. The event must only be emulated if a gesture in the capture phase happened to consume the event, be cancelled, and
This commit is contained in:
parent
6e9b054543
commit
fe9685bca1
@ -510,6 +510,9 @@ gtk_gesture_handle_event (GtkEventController *controller,
|
|||||||
PointData *data;
|
PointData *data;
|
||||||
|
|
||||||
data = g_hash_table_lookup (priv->points, sequence);
|
data = g_hash_table_lookup (priv->points, sequence);
|
||||||
|
|
||||||
|
/* 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;
|
data->press_handled = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -820,7 +823,7 @@ gtk_gesture_set_sequence_state (GtkGesture *gesture,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (data->state == state)
|
if (data->state == state)
|
||||||
return TRUE;
|
return FALSE;
|
||||||
|
|
||||||
/* denied sequences remain denied */
|
/* denied sequences remain denied */
|
||||||
if (data->state == GTK_EVENT_SEQUENCE_DENIED)
|
if (data->state == GTK_EVENT_SEQUENCE_DENIED)
|
||||||
|
@ -4181,31 +4181,65 @@ _gtk_widget_get_emulating_sequence (GtkWidget *widget,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
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,
|
_gtk_widget_set_sequence_state_internal (GtkWidget *widget,
|
||||||
GdkEventSequence *sequence,
|
GdkEventSequence *sequence,
|
||||||
GtkEventSequenceState state,
|
GtkEventSequenceState state,
|
||||||
GList *group)
|
GtkGesture *emitter)
|
||||||
{
|
{
|
||||||
|
gboolean emulates_pointer, sequence_handled = FALSE;
|
||||||
GtkWidgetPrivate *priv = widget->priv;
|
GtkWidgetPrivate *priv = widget->priv;
|
||||||
const GdkEvent *mimic_event;
|
const GdkEvent *mimic_event;
|
||||||
gboolean send_event = FALSE;
|
GList *group = NULL, *l;
|
||||||
gboolean emulates_pointer;
|
|
||||||
GdkEventSequence *seq;
|
GdkEventSequence *seq;
|
||||||
gboolean handled = FALSE;
|
gint n_handled = 0;
|
||||||
GList *l;
|
|
||||||
|
|
||||||
if (!priv->event_controllers && state != GTK_EVENT_SEQUENCE_CLAIMED)
|
if (!priv->event_controllers && state != GTK_EVENT_SEQUENCE_CLAIMED)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
|
if (emitter)
|
||||||
|
group = gtk_gesture_get_group (emitter);
|
||||||
|
|
||||||
emulates_pointer = _gtk_widget_get_emulating_sequence (widget, sequence, &seq);
|
emulates_pointer = _gtk_widget_get_emulating_sequence (widget, sequence, &seq);
|
||||||
mimic_event = _gtk_widget_get_last_event (widget, seq);
|
mimic_event = _gtk_widget_get_last_event (widget, seq);
|
||||||
|
|
||||||
for (l = priv->event_controllers; l; l = l->next)
|
for (l = priv->event_controllers; l; l = l->next)
|
||||||
{
|
{
|
||||||
GtkEventSequenceState gesture_state;
|
GtkEventSequenceState gesture_state;
|
||||||
gboolean sequence_handled, retval;
|
|
||||||
EventControllerData *data;
|
EventControllerData *data;
|
||||||
GtkGesture *gesture;
|
GtkGesture *gesture;
|
||||||
|
gboolean retval;
|
||||||
|
|
||||||
seq = sequence;
|
seq = sequence;
|
||||||
data = l->data;
|
data = l->data;
|
||||||
@ -4216,6 +4250,14 @@ _gtk_widget_set_sequence_state_internal (GtkWidget *widget,
|
|||||||
|
|
||||||
gesture = GTK_GESTURE (data->controller);
|
gesture = GTK_GESTURE (data->controller);
|
||||||
|
|
||||||
|
if (gesture == emitter)
|
||||||
|
{
|
||||||
|
sequence_handled |=
|
||||||
|
_gtk_gesture_handled_sequence_press (gesture, sequence);
|
||||||
|
n_handled++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (seq && emulates_pointer &&
|
if (seq && emulates_pointer &&
|
||||||
!gtk_gesture_handles_sequence (gesture, seq))
|
!gtk_gesture_handles_sequence (gesture, seq))
|
||||||
seq = NULL;
|
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);
|
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);
|
retval = gtk_gesture_set_sequence_state (gesture, seq, gesture_state);
|
||||||
handled |= retval;
|
|
||||||
|
|
||||||
g_signal_handler_unblock (data->controller, data->sequence_state_changed_id);
|
g_signal_handler_unblock (data->controller, data->sequence_state_changed_id);
|
||||||
|
|
||||||
|
if (retval || gesture == emitter)
|
||||||
|
{
|
||||||
|
sequence_handled |=
|
||||||
|
_gtk_gesture_handled_sequence_press (gesture, seq);
|
||||||
|
n_handled++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* If the sequence goes denied, check whether this is a controller attached
|
/* If the sequence goes denied, check whether this is a controller attached
|
||||||
* to the capture phase, that additionally handled the button/touch press (ie.
|
* to the capture phase, that additionally handled the button/touch press (ie.
|
||||||
* it was consumed), the corresponding press will be emulated for widgets
|
* 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.
|
* beneath, so the widgets beneath get a coherent stream of events from now on.
|
||||||
*/
|
*/
|
||||||
if (retval && sequence_handled &&
|
if (n_handled > 0 && sequence_handled &&
|
||||||
data->phase == GTK_PHASE_CAPTURE &&
|
state == GTK_EVENT_SEQUENCE_DENIED &&
|
||||||
state == GTK_EVENT_SEQUENCE_DENIED)
|
gtk_widget_needs_press_emulation (widget, sequence))
|
||||||
send_event = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (send_event && mimic_event)
|
|
||||||
_gtk_widget_emulate_press (widget, mimic_event);
|
_gtk_widget_emulate_press (widget, mimic_event);
|
||||||
|
|
||||||
return handled;
|
g_list_free (group);
|
||||||
|
|
||||||
|
return n_handled;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@ -16683,12 +16726,9 @@ event_controller_sequence_state_changed (GtkGesture *gesture,
|
|||||||
GtkWidget *event_widget;
|
GtkWidget *event_widget;
|
||||||
gboolean cancel = TRUE;
|
gboolean cancel = TRUE;
|
||||||
const GdkEvent *event;
|
const GdkEvent *event;
|
||||||
GList *group;
|
|
||||||
|
|
||||||
group = gtk_gesture_get_group (gesture);
|
|
||||||
handled = _gtk_widget_set_sequence_state_internal (widget, sequence,
|
handled = _gtk_widget_set_sequence_state_internal (widget, sequence,
|
||||||
state, group);
|
state, gesture);
|
||||||
g_list_free (group);
|
|
||||||
|
|
||||||
if (!handled || state != GTK_EVENT_SEQUENCE_CLAIMED)
|
if (!handled || state != GTK_EVENT_SEQUENCE_CLAIMED)
|
||||||
return;
|
return;
|
||||||
|
Loading…
Reference in New Issue
Block a user