Skip to content

Commit 3d180af

Browse files
authored
Use GestureController for Zoom (#2296)
1 parent be515b5 commit 3d180af

File tree

4 files changed

+106
-106
lines changed

4 files changed

+106
-106
lines changed

src/Gestures/Gesture.vala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ namespace Gala {
4141
SWITCH_WINDOWS,
4242
MULTITASKING_VIEW,
4343
DOCK,
44+
ZOOM,
4445
N_ACTIONS
4546
}
4647

src/Gestures/GestureController.vala

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,12 @@ public class Gala.GestureController : Object {
4747
public double overshoot_lower_clamp { get; construct set; default = 0d; }
4848
public double overshoot_upper_clamp { get; construct set; default = 1d; }
4949

50+
/**
51+
* When disabled gesture progress will stay where the gesture ended and not snap to full integers values.
52+
* This will also cause the controller to emit smooth progress information even if animations are disabled.
53+
*/
54+
public bool snap { get; construct set; default = true; }
55+
5056
private double _progress = 0;
5157
public double progress {
5258
get { return _progress; }
@@ -129,13 +135,13 @@ public class Gala.GestureController : Object {
129135
|| backend == scroll_backend && GestureSettings.get_action (gesture) == NONE);
130136

131137
if (recognizing) {
132-
if (gesture.direction == UP || gesture.direction == RIGHT) {
138+
if (gesture.direction == UP || gesture.direction == RIGHT || gesture.direction == OUT) {
133139
direction_multiplier = 1;
134140
} else {
135141
direction_multiplier = -1;
136142
}
137143

138-
if (!AnimationsSettings.get_enable_animations ()) {
144+
if (snap && !AnimationsSettings.get_enable_animations ()) {
139145
prepare ();
140146
finish (0, progress + direction_multiplier);
141147
recognizing = false;
@@ -188,17 +194,21 @@ public class Gala.GestureController : Object {
188194
return;
189195
}
190196

197+
recognizing = false;
198+
191199
progress += calculate_applied_delta (percentage, previous_delta);
192200

193201
var to = progress;
194202

195-
if (velocity.abs () > SUCCESS_VELOCITY_THRESHOLD) {
196-
to += (velocity > 0 ? direction_multiplier : -direction_multiplier) * 0.5;
197-
}
203+
if (snap) {
204+
if (velocity.abs () > SUCCESS_VELOCITY_THRESHOLD) {
205+
to += (velocity > 0 ? direction_multiplier : -direction_multiplier) * 0.5;
206+
}
198207

199-
recognizing = false;
208+
to = Math.round (to);
209+
}
200210

201-
finish (velocity, Math.round (to));
211+
finish (velocity, to);
202212

203213
previous_percentage = 0;
204214
previous_time = 0;

src/Gestures/GestureSettings.vala

Lines changed: 39 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -71,37 +71,53 @@ public class Gala.GestureSettings : Object {
7171
}
7272

7373
public static GestureAction get_action (Gesture gesture) {
74-
if (gesture.type == TOUCHPAD_SWIPE) {
75-
var fingers = gesture.fingers;
74+
var fingers = gesture.fingers;
7675

77-
if (gesture.direction == LEFT || gesture.direction == RIGHT) {
78-
var three_finger_swipe_horizontal = get_string ("three-finger-swipe-horizontal");
79-
var four_finger_swipe_horizontal = get_string ("four-finger-swipe-horizontal");
76+
switch (gesture.type) {
77+
case TOUCHPAD_SWIPE:
78+
if (gesture.direction == LEFT || gesture.direction == RIGHT) {
79+
var three_finger_swipe_horizontal = get_string ("three-finger-swipe-horizontal");
80+
var four_finger_swipe_horizontal = get_string ("four-finger-swipe-horizontal");
8081

81-
if (fingers == 3 && three_finger_swipe_horizontal == "switch-to-workspace" ||
82-
fingers == 4 && four_finger_swipe_horizontal == "switch-to-workspace") {
83-
return SWITCH_WORKSPACE;
84-
}
82+
if (fingers == 3 && three_finger_swipe_horizontal == "switch-to-workspace" ||
83+
fingers == 4 && four_finger_swipe_horizontal == "switch-to-workspace") {
84+
return SWITCH_WORKSPACE;
85+
}
86+
87+
if (fingers == 3 && three_finger_swipe_horizontal == "move-to-workspace" ||
88+
fingers == 4 && four_finger_swipe_horizontal == "move-to-workspace") {
89+
return MOVE_TO_WORKSPACE;
90+
}
8591

86-
if (fingers == 3 && three_finger_swipe_horizontal == "move-to-workspace" ||
87-
fingers == 4 && four_finger_swipe_horizontal == "move-to-workspace") {
88-
return MOVE_TO_WORKSPACE;
89-
}
9092

93+
if (fingers == 3 && three_finger_swipe_horizontal == "switch-windows" ||
94+
fingers == 4 && four_finger_swipe_horizontal == "switch-windows") {
95+
return SWITCH_WINDOWS;
96+
}
97+
} else if (gesture.direction == UP || gesture.direction == DOWN) {
98+
var three_finger_swipe_up = get_string ("three-finger-swipe-up");
99+
var four_finger_swipe_up = get_string ("four-finger-swipe-up");
91100

92-
if (fingers == 3 && three_finger_swipe_horizontal == "switch-windows" ||
93-
fingers == 4 && four_finger_swipe_horizontal == "switch-windows") {
94-
return SWITCH_WINDOWS;
101+
if (fingers == 3 && three_finger_swipe_up == "multitasking-view" ||
102+
fingers == 4 && four_finger_swipe_up == "multitasking-view") {
103+
return MULTITASKING_VIEW;
104+
}
95105
}
96-
} else if (gesture.direction == UP || gesture.direction == DOWN) {
97-
var three_finger_swipe_up = get_string ("three-finger-swipe-up");
98-
var four_finger_swipe_up = get_string ("four-finger-swipe-up");
106+
break;
99107

100-
if (fingers == 3 && three_finger_swipe_up == "multitasking-view" ||
101-
fingers == 4 && four_finger_swipe_up == "multitasking-view") {
102-
return MULTITASKING_VIEW;
108+
case TOUCHPAD_PINCH:
109+
var three_finger_pinch = get_string ("three-finger-pinch");
110+
var four_finger_pinch = get_string ("four-finger-pinch");
111+
112+
if (fingers == 3 && three_finger_pinch == "zoom"
113+
|| fingers == 4 && four_finger_pinch == "zoom"
114+
) {
115+
return ZOOM;
103116
}
104-
}
117+
break;
118+
119+
default:
120+
break;
105121
}
106122

107123
return NONE;

src/Zoom.vala

Lines changed: 49 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* SPDX-License-Identifier: GPL-3.0-or-later
66
*/
77

8-
public class Gala.Zoom : Object {
8+
public class Gala.Zoom : Object, GestureTarget {
99
private const float MIN_ZOOM = 1.0f;
1010
private const float MAX_ZOOM = 10.0f;
1111
private const float SHORTCUT_DELTA = 0.5f;
@@ -14,11 +14,15 @@ public class Gala.Zoom : Object {
1414

1515
public WindowManager wm { get; construct; }
1616

17+
public Clutter.Actor? actor { get { return wm.ui_group; } }
18+
1719
private uint mouse_poll_timer = 0;
1820
private float current_zoom = MIN_ZOOM;
1921
private ulong wins_handler_id = 0UL;
2022

21-
private GestureTracker gesture_tracker;
23+
private GestureController gesture_controller;
24+
private double current_commit = 0;
25+
2226
private GLib.Settings behavior_settings;
2327

2428
public Zoom (WindowManager wm) {
@@ -30,10 +34,10 @@ public class Gala.Zoom : Object {
3034
display.add_keybinding ("zoom-in", schema, Meta.KeyBindingFlags.NONE, (Meta.KeyHandlerFunc) zoom_in);
3135
display.add_keybinding ("zoom-out", schema, Meta.KeyBindingFlags.NONE, (Meta.KeyHandlerFunc) zoom_out);
3236

33-
gesture_tracker = new GestureTracker (ANIMATION_DURATION, ANIMATION_DURATION);
34-
gesture_tracker.enable_touchpad ();
35-
gesture_tracker.on_gesture_detected.connect (on_gesture_detected);
36-
gesture_tracker.on_gesture_handled.connect (on_gesture_handled);
37+
gesture_controller = new GestureController (ZOOM, this) {
38+
snap = false
39+
};
40+
gesture_controller.enable_touchpad ();
3741

3842
behavior_settings = new GLib.Settings ("io.elementary.desktop.wm.behavior");
3943

@@ -60,29 +64,13 @@ public class Gala.Zoom : Object {
6064
[CCode (instance_pos = -1)]
6165
private void zoom_in (Meta.Display display, Meta.Window? window,
6266
Clutter.KeyEvent event, Meta.KeyBinding binding) {
63-
zoom (SHORTCUT_DELTA, true, AnimationsSettings.get_enable_animations ());
67+
zoom (SHORTCUT_DELTA, true);
6468
}
6569

6670
[CCode (instance_pos = -1)]
6771
private void zoom_out (Meta.Display display, Meta.Window? window,
6872
Clutter.KeyEvent event, Meta.KeyBinding binding) {
69-
zoom (-SHORTCUT_DELTA, true, AnimationsSettings.get_enable_animations ());
70-
}
71-
72-
private bool on_gesture_detected (Gesture gesture) {
73-
if (gesture.type != Clutter.EventType.TOUCHPAD_PINCH ||
74-
(gesture.direction != GestureDirection.IN && gesture.direction != GestureDirection.OUT)
75-
) {
76-
return false;
77-
}
78-
79-
if ((gesture.fingers == 3 && GestureSettings.get_string ("three-finger-pinch") == "zoom") ||
80-
(gesture.fingers == 4 && GestureSettings.get_string ("four-finger-pinch") == "zoom")
81-
) {
82-
return true;
83-
}
84-
85-
return false;
73+
zoom (-SHORTCUT_DELTA, true);
8674
}
8775

8876
private bool handle_super_scroll (uint32 timestamp, double dx, double dy) {
@@ -93,38 +81,51 @@ public class Gala.Zoom : Object {
9381
var d = dx.abs () > dy.abs () ? dx : dy;
9482

9583
if (d > 0) {
96-
zoom (SHORTCUT_DELTA, true, AnimationsSettings.get_enable_animations ());
84+
zoom (SHORTCUT_DELTA, true);
9785
} else if (d < 0) {
98-
zoom (-SHORTCUT_DELTA, true, AnimationsSettings.get_enable_animations ());
86+
zoom (-SHORTCUT_DELTA, true);
9987
}
10088

10189
return Clutter.EVENT_STOP;
10290
}
10391

104-
private double on_gesture_handled (Gesture gesture, uint32 timestamp) {
105-
var initial_zoom = current_zoom;
106-
var target_zoom = (gesture.direction == GestureDirection.IN)
107-
? initial_zoom - MAX_ZOOM
108-
: initial_zoom + MAX_ZOOM;
109-
110-
GestureTracker.OnUpdate on_animation_update = (percentage) => {
111-
var zoom_level = GestureTracker.animation_value (initial_zoom, target_zoom, percentage);
112-
var delta = zoom_level - current_zoom;
113-
114-
if (!AnimationsSettings.get_enable_animations ()) {
115-
if (delta.abs () >= SHORTCUT_DELTA) {
116-
delta = (delta > 0) ? SHORTCUT_DELTA : -SHORTCUT_DELTA;
117-
} else {
118-
delta = 0;
119-
}
92+
private void zoom (float delta, bool play_sound) {
93+
// Nothing to do if zooming out of our bounds is requested
94+
if ((current_zoom <= MIN_ZOOM && delta < 0) || (current_zoom >= MAX_ZOOM && delta >= 0)) {
95+
if (play_sound) {
96+
InternalUtils.bell_notify (wm.get_display ());
12097
}
98+
return;
99+
}
121100

122-
zoom (delta, false, false);
123-
};
101+
gesture_controller.goto (current_commit + (delta / 10));
102+
}
103+
104+
public override void propagate (UpdateType update_type, GestureAction action, double progress) {
105+
switch (update_type) {
106+
case COMMIT:
107+
current_commit = progress;
108+
break;
109+
110+
case UPDATE:
111+
var target_zoom = (float) progress * 10 + 1;
112+
if (!AnimationsSettings.get_enable_animations ()) {
113+
var delta = target_zoom - current_zoom;
114+
if (delta.abs () >= SHORTCUT_DELTA - float.EPSILON) {
115+
target_zoom = current_zoom + ((delta > 0) ? SHORTCUT_DELTA : -SHORTCUT_DELTA);
116+
} else {
117+
return;
118+
}
119+
}
124120

125-
gesture_tracker.connect_handlers (null, (owned) on_animation_update, null);
121+
current_zoom = target_zoom;
122+
update_ui ();
126123

127-
return 0;
124+
break;
125+
126+
default:
127+
break;
128+
}
128129
}
129130

130131
private inline Graphene.Point compute_new_pivot_point () {
@@ -139,15 +140,7 @@ public class Gala.Zoom : Object {
139140
return new_pivot;
140141
}
141142

142-
private void zoom (float delta, bool play_sound, bool animate) {
143-
// Nothing to do if zooming out of our bounds is requested
144-
if ((current_zoom <= MIN_ZOOM && delta < 0) || (current_zoom >= MAX_ZOOM && delta >= 0)) {
145-
if (play_sound) {
146-
InternalUtils.bell_notify (wm.get_display ());
147-
}
148-
return;
149-
}
150-
143+
private void update_ui () {
151144
unowned var wins = wm.ui_group;
152145
// Add timer to poll current mouse position to reposition window-group
153146
// to show requested zoomed area
@@ -169,9 +162,6 @@ public class Gala.Zoom : Object {
169162
});
170163
}
171164

172-
current_zoom += delta;
173-
var animation_duration = animate ? ANIMATION_DURATION : 0;
174-
175165
if (wins_handler_id > 0) {
176166
wins.disconnect (wins_handler_id);
177167
wins_handler_id = 0;
@@ -185,29 +175,12 @@ public class Gala.Zoom : Object {
185175
mouse_poll_timer = 0;
186176
}
187177

188-
wins.save_easing_state ();
189-
wins.set_easing_mode (Clutter.AnimationMode.EASE_OUT_CUBIC);
190-
wins.set_easing_duration (animation_duration);
191178
wins.set_scale (MIN_ZOOM, MIN_ZOOM);
192-
wins.restore_easing_state ();
193-
194-
if (animate) {
195-
wins_handler_id = wins.transitions_completed.connect (() => {
196-
wins.disconnect (wins_handler_id);
197-
wins_handler_id = 0;
198-
wins.set_pivot_point (0.0f, 0.0f);
199-
});
200-
} else {
201-
wins.set_pivot_point (0.0f, 0.0f);
202-
}
179+
wins.set_pivot_point (0.0f, 0.0f);
203180

204181
return;
205182
}
206183

207-
wins.save_easing_state ();
208-
wins.set_easing_mode (Clutter.AnimationMode.EASE_OUT_CUBIC);
209-
wins.set_easing_duration (animation_duration);
210184
wins.set_scale (current_zoom, current_zoom);
211-
wins.restore_easing_state ();
212185
}
213186
}

0 commit comments

Comments
 (0)