Skip to content

Commit

Permalink
Introduce shell group, future proof
Browse files Browse the repository at this point in the history
  • Loading branch information
leolost2605 committed Dec 22, 2024
1 parent 92793a9 commit a8f0b50
Show file tree
Hide file tree
Showing 8 changed files with 109 additions and 106 deletions.
16 changes: 8 additions & 8 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 (int completions);
public delegate void DoneCallback ();

/**
* The actor whose property will be animated.
Expand Down Expand Up @@ -100,13 +100,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 (0);
finish ();
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 (0);
finish ();
return;
}

Expand Down Expand Up @@ -152,9 +152,9 @@ public class Gala.GesturePropertyTransition : Object {

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

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

private void finish (int completions, bool callback = true) {
if (callback && done_callback != null) {
done_callback (completions);
private void finish () {
if (done_callback != null) {
done_callback ();
}

unref ();
Expand Down
17 changes: 17 additions & 0 deletions src/Gestures/GestureTracker.vala
Original file line number Diff line number Diff line change
Expand Up @@ -195,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
17 changes: 17 additions & 0 deletions src/Gestures/ManualBackend.vala
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
* Copyright 2024 elementary, Inc. (https://elementary.io)
* SPDX-License-Identifier: GPL-3.0-or-later
*
* Authored by: Leonhard Kargl <[email protected]>
*/

public class Gala.ManualBackend : Object, GestureBackend {
public void start_action (GestureAction action, uint32 timestamp) {
if (on_gesture_detected (new Gesture () {
action = action
}, timestamp)) {
on_begin (0, timestamp);
on_end (1, timestamp);
}
}
}
82 changes: 18 additions & 64 deletions src/ShellClients/PanelClone.vala
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
public class Gala.PanelClone : Object {
private const int ANIMATION_DURATION = 250;

public WindowManager wm { get; construct; }
public WindowManagerGala wm { get; construct; }
public unowned PanelWindow panel { get; construct; }

public Pantheon.Desktop.HideMode hide_mode {
Expand All @@ -30,52 +30,35 @@ public class Gala.PanelClone : Object {
}
}

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

private SafeWindowClone clone;
private Meta.WindowActor actor;

private bool panel_hidden = false;

private GestureTracker default_gesture_tracker;
private GestureTracker? last_gesture_tracker;
private GestureTracker last_gesture_tracker;
private bool force_hide = false;

private HideTracker? hide_tracker;

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

construct {
default_gesture_tracker = new GestureTracker (ANIMATION_DURATION, ANIMATION_DURATION);

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);
actor.get_parent ().remove_child (actor);
wm.shell_group.add_child (actor);

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 (default_gesture_tracker, false);
Expand All @@ -85,50 +68,24 @@ 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) {
private float calculate_y (bool hidden) {
switch (panel.anchor) {
case TOP:
return hidden ? -actor.height : 0;
case BOTTOM:
return actor.x;
default:
return 0;
}
}

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

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

last_gesture_tracker = gesture_tracker;

panel_hidden = true;

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

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

new GesturePropertyTransition (clone, gesture_tracker, "y", null, calculate_clone_y (true)).start (with_gesture);
gesture_tracker.add_success_callback (with_gesture, () => panel_hidden = true);
}

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

Expand All @@ -154,12 +111,9 @@ public class Gala.PanelClone : Object {
Utils.x11_unset_window_pass_through (panel.window);
}

new GesturePropertyTransition (clone, gesture_tracker, "y", null, calculate_clone_y (false)).start (with_gesture, (completions) => {
if (completions > 0) {
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);
}

public void set_force_hide (bool force_hide, GestureTracker gesture_tracker, bool with_gesture) {
Expand Down
4 changes: 2 additions & 2 deletions src/ShellClients/PanelWindow.vala
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
public class Gala.PanelWindow : Object {
private static HashTable<Meta.Window, Meta.Strut?> window_struts = new HashTable<Meta.Window, Meta.Strut?> (null, null);

public WindowManager wm { get; construct; }
public WindowManagerGala wm { get; construct; }
public Meta.Window window { get; construct; }
public Pantheon.Desktop.Anchor anchor { get; construct set; }

Expand All @@ -19,7 +19,7 @@ public class Gala.PanelWindow : Object {
private int width = -1;
private int height = -1;

public PanelWindow (WindowManager wm, Meta.Window window, Pantheon.Desktop.Anchor anchor) {
public PanelWindow (WindowManagerGala wm, Meta.Window window, Pantheon.Desktop.Anchor anchor) {
Object (wm: wm, window: window, anchor: anchor);
}

Expand Down
6 changes: 3 additions & 3 deletions src/ShellClients/ShellClientsManager.vala
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
public class Gala.ShellClientsManager : Object {
private static ShellClientsManager instance;

public static void init (WindowManager wm) {
public static void init (WindowManagerGala wm) {
if (instance != null) {
return;
}
Expand All @@ -20,15 +20,15 @@ public class Gala.ShellClientsManager : Object {
return instance;
}

public WindowManager wm { get; construct; }
public WindowManagerGala wm { get; construct; }

private NotificationsClient notifications_client;
private ManagedClient[] protocol_clients = {};

private GLib.HashTable<Meta.Window, PanelWindow> panel_windows = new GLib.HashTable<Meta.Window, PanelWindow> (null, null);
private GLib.HashTable<Meta.Window, WindowPositioner> positioned_windows = new GLib.HashTable<Meta.Window, WindowPositioner> (null, null);

private ShellClientsManager (WindowManager wm) {
private ShellClientsManager (WindowManagerGala wm) {
Object (wm: wm);
}

Expand Down
45 changes: 27 additions & 18 deletions src/Widgets/MultitaskingView.vala
Original file line number Diff line number Diff line change
Expand Up @@ -676,29 +676,38 @@ namespace Gala {
ShellClientsManager.get_instance ().set_force_hide_panels (false, multitasking_gesture_tracker, with_gesture);
}

// The callback needs to run at the same frame as the others (e.g. PanelClone) so we can't do a simple Timeout here
// The actual transition does nothing here, since the opacity just stays at 255
new GesturePropertyTransition (this, multitasking_gesture_tracker, "opacity", null, 255u).start (with_gesture, (completions) => {
if (!opening) {
foreach (var container in window_containers_monitors) {
container.visible = false;
}
GestureTracker.OnEnd on_animation_end = (percentage, completions) => {
var animation_duration = completions == 0 ? 0 : ANIMATION_DURATION;
Timeout.add (animation_duration, () => {
if (!opening) {
foreach (var container in window_containers_monitors) {
container.visible = false;
}

hide ();
hide ();

wm.background_group.show ();
wm.window_group.show ();
wm.top_window_group.show ();
wm.background_group.show ();
wm.window_group.show ();
wm.top_window_group.show ();

wm.pop_modal (modal_proxy);
}
wm.pop_modal (modal_proxy);
}

animating = false;
animating = false;

if (completions == 0) {
toggle (false, true);
}
});
if (completions == 0) {
toggle (false, true);
}

return Source.REMOVE;
});
};

if (!with_gesture) {
on_animation_end (1, 1, 0);
} else {
multitasking_gesture_tracker.connect_handlers (null, null, (owned) on_animation_end);
}
}

private bool keybinding_filter (Meta.KeyBinding binding) {
Expand Down
Loading

0 comments on commit a8f0b50

Please sign in to comment.