Make startup animation use async functions throughout
During session startup, we have the following chain: LayoutManager._prepareStartupAnimation() `- LayoutManager._startupAnimation() `- LayoutManager._startupAnimationComplete() (a) | or `- LayoutManager._startupAnimationGreeter() (b) | or `- LayoutManager._startupAnimationSession() (c) `- Overview.runStartupAnimation() (d) `- OverviewActor.runStartupAnimation() (e) `- ControlsManager.runStartupAnimation() (f) Branch (b) calls LayoutManager._startupAnimationComplete() once the animation is complete. Branch (c) does the same, except that ControlsManager.runStartupAnimation() is an async function that awaits LayoutManager.ensureAllocation(). LayoutManager._prepareStartupAnimation() is an `async` function, and its caller catches & logs any error it raises. Previously, ControlsManager.runStartupAnimation() – (f) in the above diagram – was declared `async`, because it uses `await` internally, but also accepted a callback, which was called on successful completion of the function and the animation it triggers. If an exception is raised during execution of the function, its callback would never be called, and because the promise it implicitly returns is discarded, the exception would never be logged either. And, stepping a few levels up the call stack, the callback that LayoutManager._startupAnimationSession() (c) provided would never be called, and so LayoutManager._startupAnimationComplete() would never be called, meaning the cover pane that prevents input would never be removed and the session would be unusable. Remove the callback parameter from ControlsManager.runStartupAnimation() (f), and instead make it resolve in the case where the callback would previously have been called. Remove the callback parameter from OverviewActor.runStartupAnimation() (e) – it is just a wrapper around ControlsManager.runStartupAnimation(). Adjust Overview.runStartupAnimation() (d) accordingly: rather than passing a callback to OverviewActor.runStartupAnimation(), await its return and then proceed. There is a slight behaviour change here: previously, in the branch where this._syncGrab() is false, the callback would be called before calling this.hide(), whereas now this.hide() is called before the async function returns. Adjust LayoutManager._startupAnimationSession() and its siblings to be async, rather than each calling _startupAnimationComplete() directly. Finally, in _prepareStartupAnimation() await _startupAnimation() either succeeding or failing, and in either case call _startupAnimationComplete(), removing the cover pane that prevents all input. Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/3428>
This commit is contained in:
parent
acfa372d4f
commit
3d06134545
@ -763,39 +763,47 @@ export const LayoutManager = GObject.registerClass({
|
||||
else
|
||||
this.emit('startup-prepared');
|
||||
|
||||
this._startupAnimation();
|
||||
}
|
||||
|
||||
_startupAnimation() {
|
||||
if (Meta.is_restart())
|
||||
try {
|
||||
await this._startupAnimation();
|
||||
} finally {
|
||||
this._startupAnimationComplete();
|
||||
else if (Main.sessionMode.isGreeter)
|
||||
this._startupAnimationGreeter();
|
||||
else
|
||||
this._startupAnimationSession();
|
||||
}
|
||||
}
|
||||
|
||||
_startupAnimationGreeter() {
|
||||
async _startupAnimation() {
|
||||
if (Meta.is_restart())
|
||||
return;
|
||||
|
||||
if (Main.sessionMode.isGreeter)
|
||||
await this._startupAnimationGreeter();
|
||||
else
|
||||
await this._startupAnimationSession();
|
||||
}
|
||||
|
||||
async _startupAnimationGreeter() {
|
||||
await new Promise(resolve => {
|
||||
this.panelBox.ease({
|
||||
translation_y: 0,
|
||||
duration: STARTUP_ANIMATION_TIME,
|
||||
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
||||
onStopped: () => this._startupAnimationComplete(),
|
||||
onStopped: () => resolve(),
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
_startupAnimationSession() {
|
||||
const onStopped = () => this._startupAnimationComplete();
|
||||
async _startupAnimationSession() {
|
||||
if (Main.sessionMode.hasOverview) {
|
||||
Main.overview.runStartupAnimation(onStopped);
|
||||
await Main.overview.runStartupAnimation();
|
||||
} else {
|
||||
await new Promise(resolve => {
|
||||
this.uiGroup.ease({
|
||||
scale_x: 1,
|
||||
scale_y: 1,
|
||||
opacity: 255,
|
||||
duration: STARTUP_ANIMATION_TIME,
|
||||
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
||||
onStopped,
|
||||
onStopped: () => resolve(),
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -90,8 +90,8 @@ class OverviewActor extends St.BoxLayout {
|
||||
this._controls.animateFromOverview(callback);
|
||||
}
|
||||
|
||||
runStartupAnimation(callback) {
|
||||
this._controls.runStartupAnimation(callback);
|
||||
async runStartupAnimation() {
|
||||
await this._controls.runStartupAnimation();
|
||||
}
|
||||
|
||||
get dash() {
|
||||
@ -666,7 +666,7 @@ export class Overview extends Signals.EventEmitter {
|
||||
this._overview.controls.appDisplay.selectApp(id);
|
||||
}
|
||||
|
||||
runStartupAnimation(callback) {
|
||||
async runStartupAnimation() {
|
||||
Main.panel.style = 'transition-duration: 0ms;';
|
||||
|
||||
this._shown = true;
|
||||
@ -679,23 +679,19 @@ export class Overview extends Signals.EventEmitter {
|
||||
|
||||
this._changeShownState(OverviewShownState.SHOWING);
|
||||
|
||||
this._overview.runStartupAnimation(() => {
|
||||
await this._overview.runStartupAnimation();
|
||||
|
||||
// Overview got hidden during startup animation
|
||||
if (this._shownState !== OverviewShownState.SHOWING) {
|
||||
callback();
|
||||
if (this._shownState !== OverviewShownState.SHOWING)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this._syncGrab()) {
|
||||
callback();
|
||||
this.hide();
|
||||
return;
|
||||
}
|
||||
|
||||
Main.panel.style = null;
|
||||
this._changeShownState(OverviewShownState.SHOWN);
|
||||
callback();
|
||||
});
|
||||
}
|
||||
|
||||
getShowAppsButton() {
|
||||
|
@ -797,7 +797,7 @@ class ControlsManager extends St.Widget {
|
||||
this._stateAdjustment.gestureInProgress = false;
|
||||
}
|
||||
|
||||
async runStartupAnimation(callback) {
|
||||
async runStartupAnimation() {
|
||||
this._ignoreShowAppsButtonToggle = true;
|
||||
|
||||
this.prepareToEnterOverview();
|
||||
@ -839,14 +839,16 @@ class ControlsManager extends St.Widget {
|
||||
});
|
||||
|
||||
// The Dash rises from the bottom. This is the last animation to finish,
|
||||
// so run the callback there.
|
||||
// so resolve the promise there.
|
||||
this.dash.translation_y = this.dash.height + this.dash.margin_bottom;
|
||||
return new Promise(resolve => {
|
||||
this.dash.ease({
|
||||
translation_y: 0,
|
||||
delay: STARTUP_ANIMATION_TIME,
|
||||
duration: STARTUP_ANIMATION_TIME,
|
||||
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
||||
onStopped: () => callback(),
|
||||
onStopped: () => resolve(),
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user