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.
master
Vlad Zahorodnii 3 years ago
parent 97160c9b90
commit a5028ab5c5

@ -451,7 +451,7 @@ static bool isOverlappingAny(ExpoCell *w, const QHash<ExpoCell *, QRect> &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<ExpoCell *, QRect> targets;
QHash<ExpoCell *, int> 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 {

@ -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

Loading…
Cancel
Save