Skip to content

Commit 7b9f195

Browse files
committed
ShellClients: Use translation y instead of clone and gesturetransition for animation
1 parent ae33e82 commit 7b9f195

File tree

3 files changed

+68
-101
lines changed

3 files changed

+68
-101
lines changed

src/Gestures/GestureTracker.vala

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,8 @@ public class Gala.GestureTracker : Object {
7575
*/
7676
public bool enabled { get; set; default = true; }
7777

78+
public bool recognizing { get; private set; }
79+
7880
/**
7981
* Emitted when a new gesture is detected.
8082
* This should only be used to determine whether the gesture should be handled. This shouldn't
@@ -193,6 +195,23 @@ public class Gala.GestureTracker : Object {
193195
}
194196
}
195197

198+
/**
199+
* Connects a callback that will only be called if != 0 completions were made.
200+
* If with_gesture is false it will be called immediately, otherwise once {@link on_end} is emitted.
201+
*/
202+
public void add_success_callback (bool with_gesture, owned OnEnd callback) {
203+
if (!with_gesture) {
204+
callback (1, 1, min_animation_duration);
205+
} else {
206+
ulong handler_id = on_end.connect ((percentage, completions, duration) => {
207+
if (completions != 0) {
208+
callback (percentage, completions, duration);
209+
}
210+
});
211+
handlers.add (handler_id);
212+
}
213+
}
214+
196215
private void disconnect_all_handlers () {
197216
foreach (var handler in handlers) {
198217
disconnect (handler);
@@ -242,6 +261,7 @@ public class Gala.GestureTracker : Object {
242261
on_begin (percentage);
243262
}
244263

264+
recognizing = true;
245265
previous_percentage = percentage;
246266
previous_time = elapsed_time;
247267
}
@@ -283,6 +303,7 @@ public class Gala.GestureTracker : Object {
283303
}
284304

285305
disconnect_all_handlers ();
306+
recognizing = false;
286307
previous_percentage = 0;
287308
previous_time = 0;
288309
percentage_delta = 0;

src/ShellClients/HideTracker.vala

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,12 @@ public class Gala.HideTracker : Object {
1010
private const int UPDATE_TIMEOUT = 200;
1111
private const int HIDE_DELAY = 500;
1212

13-
public signal void hide ();
14-
public signal void show ();
13+
public signal void hide (GestureTracker gesture_tracker, bool with_gesture);
14+
public signal void show (GestureTracker gesture_tracker, bool with_gesture);
1515

1616
public Meta.Display display { get; construct; }
1717
public unowned PanelWindow panel { get; construct; }
18+
public GestureTracker default_gesture_tracker { get; construct; } // Placeholder that will replace pan_action once the pan_backend gets merged
1819

1920
public Pantheon.Desktop.HideMode hide_mode { get; set; }
2021

@@ -33,8 +34,8 @@ public class Gala.HideTracker : Object {
3334
private uint hide_timeout_id = 0;
3435
private uint update_timeout_id = 0;
3536

36-
public HideTracker (Meta.Display display, PanelWindow panel) {
37-
Object (display: display, panel: panel);
37+
public HideTracker (Meta.Display display, PanelWindow panel, GestureTracker default_gesture_tracker) {
38+
Object (display: display, panel: panel, default_gesture_tracker: default_gesture_tracker);
3839
}
3940

4041
~HideTracker () {
@@ -146,13 +147,13 @@ public class Gala.HideTracker : Object {
146147
}
147148

148149
update_timeout_id = Timeout.add (UPDATE_TIMEOUT, () => {
149-
update_overlap ();
150+
update_overlap (default_gesture_tracker, false);
150151
update_timeout_id = 0;
151152
return Source.REMOVE;
152153
});
153154
}
154155

155-
private void update_overlap () {
156+
public void update_overlap (GestureTracker gesture_tracker, bool with_gesture) {
156157
overlap = false;
157158
focus_overlap = false;
158159
focus_maximized_overlap = false;
@@ -185,25 +186,25 @@ public class Gala.HideTracker : Object {
185186
focus_maximized_overlap = VERTICAL in window.get_maximized ();
186187
}
187188

188-
update_hidden ();
189+
update_hidden (gesture_tracker, with_gesture);
189190
}
190191

191-
private void update_hidden () {
192+
private void update_hidden (GestureTracker gesture_tracker, bool with_gesture) {
192193
switch (hide_mode) {
193194
case MAXIMIZED_FOCUS_WINDOW:
194-
toggle_display (focus_maximized_overlap);
195+
toggle_display (focus_maximized_overlap, gesture_tracker, with_gesture);
195196
break;
196197

197198
case OVERLAPPING_FOCUS_WINDOW:
198-
toggle_display (focus_overlap);
199+
toggle_display (focus_overlap, gesture_tracker, with_gesture);
199200
break;
200201

201202
case OVERLAPPING_WINDOW:
202-
toggle_display (overlap);
203+
toggle_display (overlap, gesture_tracker, with_gesture);
203204
break;
204205

205206
case ALWAYS:
206-
toggle_display (true);
207+
toggle_display (true, gesture_tracker, with_gesture);
207208
break;
208209

209210
default:
@@ -212,7 +213,11 @@ public class Gala.HideTracker : Object {
212213
}
213214
}
214215

215-
private void toggle_display (bool should_hide) {
216+
private void toggle_display (bool should_hide, GestureTracker gesture_tracker, bool with_gesture) {
217+
if (display.get_monitor_in_fullscreen (panel.window.get_monitor ())) {
218+
return;
219+
}
220+
216221
#if HAS_MUTTER45
217222
hovered = panel.window.has_pointer ();
218223
#else
@@ -222,7 +227,7 @@ public class Gala.HideTracker : Object {
222227
if (should_hide && !hovered && !panel.window.has_focus ()) {
223228
trigger_hide ();
224229
} else {
225-
trigger_show ();
230+
trigger_show (gesture_tracker, with_gesture);
226231
}
227232
}
228233

@@ -241,7 +246,7 @@ public class Gala.HideTracker : Object {
241246
}
242247

243248
hide_timeout_id = Timeout.add_once (HIDE_DELAY, () => {
244-
hide ();
249+
hide (default_gesture_tracker, false);
245250
hide_timeout_id = 0;
246251
});
247252
}
@@ -253,9 +258,9 @@ public class Gala.HideTracker : Object {
253258
}
254259
}
255260

256-
private void trigger_show () {
261+
private void trigger_show (GestureTracker gesture_tracker, bool with_gesture) {
257262
reset_hide_timeout ();
258-
show ();
263+
show (gesture_tracker, with_gesture);
259264
}
260265

261266
private bool check_valid_gesture () {
@@ -281,7 +286,7 @@ public class Gala.HideTracker : Object {
281286

282287
if (delta_y < 0) { // Only allow swipes upwards
283288
panel.window.focus (pan_action.get_last_event (0).get_time ());
284-
trigger_show ();
289+
trigger_show (default_gesture_tracker, false);
285290
}
286291

287292
return false;
@@ -325,7 +330,7 @@ public class Gala.HideTracker : Object {
325330
int.MAX
326331
);
327332

328-
barrier.trigger.connect (trigger_show);
333+
barrier.trigger.connect (() => trigger_show (default_gesture_tracker, false));
329334
}
330335

331336
#if HAS_MUTTER45
@@ -346,6 +351,6 @@ public class Gala.HideTracker : Object {
346351
int.MAX
347352
);
348353

349-
barrier.trigger.connect (trigger_show);
354+
barrier.trigger.connect (() => trigger_show (default_gesture_tracker, false));
350355
}
351356
}

src/ShellClients/PanelClone.vala

Lines changed: 22 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,10 @@ public class Gala.PanelClone : Object {
1818
set {
1919
if (value == NEVER) {
2020
hide_tracker = null;
21-
show ();
21+
show (default_gesture_tracker, false);
2222
return;
2323
} else if (hide_tracker == null) {
24-
hide_tracker = new HideTracker (wm.get_display (), panel);
24+
hide_tracker = new HideTracker (wm.get_display (), panel, default_gesture_tracker);
2525
hide_tracker.hide.connect (hide);
2626
hide_tracker.show.connect (show);
2727
}
@@ -32,100 +32,56 @@ public class Gala.PanelClone : Object {
3232

3333
public bool panel_hidden { get; private set; default = true; }
3434

35-
private SafeWindowClone clone;
3635
private Meta.WindowActor actor;
3736

37+
private GestureTracker default_gesture_tracker;
38+
private GestureTracker last_gesture_tracker;
39+
3840
private HideTracker? hide_tracker;
3941

4042
public PanelClone (WindowManager wm, PanelWindow panel) {
4143
Object (wm: wm, panel: panel);
4244
}
4345

4446
construct {
45-
clone = new SafeWindowClone (panel.window, true);
46-
wm.ui_group.add_child (clone);
47+
last_gesture_tracker = default_gesture_tracker = new GestureTracker (ANIMATION_DURATION, ANIMATION_DURATION);
4748

4849
actor = (Meta.WindowActor) panel.window.get_compositor_private ();
49-
// WindowActor position and Window position aren't necessarily the same.
50-
// The clone needs the actor position
51-
actor.notify["x"].connect (update_clone_position);
52-
actor.notify["y"].connect (update_clone_position);
53-
// Actor visibility might be changed by something else e.g. workspace switch
54-
// but we want to keep it in sync with us
55-
actor.notify["visible"].connect (update_visible);
5650

5751
notify["panel-hidden"].connect (() => {
58-
update_visible ();
5952
// When hidden changes schedule an update to make sure it's actually
6053
// correct since things might have changed during the animation
6154
if (hide_tracker != null) {
6255
hide_tracker.schedule_update ();
6356
}
6457
});
6558

66-
// Make sure the actor is visible once it's focused FIXME: better event not only focused
67-
// https://github.com/elementary/gala/issues/2080
68-
panel.window.focused.connect (update_visible);
69-
70-
update_visible ();
71-
update_clone_position ();
72-
7359
Idle.add_once (() => {
7460
if (hide_mode == NEVER) {
75-
show ();
61+
show (default_gesture_tracker, false);
7662
} else {
7763
hide_tracker.schedule_update ();
7864
}
7965
});
8066
}
8167

82-
private void update_visible () {
83-
actor.visible = !panel_hidden;
84-
85-
if (actor.visible && !wm.get_display ().get_monitor_in_fullscreen (panel.window.get_monitor ())) {
86-
// The actor has just been revealed, make sure it's at the top
87-
// https://github.com/elementary/gala/issues/2080
88-
actor.get_parent ().set_child_above_sibling (actor, null);
89-
}
90-
}
91-
92-
private void update_clone_position () {
93-
clone.set_position (calculate_clone_x (panel_hidden), calculate_clone_y (panel_hidden));
94-
}
95-
96-
private float calculate_clone_x (bool hidden) {
97-
switch (panel.anchor) {
98-
case TOP:
99-
case BOTTOM:
100-
return actor.x;
101-
default:
102-
return 0;
103-
}
104-
}
105-
106-
private float calculate_clone_y (bool hidden) {
68+
private float calculate_y (bool hidden) {
10769
switch (panel.anchor) {
10870
case TOP:
109-
return hidden ? actor.y - actor.height : actor.y;
71+
return hidden ? -actor.height : 0;
11072
case BOTTOM:
111-
return hidden ? actor.y + actor.height : actor.y;
73+
return hidden ? actor.height : 0;
11274
default:
11375
return 0;
11476
}
11577
}
11678

117-
private int get_animation_duration () {
118-
var fullscreen = wm.get_display ().get_monitor_in_fullscreen (panel.window.get_monitor ());
119-
var should_animate = AnimationsSettings.get_enable_animations () && !wm.workspace_view.is_opened () && !fullscreen;
120-
return should_animate ? ANIMATION_DURATION : 0;
121-
}
122-
123-
private void hide () {
124-
if (panel_hidden) {
79+
private void hide (GestureTracker gesture_tracker, bool with_gesture) {
80+
if (panel_hidden || last_gesture_tracker.recognizing) {
12581
return;
12682
}
12783

128-
panel_hidden = true;
84+
last_gesture_tracker = gesture_tracker;
12985

13086
if (!Meta.Util.is_wayland_compositor ()) {
13187
Utils.x11_set_window_pass_through (panel.window);
@@ -136,39 +92,24 @@ public class Gala.PanelClone : Object {
13692
return;
13793
}
13894

139-
clone.visible = true;
95+
new GesturePropertyTransition (actor, gesture_tracker, "translation-y", null, calculate_y (true)).start (with_gesture);
14096

141-
clone.save_easing_state ();
142-
clone.set_easing_mode (Clutter.AnimationMode.EASE_OUT_QUAD);
143-
clone.set_easing_duration (get_animation_duration ());
144-
clone.y = calculate_clone_y (true);
145-
clone.restore_easing_state ();
97+
gesture_tracker.add_success_callback (with_gesture, () => panel_hidden = true);
14698
}
14799

148-
private void show () {
149-
if (!panel_hidden) {
100+
private void show (GestureTracker gesture_tracker, bool with_gesture) {
101+
if (!panel_hidden || last_gesture_tracker.recognizing) {
150102
return;
151103
}
152104

105+
last_gesture_tracker = gesture_tracker;
106+
153107
if (!Meta.Util.is_wayland_compositor ()) {
154108
Utils.x11_unset_window_pass_through (panel.window);
155109
}
156110

157-
clone.save_easing_state ();
158-
clone.set_easing_mode (Clutter.AnimationMode.EASE_OUT_QUAD);
159-
clone.set_easing_duration (get_animation_duration ());
160-
clone.y = calculate_clone_y (false);
161-
clone.restore_easing_state ();
162-
163-
unowned var y_transition = clone.get_transition ("y");
164-
if (y_transition != null) {
165-
y_transition.completed.connect (() => {
166-
clone.visible = false;
167-
panel_hidden = false;
168-
});
169-
} else {
170-
clone.visible = false;
171-
panel_hidden = false;
172-
}
111+
new GesturePropertyTransition (actor, gesture_tracker, "translation-y", null, calculate_y (false)).start (with_gesture);
112+
113+
gesture_tracker.add_success_callback (with_gesture, () => panel_hidden = false);
173114
}
174115
}

0 commit comments

Comments
 (0)