gtkmodelbutton: Ignore releases outside of the button
authorSebastian Keller <skeller@gnome.org>
Thu, 20 Apr 2023 22:31:53 +0000 (00:31 +0200)
committerSebastian Keller <skeller@gnome.org>
Tue, 25 Apr 2023 17:28:42 +0000 (19:28 +0200)
This is also how regular buttons behave. Otherwise releasing on a
different menu item would register a click on the item that was
originally pressed. In these cases it is better to not register a click
at all.

Closes: https://gitlab.gnome.org/GNOME/gtk/-/issues/5760
gtk/gtkmodelbutton.c

index 064583623abad5aef2df6c26fa0efe2fa949382e..a296e6119c6b927d6dbc590051d4d5444048504f 100644 (file)
@@ -1450,9 +1450,26 @@ gesture_pressed (GtkGestureClick *gesture,
 }
 
 static void
-emit_clicked (GtkModelButton *button)
+gesture_released (GtkGestureClick *gesture,
+                  guint            n_press,
+                  double           x,
+                  double           y,
+                  GtkWidget       *widget)
 {
-  g_signal_emit (button, signals[SIGNAL_CLICKED], 0);
+  if (gtk_widget_contains (widget, x, y))
+    g_signal_emit (widget, signals[SIGNAL_CLICKED], 0);
+}
+
+static void
+gesture_unpaired_release (GtkGestureClick  *gesture,
+                          double            x,
+                          double            y,
+                          guint             button,
+                          GdkEventSequence *sequence,
+                          GtkWidget        *widget)
+{
+  if (gtk_widget_contains (widget, x, y))
+    g_signal_emit (widget, signals[SIGNAL_CLICKED], 0);
 }
 
 static void
@@ -1489,8 +1506,8 @@ gtk_model_button_init (GtkModelButton *self)
   gtk_gesture_single_set_exclusive (GTK_GESTURE_SINGLE (gesture), TRUE);
   gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (gesture), GDK_BUTTON_PRIMARY);
   g_signal_connect (gesture, "pressed", G_CALLBACK (gesture_pressed), self);
-  g_signal_connect_swapped (gesture, "released", G_CALLBACK (emit_clicked), self);
-  g_signal_connect_swapped (gesture, "unpaired-release", G_CALLBACK (emit_clicked), self);
+  g_signal_connect (gesture, "released", G_CALLBACK (gesture_released), self);
+  g_signal_connect (gesture, "unpaired-release", G_CALLBACK (gesture_unpaired_release), self);
   gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (gesture), GTK_PHASE_CAPTURE);
   gtk_widget_add_controller (GTK_WIDGET (self), GTK_EVENT_CONTROLLER (gesture));
 }