Skip to content

Commit

Permalink
ShellClients: Allow force hiding all panels
Browse files Browse the repository at this point in the history
This is e.g. used by the multitasking view.
It also supports hiding with gesture
  • Loading branch information
leolost2605 committed Dec 8, 2024
1 parent 9d0e352 commit de12513
Show file tree
Hide file tree
Showing 7 changed files with 88 additions and 169 deletions.
14 changes: 7 additions & 7 deletions src/Gestures/GesturePropertyTransition.vala
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
* with easing without a gesture. Respects the enable animation setting.
*/
public class Gala.GesturePropertyTransition : Object {
public delegate void DoneCallback ();
public delegate void DoneCallback (bool cancel_action);

/**
* The actor whose property will be animated.
Expand Down Expand Up @@ -90,13 +90,13 @@ public class Gala.GesturePropertyTransition : Object {

if (actual_from_value.type () != current_value.type ()) {
warning ("from_value of type %s is not of the same type as the property %s which is %s. Can't animate.", from_value.type_name (), property, current_value.type_name ());
finish ();
finish (true);
return;
}

if (current_value.type () != to_value.type ()) {
warning ("to_value of type %s is not of the same type as the property %s which is %s. Can't animate.", to_value.type_name (), property, current_value.type_name ());
finish ();
finish (true);
return;
}

Expand All @@ -118,9 +118,9 @@ public class Gala.GesturePropertyTransition : Object {

unowned var transition = actor.get_transition (property);
if (transition == null) {
finish ();
finish (cancel_action);
} else {
transition.stopped.connect (finish);
transition.stopped.connect (() => finish (cancel_action));
}
};

Expand All @@ -147,9 +147,9 @@ public class Gala.GesturePropertyTransition : Object {
}
}

private void finish () {
private void finish (bool cancel_action) {
if (done_callback != null) {
done_callback ();
done_callback (cancel_action);
}

unref ();
Expand Down
4 changes: 4 additions & 0 deletions src/Gestures/GestureTracker.vala
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,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.
* If the receiving code needs to handle this gesture, it should call to connect_handlers to
Expand Down Expand Up @@ -212,6 +214,7 @@ public class Gala.GestureTracker : Object {
on_begin (percentage);
}

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

disconnect_all_handlers ();
recognizing = false;
previous_percentage = 0;
previous_time = 0;
percentage_delta = 0;
Expand Down
44 changes: 26 additions & 18 deletions src/ShellClients/HideTracker.vala
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,21 @@
*/

public class Gala.HideTracker : Object {
private const int ANIMATION_DURATION = 250;
private const int BARRIER_OFFSET = 50; // Allow hot corner trigger
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 Pantheon.Desktop.HideMode hide_mode { get; set; }

private Clutter.PanAction pan_action;
private GestureTracker gesture_tracker; // Placeholder that will replace pan_action once the pan_backend gets merged

private bool hovered = false;

Expand Down Expand Up @@ -79,6 +81,8 @@ public class Gala.HideTracker : Object {

display.get_workspace_manager ().active_workspace_changed.connect (schedule_update);

gesture_tracker = new GestureTracker (ANIMATION_DURATION, ANIMATION_DURATION);

pan_action = new Clutter.PanAction () {
n_touch_points = 1,
pan_axis = X_AXIS
Expand Down Expand Up @@ -146,13 +150,13 @@ public class Gala.HideTracker : Object {
}

update_timeout_id = Timeout.add (UPDATE_TIMEOUT, () => {
update_overlap ();
update_overlap (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 +189,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 +216,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 +230,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 +249,7 @@ public class Gala.HideTracker : Object {
}

hide_timeout_id = Timeout.add_once (HIDE_DELAY, () => {
hide ();
hide (gesture_tracker, false);
hide_timeout_id = 0;
});
}
Expand All @@ -253,9 +261,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 +289,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 (gesture_tracker, false);
}

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

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

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

barrier.trigger.connect (trigger_show);
barrier.trigger.connect (() => trigger_show (gesture_tracker, false));
}
}
67 changes: 36 additions & 31 deletions src/ShellClients/PanelClone.vala
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public class Gala.PanelClone : Object {
set {
if (value == NEVER) {
hide_tracker = null;
show ();
show (new GestureTracker (ANIMATION_DURATION, ANIMATION_DURATION), false);
return;
} else if (hide_tracker == null) {
hide_tracker = new HideTracker (wm.get_display (), panel);
Expand All @@ -35,6 +35,9 @@ public class Gala.PanelClone : Object {
private SafeWindowClone clone;
private Meta.WindowActor actor;

private GestureTracker? last_gesture_tracker;
private bool force_hide = false;

private HideTracker? hide_tracker;

public PanelClone (WindowManager wm, PanelWindow panel) {
Expand Down Expand Up @@ -72,7 +75,7 @@ public class Gala.PanelClone : Object {

Idle.add_once (() => {
if (hide_mode == NEVER) {
show ();
show (new GestureTracker (ANIMATION_DURATION, ANIMATION_DURATION), false);
} else {
hide_tracker.schedule_update ();
}
Expand Down Expand Up @@ -114,17 +117,13 @@ public class Gala.PanelClone : Object {
}
}

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 != null && last_gesture_tracker.recognizing) {
return;
}

last_gesture_tracker = gesture_tracker;

panel_hidden = true;

if (!Meta.Util.is_wayland_compositor ()) {
Expand All @@ -138,37 +137,43 @@ public class Gala.PanelClone : Object {

clone.visible = true;

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 ();
new GesturePropertyTransition (clone, gesture_tracker, "y", null, calculate_clone_y (true)).start (with_gesture);
}

private void show () {
if (!panel_hidden) {
private void show (GestureTracker gesture_tracker, bool with_gesture) {
if (!panel_hidden || force_hide || last_gesture_tracker != null && 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;
});
new GesturePropertyTransition (clone, gesture_tracker, "y", null, calculate_clone_y (false)).start (with_gesture, (cancel_action) => {
if (!cancel_action) {
// We need the small timeout because in the case that we're showing in sync with the multitasking view
// we have to make sure that we hide the clone after the multitasking view was already hidden otherwise
// it flickers because the actual window actors are hidden by the multitasking view
Timeout.add_once (10, () => {
force_hide = false;
clone.visible = false;
panel_hidden = false;
});
}
});
}

public void set_force_hide (bool force_hide, GestureTracker gesture_tracker, bool with_gesture) {
this.force_hide = force_hide;

if (force_hide) {
hide (gesture_tracker, with_gesture);
} else if (hide_mode == NEVER) {
show (gesture_tracker, with_gesture);
} else {
clone.visible = false;
panel_hidden = false;
hide_tracker.update_overlap (gesture_tracker, with_gesture);
}
}
}
4 changes: 4 additions & 0 deletions src/ShellClients/PanelWindow.vala
Original file line number Diff line number Diff line change
Expand Up @@ -143,4 +143,8 @@ public class Gala.PanelWindow : Object {
return TOP;
}
}

public void set_force_hide (bool force_hide, GestureTracker gesture_tracker, bool with_gesture) {
clone.set_force_hide (force_hide, gesture_tracker, with_gesture);
}
}
6 changes: 6 additions & 0 deletions src/ShellClients/ShellClientsManager.vala
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,12 @@ public class Gala.ShellClientsManager : Object {
return positioned;
}

public void set_force_hide_panels (bool force_hide, GestureTracker gesture_tracker, bool with_gesture) {
foreach (var panel in panel_windows.get_values ()) {
panel.set_force_hide (force_hide, gesture_tracker, with_gesture);
}
}

//X11 only
private void parse_mutter_hints (Meta.Window window) requires (!Meta.Util.is_wayland_compositor ()) {
if (window.mutter_hints == null) {
Expand Down
Loading

0 comments on commit de12513

Please sign in to comment.