iconGrid/iconGrid: Wait for icon sizes before running spring animation

To run the spring animation, IconGrid uses the transformed position and size
of the icons. This works okay when IconGridLayout doesn't need to update the
icon sizes, but looks bad when IconGridLayout selects a different icon size.

Wait for the icon sizes to be recalculated, and the icons  beallocated, before
running the spring animation. If no icon size update is pending, run the spring
animation directly.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1518>
This commit is contained in:
Georges Basile Stavracas Neto 2020-12-02 17:43:13 -03:00 committed by Marge Bot
parent 10d91b52e7
commit b730875012

View File

@ -391,6 +391,9 @@ var IconGridLayout = GObject.registerClass({
this._containerDestroyedId = 0; this._containerDestroyedId = 0;
this._updateIconSizesLaterId = 0; this._updateIconSizesLaterId = 0;
this._resolveOnIdleId = 0;
this._iconSizeUpdateResolveCbs = [];
} }
_findBestIconSize() { _findBestIconSize() {
@ -701,11 +704,28 @@ var IconGridLayout = GObject.registerClass({
return isRtl ? rowAlign * -1 : rowAlign; return isRtl ? rowAlign * -1 : rowAlign;
} }
_runPostAllocation() {
if (this._iconSizeUpdateResolveCbs.length > 0 &&
this._resolveOnIdleId === 0) {
this._resolveOnIdleId = GLib.idle_add(GLib.PRIORITY_DEFAULT, () => {
this._iconSizeUpdateResolveCbs.forEach(cb => cb());
this._iconSizeUpdateResolveCbs = [];
this._resolveOnIdleId = 0;
return GLib.SOURCE_REMOVE;
});
}
}
_onDestroy() { _onDestroy() {
if (this._updateIconSizesLaterId >= 0) { if (this._updateIconSizesLaterId >= 0) {
Meta.later_remove(this._updateIconSizesLaterId); Meta.later_remove(this._updateIconSizesLaterId);
this._updateIconSizesLaterId = 0; this._updateIconSizesLaterId = 0;
} }
if (this._resolveOnIdleId > 0) {
GLib.source_remove(this._resolveOnIdleId);
delete this._resolveOnIdleId;
}
} }
vfunc_set_container(container) { vfunc_set_container(container) {
@ -820,6 +840,8 @@ var IconGridLayout = GObject.registerClass({
}); });
this._pageSizeChanged = false; this._pageSizeChanged = false;
this._runPostAllocation();
} }
/** /**
@ -964,6 +986,14 @@ var IconGridLayout = GObject.registerClass({
return itemData.pageIndex; return itemData.pageIndex;
} }
ensureIconSizeUpdated() {
if (this._updateIconSizesLaterId === 0)
return Promise.resolve();
return new Promise(
resolve => this._iconSizeUpdateResolveCbs.push(resolve));
}
adaptToSize(pageWidth, pageHeight) { adaptToSize(pageWidth, pageHeight) {
if (this._pageWidth === pageWidth && this._pageHeight === pageHeight) if (this._pageWidth === pageWidth && this._pageHeight === pageHeight)
return; return;
@ -1617,7 +1647,7 @@ var IconGrid = GObject.registerClass({
this.layout_manager.adaptToSize(width, height); this.layout_manager.adaptToSize(width, height);
} }
animateSpring(animationDirection, sourceActor) { async animateSpring(animationDirection, sourceActor) {
this._resetAnimationActors(); this._resetAnimationActors();
let actors = this._getChildrenToAnimate(); let actors = this._getChildrenToAnimate();
@ -1626,6 +1656,8 @@ var IconGrid = GObject.registerClass({
return; return;
} }
await this.layout_manager.ensureIconSizeUpdated();
let [sourceX, sourceY] = sourceActor.get_transformed_position(); let [sourceX, sourceY] = sourceActor.get_transformed_position();
let [sourceWidth, sourceHeight] = sourceActor.get_size(); let [sourceWidth, sourceHeight] = sourceActor.get_size();
// Get the center // Get the center