button: Track gesture point to maintain priv->in_button

This makes the active state work invariably with both mouse/touch, and
regardless of X11 pointer emulation being friendly and sending crossing
events for the emulated pointer events in the latter.

This makes GtkButtons' active state look correct when pressing on
touchscreens on wayland.

https://bugzilla.gnome.org/show_bug.cgi?id=731380
This commit is contained in:
Carlos Garnacho 2014-08-20 20:12:35 +02:00
parent d04d29f26c
commit ea830aee5d

View File

@ -592,6 +592,7 @@ multipress_pressed_cb (GtkGestureMultiPress *gesture,
if (priv->focus_on_click && !gtk_widget_has_focus (widget))
gtk_widget_grab_focus (widget);
priv->in_button = TRUE;
g_signal_emit (button, button_signals[PRESSED], 0);
gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_CLAIMED);
}
@ -604,10 +605,44 @@ multipress_released_cb (GtkGestureMultiPress *gesture,
GtkWidget *widget)
{
GtkButton *button = GTK_BUTTON (widget);
GtkButtonPrivate *priv = button->priv;
GdkEventSequence *sequence;
GdkDevice *source;
sequence = gtk_gesture_single_get_current_sequence (GTK_GESTURE_SINGLE (gesture));
source = gdk_event_get_source_device (gtk_gesture_get_last_event (GTK_GESTURE (gesture),
sequence));
if (gdk_device_get_source (source) == GDK_SOURCE_TOUCHSCREEN)
priv->in_button = FALSE;
g_signal_emit (button, button_signals[RELEASED], 0);
}
static void
multipress_gesture_update_cb (GtkGesture *gesture,
GdkEventSequence *sequence,
GtkButton *button)
{
GtkButtonPrivate *priv = button->priv;
GtkAllocation allocation;
gboolean in_button;
gdouble x, y;
if (sequence != gtk_gesture_single_get_current_sequence (GTK_GESTURE_SINGLE (gesture)))
return;
gtk_widget_get_allocation (GTK_WIDGET (button), &allocation);
gtk_gesture_get_point (gesture, sequence, &x, &y);
in_button = (x >= 0 && y >= 0 && x < allocation.width && y < allocation.height);
if (priv->in_button != in_button)
{
priv->in_button = in_button;
gtk_button_update_state (button);
}
}
static void
gtk_button_init (GtkButton *button)
{
@ -646,6 +681,7 @@ gtk_button_init (GtkButton *button)
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (priv->gesture), GDK_BUTTON_PRIMARY);
g_signal_connect (priv->gesture, "pressed", G_CALLBACK (multipress_pressed_cb), button);
g_signal_connect (priv->gesture, "released", G_CALLBACK (multipress_released_cb), button);
g_signal_connect (priv->gesture, "update", G_CALLBACK (multipress_gesture_update_cb), button);
gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (priv->gesture), GTK_PHASE_BUBBLE);
}