Skip to content

Commit

Permalink
ShellClients: Use translation y instead of clone and gesturetransitio…
Browse files Browse the repository at this point in the history
…n for animation
  • Loading branch information
leolost2605 committed Dec 25, 2024
1 parent 145a3eb commit 4fd5c53
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 101 deletions.
21 changes: 21 additions & 0 deletions src/Gestures/GestureTracker.vala
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ public class Gala.GestureTracker : Object {
*/
public bool enabled { get; set; default = true; }

public bool recognizing { get; private set; }

/**
* Emitted when a new gesture is detected.
* This should only be used to determine whether the gesture should be handled. This shouldn't
Expand Down Expand Up @@ -193,6 +195,23 @@ public class Gala.GestureTracker : Object {
}
}

/**
* Connects a callback that will only be called if != 0 completions were made.
* If with_gesture is false it will be called immediately, otherwise once {@link on_end} is emitted.
*/
public void add_success_callback (bool with_gesture, owned OnEnd callback) {
if (!with_gesture) {
callback (1, 1, min_animation_duration);
} else {
ulong handler_id = on_end.connect ((percentage, completions, duration) => {
if (completions != 0) {
callback (percentage, completions, duration);
}
});
handlers.add (handler_id);
}
}

private void disconnect_all_handlers () {
foreach (var handler in handlers) {
disconnect (handler);
Expand Down Expand Up @@ -242,6 +261,7 @@ public class Gala.GestureTracker : Object {
on_begin (percentage);
}

recognizing = true;
previous_percentage = percentage;
previous_time = elapsed_time;
}
Expand Down Expand Up @@ -283,6 +303,7 @@ public class Gala.GestureTracker : Object {
}

disconnect_all_handlers ();
recognizing = false;
previous_percentage = 0;
previous_time = 0;
percentage_delta = 0;
Expand Down
45 changes: 25 additions & 20 deletions src/ShellClients/HideTracker.vala
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,12 @@ public class Gala.HideTracker : Object {
private const int UPDATE_TIMEOUT = 200;
private const int HIDE_DELAY = 500;

public signal void hide ();
public signal void show ();
public signal void hide (GestureTracker gesture_tracker, bool with_gesture);
public signal void show (GestureTracker gesture_tracker, bool with_gesture);

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

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

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

public HideTracker (Meta.Display display, PanelWindow panel) {
Object (display: display, panel: panel);
public HideTracker (Meta.Display display, PanelWindow panel, GestureTracker default_gesture_tracker) {
Object (display: display, panel: panel, default_gesture_tracker: default_gesture_tracker);
}

~HideTracker () {
Expand Down Expand Up @@ -146,13 +147,13 @@ public class Gala.HideTracker : Object {
}

update_timeout_id = Timeout.add (UPDATE_TIMEOUT, () => {
update_overlap ();
update_overlap (default_gesture_tracker, false);
update_timeout_id = 0;
return Source.REMOVE;
});
}

private void update_overlap () {
public void update_overlap (GestureTracker gesture_tracker, bool with_gesture) {
overlap = false;
focus_overlap = false;
focus_maximized_overlap = false;
Expand Down Expand Up @@ -185,25 +186,25 @@ public class Gala.HideTracker : Object {
focus_maximized_overlap = VERTICAL in window.get_maximized ();
}

update_hidden ();
update_hidden (gesture_tracker, with_gesture);
}

private void update_hidden () {
private void update_hidden (GestureTracker gesture_tracker, bool with_gesture) {
switch (hide_mode) {
case MAXIMIZED_FOCUS_WINDOW:
toggle_display (focus_maximized_overlap);
toggle_display (focus_maximized_overlap, gesture_tracker, with_gesture);
break;

case OVERLAPPING_FOCUS_WINDOW:
toggle_display (focus_overlap);
toggle_display (focus_overlap, gesture_tracker, with_gesture);
break;

case OVERLAPPING_WINDOW:
toggle_display (overlap);
toggle_display (overlap, gesture_tracker, with_gesture);
break;

case ALWAYS:
toggle_display (true);
toggle_display (true, gesture_tracker, with_gesture);
break;

default:
Expand All @@ -212,7 +213,11 @@ public class Gala.HideTracker : Object {
}
}

private void toggle_display (bool should_hide) {
private void toggle_display (bool should_hide, GestureTracker gesture_tracker, bool with_gesture) {
if (display.get_monitor_in_fullscreen (panel.window.get_monitor ())) {
return;
}

#if HAS_MUTTER45
hovered = panel.window.has_pointer ();
#else
Expand All @@ -222,7 +227,7 @@ public class Gala.HideTracker : Object {
if (should_hide && !hovered && !panel.window.has_focus ()) {
trigger_hide ();
} else {
trigger_show ();
trigger_show (gesture_tracker, with_gesture);
}
}

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

hide_timeout_id = Timeout.add_once (HIDE_DELAY, () => {
hide ();
hide (default_gesture_tracker, false);
hide_timeout_id = 0;
});
}
Expand All @@ -253,9 +258,9 @@ public class Gala.HideTracker : Object {
}
}

private void trigger_show () {
private void trigger_show (GestureTracker gesture_tracker, bool with_gesture) {
reset_hide_timeout ();
show ();
show (gesture_tracker, with_gesture);
}

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

if (delta_y < 0) { // Only allow swipes upwards
panel.window.focus (pan_action.get_last_event (0).get_time ());
trigger_show ();
trigger_show (default_gesture_tracker, false);
}

return false;
Expand Down Expand Up @@ -325,7 +330,7 @@ public class Gala.HideTracker : Object {
int.MAX
);

barrier.trigger.connect (trigger_show);
barrier.trigger.connect (() => trigger_show (default_gesture_tracker, false));
}

#if HAS_MUTTER45
Expand All @@ -346,6 +351,6 @@ public class Gala.HideTracker : Object {
int.MAX
);

barrier.trigger.connect (trigger_show);
barrier.trigger.connect (() => trigger_show (default_gesture_tracker, false));
}
}
103 changes: 22 additions & 81 deletions src/ShellClients/PanelClone.vala
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ public class Gala.PanelClone : Object {
set {
if (value == NEVER) {
hide_tracker = null;
show ();
show (default_gesture_tracker, false);
return;
} else if (hide_tracker == null) {
hide_tracker = new HideTracker (wm.get_display (), panel);
hide_tracker = new HideTracker (wm.get_display (), panel, default_gesture_tracker);
hide_tracker.hide.connect (hide);
hide_tracker.show.connect (show);
}
Expand All @@ -32,100 +32,56 @@ public class Gala.PanelClone : Object {

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

private SafeWindowClone clone;
private Meta.WindowActor actor;

private GestureTracker default_gesture_tracker;
private GestureTracker last_gesture_tracker;

private HideTracker? hide_tracker;

public PanelClone (WindowManager wm, PanelWindow panel) {
Object (wm: wm, panel: panel);
}

construct {
clone = new SafeWindowClone (panel.window, true);
wm.ui_group.add_child (clone);
last_gesture_tracker = default_gesture_tracker = new GestureTracker (ANIMATION_DURATION, ANIMATION_DURATION);

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

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

// Make sure the actor is visible once it's focused FIXME: better event not only focused
// https://github.com/elementary/gala/issues/2080
panel.window.focused.connect (update_visible);

update_visible ();
update_clone_position ();

Idle.add_once (() => {
if (hide_mode == NEVER) {
show ();
show (default_gesture_tracker, false);
} else {
hide_tracker.schedule_update ();
}
});
}

private void update_visible () {
actor.visible = !panel_hidden;

if (actor.visible && !wm.get_display ().get_monitor_in_fullscreen (panel.window.get_monitor ())) {
// The actor has just been revealed, make sure it's at the top
// https://github.com/elementary/gala/issues/2080
actor.get_parent ().set_child_above_sibling (actor, null);
}
}

private void update_clone_position () {
clone.set_position (calculate_clone_x (panel_hidden), calculate_clone_y (panel_hidden));
}

private float calculate_clone_x (bool hidden) {
switch (panel.anchor) {
case TOP:
case BOTTOM:
return actor.x;
default:
return 0;
}
}

private float calculate_clone_y (bool hidden) {
private float calculate_y (bool hidden) {
switch (panel.anchor) {
case TOP:
return hidden ? actor.y - actor.height : actor.y;
return hidden ? -actor.height : 0;
case BOTTOM:
return hidden ? actor.y + actor.height : actor.y;
return hidden ? actor.height : 0;
default:
return 0;
}
}

private int get_animation_duration () {
var fullscreen = wm.get_display ().get_monitor_in_fullscreen (panel.window.get_monitor ());
var should_animate = AnimationsSettings.get_enable_animations () && !wm.workspace_view.is_opened () && !fullscreen;
return should_animate ? ANIMATION_DURATION : 0;
}

private void hide () {
if (panel_hidden) {
private void hide (GestureTracker gesture_tracker, bool with_gesture) {
if (panel_hidden || last_gesture_tracker.recognizing) {
return;
}

panel_hidden = true;
last_gesture_tracker = gesture_tracker;

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

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

clone.save_easing_state ();
clone.set_easing_mode (Clutter.AnimationMode.EASE_OUT_QUAD);
clone.set_easing_duration (get_animation_duration ());
clone.y = calculate_clone_y (true);
clone.restore_easing_state ();
gesture_tracker.add_success_callback (with_gesture, () => panel_hidden = true);
}

private void show () {
if (!panel_hidden) {
private void show (GestureTracker gesture_tracker, bool with_gesture) {
if (!panel_hidden || last_gesture_tracker.recognizing) {
return;
}

last_gesture_tracker = gesture_tracker;

if (!Meta.Util.is_wayland_compositor ()) {
Utils.x11_unset_window_pass_through (panel.window);
}

clone.save_easing_state ();
clone.set_easing_mode (Clutter.AnimationMode.EASE_OUT_QUAD);
clone.set_easing_duration (get_animation_duration ());
clone.y = calculate_clone_y (false);
clone.restore_easing_state ();

unowned var y_transition = clone.get_transition ("y");
if (y_transition != null) {
y_transition.completed.connect (() => {
clone.visible = false;
panel_hidden = false;
});
} else {
clone.visible = false;
panel_hidden = false;
}
new GesturePropertyTransition (actor, gesture_tracker, "translation-y", null, calculate_y (false)).start (with_gesture);

gesture_tracker.add_success_callback (with_gesture, () => panel_hidden = false);
}
}

0 comments on commit 4fd5c53

Please sign in to comment.