workspace: Extend clip when animating from window picker to app grid

We want to clip the Workspace actor in the appGrid state of the overview
in order to make sure windows that overflow the monitor don't spill out.
So far we had commit b1970b95b8 for that.

Now since the last commit, window previews always slightly overflow the
allocation with their icons. That means a part of the window icon gets
clipped away as soon as the transition to the appGrid starts, which
looks weird.

Fix that bug in the transition by slightly extending the clip downwards
when animating between the window picker and the app grid state. The
extra height we extend the clip by is controlled by the overviewState,
which means we extend the clip by the full icon overlap in the window
picker state, but don't extend the clip at all when in the app grid
state.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1813>
This commit is contained in:
Jonas Dreßler 2021-03-10 13:24:07 +01:00 committed by Marge Bot
parent fcc80407ea
commit 4e83aaf850

View File

@ -592,6 +592,7 @@ var WorkspaceLayout = GObject.registerClass({
vfunc_allocate(container, box) {
const containerBox = container.allocation;
const [containerWidth, containerHeight] = containerBox.get_size();
const containerAllocationChanged =
this._lastBox === null || !this._lastBox.equal(containerBox);
this._lastBox = containerBox.copy();
@ -608,6 +609,27 @@ var WorkspaceLayout = GObject.registerClass({
this.notify('layout-frozen');
}
const { ControlsState } = OverviewControls;
const inSessionTransition =
this._overviewAdjustment.value <= ControlsState.WINDOW_PICKER;
const window = this._sortedWindows[0];
if (inSessionTransition || !window) {
container.remove_clip();
} else {
const [, bottomOversize] = window.chromeHeights();
const [containerX, containerY] = containerBox.get_origin();
const extraHeightProgress = this._overviewAdjustment.value -
OverviewControls.ControlsState.WINDOW_PICKER;
const extraClipHeight = bottomOversize * (1 - extraHeightProgress);
container.set_clip(containerX, containerY,
containerWidth, containerHeight + extraClipHeight);
}
let layoutChanged = false;
if (!this._layoutFrozen) {
if (this._layout === null) {
@ -624,14 +646,10 @@ var WorkspaceLayout = GObject.registerClass({
const workareaWidth = this._workarea.width;
const stateAdjustementValue = this._stateAdjustment.value;
const allocationScale = containerBox.get_width() / workareaWidth;
const allocationScale = containerWidth / workareaWidth;
const childBox = new Clutter.ActorBox();
const { ControlsState } = OverviewControls;
const inSessionTransition =
this._overviewAdjustment.value <= ControlsState.WINDOW_PICKER;
const nSlots = this._windowSlots.length;
for (let i = 0; i < nSlots; i++) {
let [x, y, width, height, child] = this._windowSlots[i];
@ -1036,15 +1054,6 @@ class Workspace extends St.Widget {
});
this._overviewAdjustment = overviewAdjustment;
this._overviewStateId = overviewAdjustment.connect('notify::value', () => {
const overviewState = overviewAdjustment.value;
// We want windows not to spill out when the overview is in
// APP_GRID state, but HIDDEN and WINDOW_PICKER should allow
// them to eventually draw outside the workspace.
this._container.clip_to_allocation =
overviewState > OverviewControls.ControlsState.WINDOW_PICKER;
});
this.monitorIndex = monitorIndex;
this._monitor = Main.layoutManager.monitors[this.monitorIndex];
@ -1296,11 +1305,6 @@ class Workspace extends St.Widget {
this._layoutFrozenId = 0;
}
if (this._overviewStateId > 0) {
this._overviewAdjustment.disconnect(this._overviewStateId);
delete this._overviewStateId;
}
this._windows = [];
}