From a5028ab5c5929ad1772cc73ca4da7c54114f1f9e Mon Sep 17 00:00:00 2001 From: Vlad Zahorodnii Date: Fri, 3 Dec 2021 23:08:09 +0200 Subject: [PATCH] effects/overview: Make ExpoLayout agnostic about coordinates space where natural geometry is Currently, the ExpoLayout wants the natural geometry to be in the local coordinate space because of the default layout mode. With the natural layout, the ExpoLayout will run a simple loop that repels overlapping cells. Once no two items overlap, the items will be scaled down based on their bounding rectangle and the target area. The problem is that the ExpoLayout includes the area where items will be eventually placed when computing the bounding rectangle, which can result in a sort of a bug where almost all windows are shifted to one side of the screen, which is not at 0,0. This change removes the target area from the bounding rect math so the coordinate space where natural geometry is specified is irrelevant. It fixes the issue where windows can be shifted to one side of the screen after adding or removing a window. It also makes the ExpoLayout API more simpler on the QML side and ensures that no relayouting will be performed if only the position of the WindowHeap changes. --- src/effects/overview/expolayout.cpp | 11 +++++------ src/effects/overview/qml/WindowHeap.qml | 4 ++-- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/effects/overview/expolayout.cpp b/src/effects/overview/expolayout.cpp index c4d26ef127..66f3cb4ab7 100644 --- a/src/effects/overview/expolayout.cpp +++ b/src/effects/overview/expolayout.cpp @@ -451,7 +451,7 @@ static bool isOverlappingAny(ExpoCell *w, const QHash &target void ExpoLayout::calculateWindowTransformationsNatural() { - QRect area = QRect(0, 0, width(), height()); + const QRect area = QRect(0, 0, width(), height()); if (m_cells.count() == 1) { // Just move the window to its original location to save time ExpoCell *cell = m_cells.constFirst(); @@ -470,7 +470,7 @@ void ExpoLayout::calculateWindowTransformationsNatural() return a->persistentKey() < b->persistentKey(); }); - QRect bounds = area; + QRect bounds; int direction = 0; QHash targets; QHash directions; @@ -569,11 +569,10 @@ void ExpoLayout::calculateWindowTransformationsNatural() } } while (overlap); - // Work out scaling by getting the most top-left and most bottom-right window coords. - // The 20's and 10's are so that the windows don't touch the edge of the screen. + // Compute the scale factor so the bounding rect fits the target area. qreal scale; - if (bounds == area) { - scale = 1.0; // Don't add borders to the screen + if (bounds.width() <= area.width() && bounds.height() <= area.height()) { + scale = 1.0; } else if (area.width() / qreal(bounds.width()) < area.height() / qreal(bounds.height())) { scale = area.width() / qreal(bounds.width()); } else { diff --git a/src/effects/overview/qml/WindowHeap.qml b/src/effects/overview/qml/WindowHeap.qml index b91e1d7ca4..4635de1b94 100644 --- a/src/effects/overview/qml/WindowHeap.qml +++ b/src/effects/overview/qml/WindowHeap.qml @@ -126,8 +126,8 @@ FocusScope { ExpoCell { id: cell layout: expoLayout - naturalX: thumb.client.x - targetScreen.geometry.x - expoLayout.Kirigami.ScenePosition.x - naturalY: thumb.client.y - targetScreen.geometry.y - expoLayout.Kirigami.ScenePosition.y + naturalX: thumb.client.x + naturalY: thumb.client.y naturalWidth: thumb.client.width naturalHeight: thumb.client.height persistentKey: thumb.client.internalId