From 78d6b13c2920cadfb6efa8fb42490cd0b5f65add Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Wed, 9 Dec 2020 19:32:01 +0100 Subject: [PATCH] workspacesView: Don't update scroll position when allocating Updating scroll position may have significant side effects, e.g. switching workspace; this should never happen during allocation, as we're in the middle of painting a frame. So, put it in an idle callback if we're doing it from an allocation to have the side effects happen the right time. Part-of: --- js/ui/workspacesView.js | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/js/ui/workspacesView.js b/js/ui/workspacesView.js index 4aac1cc1c..cccd447e2 100644 --- a/js/ui/workspacesView.js +++ b/js/ui/workspacesView.js @@ -78,6 +78,7 @@ class WorkspacesView extends WorkspacesViewBase { this._animating = false; // tweening this._gestureActive = false; // touch(pad) gestures + this._updateScrollPositionId = 0; this._scrollAdjustment = scrollAdjustment; this._onScrollId = this._scrollAdjustment.connect('notify::value', @@ -124,7 +125,14 @@ class WorkspacesView extends WorkspacesViewBase { child.allocate_available_size(x, y, box.get_width(), box.get_height()); }); - this._updateScrollPosition(); + // Update scroll position in an idle callback to avoid unintended + // side effects (e.g. workspace switch) during layout. + this._updateScrollPositionId = + GLib.idle_add(GLib.PRIORITY_DEFAULT, () => { + this._updateScrollPositionId = 0; + this._updateScrollPosition(); + return GLib.SOURCE_REMOVE; + }); } getActiveWorkspace() { @@ -227,6 +235,8 @@ class WorkspacesView extends WorkspacesViewBase { _onDestroy() { super._onDestroy(); + if (this._updateScrollPositionId) + GLib.source_remove(this._updateScrollPositionId); this._scrollAdjustment.disconnect(this._onScrollId); global.window_manager.disconnect(this._switchWorkspaceNotifyId); let workspaceManager = global.workspace_manager; @@ -254,6 +264,11 @@ class WorkspacesView extends WorkspacesViewBase { if (!this.has_allocation()) return; + if (this._updateScrollPositionId) { + GLib.source_remove(this._updateScrollPositionId); + this._updateScrollPositionId = 0; + } + const adj = this._scrollAdjustment; const allowSwitch = adj.get_transition('value') === null && !this._gestureActive;