Merge branch 'wip/carlosg/spin-button-swipe-gesture' into 'master'

spinbutton: Connect swipe gesture to the text entry

Closes #4008

See merge request GNOME/gtk!3649
diff --git a/gtk/gtkspinbutton.c b/gtk/gtkspinbutton.c
index f54b8a7..4e70bc5 100644
--- a/gtk/gtkspinbutton.c
+++ b/gtk/gtkspinbutton.c
@@ -208,6 +208,7 @@
 
   double         climb_rate;
   double         timer_step;
+  double         swipe_remainder;
 
   int            width_chars;
 
@@ -838,6 +839,7 @@
 {
   gtk_gesture_set_state (gesture, GTK_EVENT_SEQUENCE_CLAIMED);
   gtk_widget_grab_focus (GTK_WIDGET (spin_button));
+  spin_button->swipe_remainder = 0;
 }
 
 static void
@@ -845,10 +847,12 @@
                       GdkEventSequence *sequence,
                       GtkSpinButton    *spin_button)
 {
-  double vel_y;
+  double vel_y, step;
 
   gtk_gesture_swipe_get_velocity (GTK_GESTURE_SWIPE (gesture), NULL, &vel_y);
-  gtk_spin_button_real_spin (spin_button, -vel_y / 20);
+  step = (-vel_y / 20) + spin_button->swipe_remainder;
+  spin_button->swipe_remainder = fmod (step, gtk_adjustment_get_step_increment (spin_button->adjustment));
+  gtk_spin_button_real_spin (spin_button, step - spin_button->swipe_remainder);
 }
 
 static gboolean
@@ -1075,7 +1079,8 @@
                     G_CALLBACK (swipe_gesture_begin), spin_button);
   g_signal_connect (gesture, "update",
                     G_CALLBACK (swipe_gesture_update), spin_button);
-  gtk_widget_add_controller (GTK_WIDGET (spin_button), GTK_EVENT_CONTROLLER (gesture));
+  gtk_widget_add_controller (GTK_WIDGET (spin_button->entry),
+                             GTK_EVENT_CONTROLLER (gesture));
 
   controller = gtk_event_controller_scroll_new (GTK_EVENT_CONTROLLER_SCROLL_VERTICAL |
 				                GTK_EVENT_CONTROLLER_SCROLL_DISCRETE);