quick-settings: Handle interrupted menu animations

If the menu is closed while it is being opened, we should skip the next
animation in the chain. Similarly, if a menu is opened while it is being
closed, we should continue the animation from the previous state instead
of resetting height to 0.

Closes: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/5843
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2481>
This commit is contained in:
Dylan McCall 2022-09-09 11:34:07 -07:00 committed by Dylan McCall
parent b7e42952dc
commit babf69f6ba

View File

@ -366,6 +366,7 @@ class QuickToggleMenu extends PopupMenu.PopupMenuBase {
reactive: true, reactive: true,
x_expand: true, x_expand: true,
y_expand: false, y_expand: false,
height: 0,
constraints, constraints,
}); });
this.actor._delegate = this; this.actor._delegate = this;
@ -446,17 +447,19 @@ class QuickToggleMenu extends PopupMenu.PopupMenuBase {
this.actor.show(); this.actor.show();
this.isOpen = true; this.isOpen = true;
const previousHeight = this.actor.height;
this.actor.height = -1; this.actor.height = -1;
const [targetHeight] = this.actor.get_preferred_height(-1); const [targetHeight] = this.actor.get_preferred_height(-1);
this.actor.height = previousHeight;
const distance = Math.abs(targetHeight - previousHeight);
const duration = animate !== PopupAnimation.NONE const duration = animate !== PopupAnimation.NONE
? POPUP_ANIMATION_TIME / 2 ? POPUP_ANIMATION_TIME / 2
: 0; : 0;
this.actor.height = 0;
this.box.opacity = 0; this.box.opacity = 0;
this.actor.ease({ this.actor.ease({
duration, duration: duration * (distance / targetHeight),
height: targetHeight, height: targetHeight,
onComplete: () => { onComplete: () => {
this.box.ease({ this.box.ease({
@ -473,12 +476,13 @@ class QuickToggleMenu extends PopupMenu.PopupMenuBase {
if (!this.isOpen) if (!this.isOpen)
return; return;
const {opacity} = this.box;
const duration = animate !== PopupAnimation.NONE const duration = animate !== PopupAnimation.NONE
? POPUP_ANIMATION_TIME / 2 ? POPUP_ANIMATION_TIME / 2
: 0; : 0;
this.box.ease({ this.box.ease({
duration, duration: duration * (opacity / 255),
opacity: 0, opacity: 0,
onComplete: () => { onComplete: () => {
this.actor.ease({ this.actor.ease({