Commit ea830aee authored by Carlos Garnacho's avatar Carlos Garnacho

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.
parent d04d29f2
......@@ -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),
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)))
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);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment