From 6064cd4a8a1a1e879840d48bd5065ca3f5d99651 Mon Sep 17 00:00:00 2001 From: Leonhard Kargl Date: Wed, 16 Oct 2024 16:50:10 +0200 Subject: [PATCH] Use pan backend for dock reveal --- src/ShellClients/HideTracker.vala | 31 ++++++++++++++-- src/ShellClients/PanelClone.vala | 60 ++++++++++++++++++++++--------- src/ShellClients/PanelWindow.vala | 6 ++-- 3 files changed, 75 insertions(+), 22 deletions(-) diff --git a/src/ShellClients/HideTracker.vala b/src/ShellClients/HideTracker.vala index ef8d29d2..50997ce0 100644 --- a/src/ShellClients/HideTracker.vala +++ b/src/ShellClients/HideTracker.vala @@ -9,12 +9,14 @@ public class Gala.HideTracker : Object { private const uint UPDATE_TIMEOUT = 200; public signal void hide (); - public signal void show (); + public signal void show (GestureTracker? with_gesture_tracker); public Meta.Display display { get; construct; } public unowned PanelWindow panel { get; construct; } public Pantheon.Desktop.HideMode hide_mode { get; set; default = NEVER; } + private GestureTracker gesture_tracker; + private bool hovered = false; private bool overlap = false; @@ -60,6 +62,12 @@ public class Gala.HideTracker : Object { }); display.get_workspace_manager ().active_workspace_changed.connect (schedule_update); + + var size = new Utils.Size.actor_tracking ((Clutter.Actor) panel.window.get_compositor_private ()); + + gesture_tracker = new GestureTracker (PanelClone.ANIMATION_DURATION, PanelClone.ANIMATION_DURATION); + gesture_tracker.enable_pan (display.get_stage (), size); + gesture_tracker.on_gesture_detected.connect (check_valid_gesture); } //Can be removed with mutter > 45 @@ -181,7 +189,7 @@ public class Gala.HideTracker : Object { hovered = window_has_pointer (); #endif - if (should_hide && !hovered) { + if (should_hide && !hovered && !panel.window.has_focus ()) { // Don't hide if we have transients, e.g. an open popover, dialog, etc. var has_transients = false; panel.window.foreach_transient (() => { @@ -195,7 +203,24 @@ public class Gala.HideTracker : Object { hide (); } else { - show (); + show (null); } } + + private bool check_valid_gesture (Gesture gesture) { + warning ("DETECTED"); + if (panel.anchor != BOTTOM) { + debug ("Swipe to reveal is currently only supported for bottom anchors"); + return false; + } + + var monitor_geom = display.get_monitor_geometry (panel.window.get_monitor ()); + if ((gesture.origin_y - monitor_geom.y - monitor_geom.height).abs () < 50) { // Only start if the gesture starts near the bottom of the monitor + show (gesture_tracker); + panel.window.focus (Gdk.CURRENT_TIME); + return true; + } + + return false; + } } diff --git a/src/ShellClients/PanelClone.vala b/src/ShellClients/PanelClone.vala index 77b40a50..6467467e 100644 --- a/src/ShellClients/PanelClone.vala +++ b/src/ShellClients/PanelClone.vala @@ -6,7 +6,7 @@ */ public class Gala.PanelClone : Object { - private const int ANIMATION_DURATION = 250; + public const int ANIMATION_DURATION = 250; public WindowManager wm { get; construct; } public unowned PanelWindow panel { get; construct; } @@ -32,7 +32,7 @@ public class Gala.PanelClone : Object { public bool panel_hidden { get; private set; default = true; } - private SafeWindowClone clone; + public SafeWindowClone clone; private Meta.WindowActor actor; private HideTracker? hide_tracker; @@ -111,10 +111,12 @@ public class Gala.PanelClone : Object { } private void hide () { - if (panel_hidden) { + if (panel_hidden || animating) { return; } + animating = true; + panel_hidden = true; if (panel.anchor != TOP && panel.anchor != BOTTOM) { @@ -129,25 +131,51 @@ public class Gala.PanelClone : Object { clone.set_easing_duration (get_animation_duration ()); clone.y = calculate_clone_y (true); clone.restore_easing_state (); + + animating = false; } - public void show () { - if (!panel_hidden) { + private bool animating = false; + public void show (GestureTracker? with_gesture_tracker = null) { + if (!panel_hidden || animating) { return; } - var animation_duration = get_animation_duration (); + animating = true; - clone.save_easing_state (); - clone.set_easing_mode (Clutter.AnimationMode.EASE_OUT_QUAD); - clone.set_easing_duration (animation_duration); - clone.y = calculate_clone_y (false); - clone.restore_easing_state (); + var initial_y = clone.y; + var target_y = calculate_clone_y (false); - Timeout.add (animation_duration, () => { - clone.visible = false; - panel_hidden = false; - return Source.REMOVE; - }); + GestureTracker.OnUpdate on_update = (percentage) => { + var value = GestureTracker.animation_value (initial_y, target_y, percentage, true); + clone.y = value; + }; + + GestureTracker.OnEnd on_end = (percentage, cancel_action, calculated_duration) => { + if (cancel_action) { + animating = false; + hide (); + return; + } + + clone.save_easing_state (); + clone.set_easing_mode (Clutter.AnimationMode.EASE_OUT_QUAD); + clone.set_easing_duration (calculated_duration); + clone.y = calculate_clone_y (false); + clone.restore_easing_state (); + + Timeout.add (calculated_duration, () => { + clone.visible = false; + panel_hidden = false; + animating = false; + return Source.REMOVE; + }); + }; + + if (with_gesture_tracker != null) { + with_gesture_tracker.connect_handlers (null, (owned) on_update, (owned) on_end); + } else { + on_end (1, false, get_animation_duration ()); + } } } diff --git a/src/ShellClients/PanelWindow.vala b/src/ShellClients/PanelWindow.vala index 6e4f1c7a..9de75eeb 100644 --- a/src/ShellClients/PanelWindow.vala +++ b/src/ShellClients/PanelWindow.vala @@ -19,7 +19,7 @@ public class Gala.PanelWindow : Object { private Barrier? barrier; - private PanelClone clone; + public PanelClone clone; private uint idle_move_id = 0; @@ -247,7 +247,7 @@ public class Gala.PanelWindow : Object { int.MAX ); - barrier.trigger.connect (clone.show); + barrier.trigger.connect (() => clone.show ()); } #if HAS_MUTTER45 @@ -268,6 +268,6 @@ public class Gala.PanelWindow : Object { int.MAX ); - barrier.trigger.connect (clone.show); + barrier.trigger.connect (() => clone.show ()); } }