workspace: Use Util.lerp() instead of actor box for interpolating
Instead of interpolating our workspace and layout boxes for each child using clutter_actor_box_interpolate(), use our Util.lerp() function and stay in JS land instead. This is quite a large performance improvement since it avoids heap-allocating a new ClutterActorBox for every child. With this, we're finally at a duration of 1.0 ms to allocate the Workspace with 20 windows. Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1743>
This commit is contained in:
parent
afb56df55c
commit
59b97a3095
@ -616,8 +616,7 @@ var WorkspaceLayout = GObject.registerClass({
|
||||
|
||||
const allocationScale = containerBox.get_width() / workareaWidth;
|
||||
|
||||
const workspaceBox = new Clutter.ActorBox();
|
||||
const layoutBox = new Clutter.ActorBox();
|
||||
const childBox = new Clutter.ActorBox();
|
||||
|
||||
const { ControlsState } = OverviewControls;
|
||||
const inSessionTransition =
|
||||
@ -625,44 +624,46 @@ var WorkspaceLayout = GObject.registerClass({
|
||||
|
||||
const nSlots = this._windowSlots.length;
|
||||
for (let i = 0; i < nSlots; i++) {
|
||||
const [x, y, width, height, child] = this._windowSlots[i];
|
||||
let [x, y, width, height, child] = this._windowSlots[i];
|
||||
if (!child.visible)
|
||||
continue;
|
||||
|
||||
const windowInfo = this._windows.get(child);
|
||||
|
||||
let workspaceBoxX, workspaceBoxY;
|
||||
let workspaceBoxWidth, workspaceBoxHeight;
|
||||
|
||||
if (windowInfo.metaWindow.showing_on_its_workspace()) {
|
||||
workspaceBox.set_origin(
|
||||
child.boundingBox.x - workareaX,
|
||||
child.boundingBox.y - workareaY);
|
||||
workspaceBox.set_size(
|
||||
child.boundingBox.width,
|
||||
child.boundingBox.height);
|
||||
workspaceBoxX = (child.boundingBox.x - workareaX) * allocationScale;
|
||||
workspaceBoxY = (child.boundingBox.y - workareaY) * allocationScale;
|
||||
workspaceBoxWidth = child.boundingBox.width * allocationScale;
|
||||
workspaceBoxHeight = child.boundingBox.height * allocationScale;
|
||||
} else {
|
||||
workspaceBox.set_origin(workareaX, workareaY);
|
||||
workspaceBox.set_size(0, 0);
|
||||
workspaceBoxX = workareaX * allocationScale;
|
||||
workspaceBoxY = workareaY * allocationScale;
|
||||
workspaceBoxWidth = 0;
|
||||
workspaceBoxHeight = 0;
|
||||
|
||||
child.opacity = stateAdjustementValue * 255;
|
||||
}
|
||||
|
||||
workspaceBox.scale(allocationScale);
|
||||
|
||||
// Don't allow the scaled floating size to drop below
|
||||
// the target layout size.
|
||||
// We only want to apply this when the scaled floating size is
|
||||
// actually larger than the target layout size, that is while
|
||||
// animating between the session and the window picker.
|
||||
if (inSessionTransition) {
|
||||
workspaceBox.set_size(
|
||||
Math.max(workspaceBox.get_width(), width),
|
||||
Math.max(workspaceBox.get_height(), height));
|
||||
workspaceBoxWidth = Math.max(workspaceBoxWidth, width);
|
||||
workspaceBoxHeight = Math.max(workspaceBoxHeight, height);
|
||||
}
|
||||
|
||||
layoutBox.set_origin(x, y);
|
||||
layoutBox.set_size(width, height);
|
||||
x = Util.lerp(workspaceBoxX, x, stateAdjustementValue);
|
||||
y = Util.lerp(workspaceBoxY, y, stateAdjustementValue);
|
||||
width = Util.lerp(workspaceBoxWidth, width, stateAdjustementValue);
|
||||
height = Util.lerp(workspaceBoxHeight, height, stateAdjustementValue);
|
||||
|
||||
const childBox = workspaceBox.interpolate(layoutBox,
|
||||
stateAdjustementValue);
|
||||
childBox.set_origin(x, y);
|
||||
childBox.set_size(width, height);
|
||||
|
||||
if (windowInfo.currentTransition) {
|
||||
windowInfo.currentTransition.get_interval().set_final(childBox);
|
||||
|
Loading…
Reference in New Issue
Block a user