@@ -39,10 +39,13 @@ public class Gala.GestureController : Object {
3939 get { return _target; }
4040 set {
4141 _target = value ;
42- target. propagate (UPDATE , action, calculate_bounded_progress () );
42+ target. propagate (UPDATE , action, progress );
4343 }
4444 }
4545
46+ private Variant ? _action_info;
47+ public Variant ? action_info { get { return _action_info; } }
48+
4649 public double distance { get ; construct set ; }
4750 public double overshoot_lower_clamp { get ; construct set ; default = 0d; }
4851 public double overshoot_upper_clamp { get ; construct set ; default = 1d; }
@@ -58,7 +61,7 @@ public class Gala.GestureController : Object {
5861 get { return _progress; }
5962 set {
6063 _progress = value ;
61- target. propagate (UPDATE , action, calculate_bounded_progress () );
64+ target. propagate (UPDATE , action, value );
6265 }
6366 }
6467
@@ -77,34 +80,19 @@ public class Gala.GestureController : Object {
7780 private ScrollBackend ? scroll_backend;
7881
7982 private GestureBackend ? recognizing_backend;
83+ private double gesture_progress;
8084 private double previous_percentage;
8185 private uint64 previous_time;
8286 private double previous_delta;
8387 private double velocity;
8488 private int direction_multiplier;
8589
86- private Clutter . Timeline ? timeline;
90+ private SpringTimeline ? timeline;
8791
8892 public GestureController (GestureAction action, GestureTarget target) {
8993 Object (action: action, target: target);
9094 }
9195
92- private double calculate_bounded_progress () {
93- var lower_clamp_int = (int ) overshoot_lower_clamp;
94- var upper_clamp_int = (int ) overshoot_upper_clamp;
95-
96- double stretched_percentage = 0 ;
97- if (_progress < lower_clamp_int) {
98- stretched_percentage = (_progress - lower_clamp_int) * - (overshoot_lower_clamp - lower_clamp_int);
99- } else if (_progress > upper_clamp_int) {
100- stretched_percentage = (_progress - upper_clamp_int) * (overshoot_upper_clamp - upper_clamp_int);
101- }
102-
103- var clamped = _progress. clamp (lower_clamp_int, upper_clamp_int);
104-
105- return clamped + stretched_percentage;
106- }
107-
10896 public void enable_touchpad () {
10997 touchpad_backend = ToucheggBackend . get_default ();
11098 touchpad_backend. on_gesture_detected. connect (gesture_detected);
@@ -127,11 +115,11 @@ public class Gala.GestureController : Object {
127115 timeline = null ;
128116 }
129117
130- target. propagate (START , action, calculate_bounded_progress () );
118+ target. propagate (START , action, progress );
131119 }
132120
133121 private bool gesture_detected (GestureBackend backend, Gesture gesture, uint32 timestamp) {
134- recognizing = enabled && (GestureSettings . get_action (gesture) == action
122+ recognizing = enabled && (GestureSettings . get_action (gesture, out _action_info ) == action
135123 || backend == scroll_backend && GestureSettings . get_action (gesture) == NONE );
136124
137125 if (recognizing) {
@@ -142,9 +130,9 @@ public class Gala.GestureController : Object {
142130 }
143131
144132 if (snap && ! Meta . Prefs . get_gnome_animations ()) {
133+ recognizing = false ;
145134 prepare ();
146135 finish (0 , progress + direction_multiplier);
147- recognizing = false ;
148136 }
149137
150138 recognizing_backend = backend;
@@ -160,6 +148,7 @@ public class Gala.GestureController : Object {
160148
161149 prepare ();
162150
151+ gesture_progress = progress;
163152 previous_percentage = percentage;
164153 previous_time = elapsed_time;
165154 }
@@ -182,7 +171,7 @@ public class Gala.GestureController : Object {
182171 }
183172 }
184173
185- progress + = calculate_applied_delta (percentage, updated_delta);
174+ update_gesture_progress (percentage, updated_delta);
186175
187176 previous_percentage = percentage;
188177 previous_time = elapsed_time;
@@ -196,7 +185,7 @@ public class Gala.GestureController : Object {
196185
197186 recognizing = false ;
198187
199- progress + = calculate_applied_delta (percentage, previous_delta);
188+ update_gesture_progress (percentage, previous_delta);
200189
201190 var to = progress;
202191
@@ -208,17 +197,32 @@ public class Gala.GestureController : Object {
208197 to = Math . round (to);
209198 }
210199
211- finish (velocity, to);
200+ finish (velocity * direction_multiplier , to);
212201
202+ gesture_progress = 0 ;
213203 previous_percentage = 0 ;
214204 previous_time = 0 ;
215205 previous_delta = 0 ;
216206 velocity = 0 ;
217207 direction_multiplier = 0 ;
218208 }
219209
220- private inline double calculate_applied_delta (double percentage, double percentage_delta) {
221- return ((percentage - percentage_delta) - (previous_percentage - previous_delta)) * direction_multiplier;
210+ private void update_gesture_progress (double percentage, double percentage_delta) {
211+ gesture_progress + = ((percentage - percentage_delta) - (previous_percentage - previous_delta)) * direction_multiplier;
212+
213+ var lower_clamp_int = (int ) overshoot_lower_clamp;
214+ var upper_clamp_int = (int ) overshoot_upper_clamp;
215+
216+ double stretched_percentage = 0 ;
217+ if (gesture_progress < lower_clamp_int) {
218+ stretched_percentage = (gesture_progress - lower_clamp_int) * - (overshoot_lower_clamp - lower_clamp_int);
219+ } else if (gesture_progress > upper_clamp_int) {
220+ stretched_percentage = (gesture_progress - upper_clamp_int) * (overshoot_upper_clamp - upper_clamp_int);
221+ }
222+
223+ var clamped = gesture_progress. clamp (lower_clamp_int, upper_clamp_int);
224+
225+ progress = clamped + stretched_percentage;
222226 }
223227
224228 private void finish (double velocity, double to) {
@@ -227,39 +231,48 @@ public class Gala.GestureController : Object {
227231 target. propagate (COMMIT , action, clamped_to);
228232
229233 if (progress == to) {
230- target . propagate ( END , action, calculate_bounded_progress () );
234+ finished ( );
231235 return ;
232236 }
233237
234238 if (! Meta . Prefs . get_gnome_animations ()) {
235239 progress = clamped_to;
236- target . propagate ( END , action, calculate_bounded_progress () );
240+ finished ( );
237241 return ;
238242 }
239243
240- var spring = new SpringTimeline (target. actor, progress, clamped_to, velocity, 1 , 1 , 1000 );
244+ var spring = new SpringTimeline (target. actor, progress, clamped_to, velocity, 1 , 1 , 500 );
241245 spring. progress. connect ((value ) = > progress = value );
242- spring. stopped. connect (() = > {
243- target. propagate (END , action, calculate_bounded_progress ());
244- timeline = null ;
245- });
246+ spring. stopped. connect_after (finished);
246247
247248 timeline = spring;
248249 }
249250
251+ private void finished (bool is_finished = true ) {
252+ target. propagate (END , action, progress);
253+ timeline = null ;
254+
255+ if (is_finished) {
256+ _action_info = null ;
257+ }
258+ }
259+
250260 /**
251261 * Animates to the given progress value.
252262 * If the gesture is currently recognizing, it will do nothing.
253263 * If that's not what you want, you should call {@link cancel_gesture} first.
254264 * If you don't want animation but an immediate jump, you should set {@link progress} directly.
255265 */
256266 public void goto (double to) {
257- if (progress == to || recognizing) {
267+ var clamped_to = to. clamp ((int ) overshoot_lower_clamp, (int ) overshoot_upper_clamp);
268+ if (progress == to || recognizing ||
269+ timeline != null && clamped_to == timeline. value_to // Only allow overshoot if there's no ongoing overshoot animation to prevent stacking
270+ ) {
258271 return ;
259272 }
260273
261274 prepare ();
262- finish (0.005 , to);
275+ finish ((to > progress ? 1 : - 1 ) * 1 , to);
263276 }
264277
265278 public void cancel_gesture () {
0 commit comments