diff --git a/src/Gestures/GestureTracker.vala b/src/Gestures/GestureTracker.vala index 9ca525bb9..89b684d0d 100644 --- a/src/Gestures/GestureTracker.vala +++ b/src/Gestures/GestureTracker.vala @@ -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 @@ -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); @@ -242,6 +261,7 @@ public class Gala.GestureTracker : Object { on_begin (percentage); } + recognizing = true; previous_percentage = percentage; previous_time = elapsed_time; } @@ -283,6 +303,7 @@ public class Gala.GestureTracker : Object { } disconnect_all_handlers (); + recognizing = false; previous_percentage = 0; previous_time = 0; percentage_delta = 0; diff --git a/src/ShellClients/PanelClone.vala b/src/ShellClients/PanelClone.vala index 6a32b101f..0af26758c 100644 --- a/src/ShellClients/PanelClone.vala +++ b/src/ShellClients/PanelClone.vala @@ -32,9 +32,10 @@ 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 HideTracker? hide_tracker; public PanelClone (WindowManager wm, PanelWindow panel) { @@ -42,20 +43,11 @@ public class Gala.PanelClone : Object { } construct { - clone = new SafeWindowClone (panel.window, true); - wm.ui_group.add_child (clone); + 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) { @@ -63,13 +55,6 @@ public class Gala.PanelClone : Object { } }); - // 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 (); @@ -79,54 +64,22 @@ public class Gala.PanelClone : Object { }); } - 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) { + if (panel_hidden || default_gesture_tracker.recognizing) { return; } - panel_hidden = true; - if (!Meta.Util.is_wayland_compositor ()) { Utils.x11_set_window_pass_through (panel.window); } @@ -136,17 +89,13 @@ public class Gala.PanelClone : Object { return; } - clone.visible = true; + new GesturePropertyTransition (actor, default_gesture_tracker, "translation-y", null, calculate_y (true)).start (false); - 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 (); + default_gesture_tracker.add_success_callback (false, () => panel_hidden = true); } private void show () { - if (!panel_hidden) { + if (!panel_hidden || default_gesture_tracker.recognizing) { return; } @@ -154,21 +103,8 @@ public class Gala.PanelClone : Object { 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, default_gesture_tracker, "translation-y", null, calculate_y (false)).start (false); + + default_gesture_tracker.add_success_callback (false, () => panel_hidden = false); } }