effects/overview: Layout window thumbnails in updatePolish()

Currently, ExpoLayout delays layout updates by using a singleshot timer
(primarily due to the author of the effect not being aware of
QQuickItem::polish() and QQuickItem::updatePolish()).

This change makes ExpoLayout schedule layout updates using QtQuick's
native item polish machinery, which gets triggered before rendering and
thus we can batch more geometry updates.

In addition to that, this change simplifies the initialization code in
ScreenView by making the fact that ExpoLayout is arranged right before
rendering internal to the WindowHeap type.
This commit is contained in:
Vlad Zahorodnii 2021-08-31 13:41:36 +03:00
parent 683bf20168
commit b0c26cc424
4 changed files with 42 additions and 36 deletions

View file

@ -45,7 +45,7 @@ void ExpoCell::setLayout(ExpoLayout *layout)
void ExpoCell::update()
{
if (m_layout) {
m_layout->scheduleUpdate();
m_layout->polish();
}
}
@ -199,8 +199,6 @@ void ExpoCell::setPersistentKey(const QString &key)
ExpoLayout::ExpoLayout(QQuickItem *parent)
: QQuickItem(parent)
{
m_updateTimer.setSingleShot(true);
connect(&m_updateTimer, &QTimer::timeout, this, &ExpoLayout::update);
}
ExpoLayout::LayoutMode ExpoLayout::mode() const
@ -212,7 +210,7 @@ void ExpoLayout::setMode(LayoutMode mode)
{
if (m_mode != mode) {
m_mode = mode;
scheduleUpdate();
polish();
Q_EMIT modeChanged();
}
}
@ -226,7 +224,7 @@ void ExpoLayout::setFillGaps(bool fill)
{
if (m_fillGaps != fill) {
m_fillGaps = fill;
scheduleUpdate();
polish();
Q_EMIT fillGapsChanged();
}
}
@ -240,51 +238,60 @@ void ExpoLayout::setSpacing(int spacing)
{
if (m_spacing != spacing) {
m_spacing = spacing;
scheduleUpdate();
polish();
Q_EMIT spacingChanged();
}
}
void ExpoLayout::update()
bool ExpoLayout::isReady() const
{
if (m_cells.isEmpty()) {
return;
}
switch (m_mode) {
case LayoutClosest:
calculateWindowTransformationsClosest();
break;
case LayoutKompose:
calculateWindowTransformationsKompose();
break;
case LayoutNatural:
calculateWindowTransformationsNatural();
break;
return m_ready;
}
void ExpoLayout::setReady()
{
if (!m_ready) {
m_ready = true;
Q_EMIT readyChanged();
}
}
void ExpoLayout::scheduleUpdate()
void ExpoLayout::updatePolish()
{
m_updateTimer.start();
if (!m_cells.isEmpty()) {
switch (m_mode) {
case LayoutClosest:
calculateWindowTransformationsClosest();
break;
case LayoutKompose:
calculateWindowTransformationsKompose();
break;
case LayoutNatural:
calculateWindowTransformationsNatural();
break;
}
}
setReady();
}
void ExpoLayout::addCell(ExpoCell *cell)
{
Q_ASSERT(!m_cells.contains(cell));
m_cells.append(cell);
scheduleUpdate();
polish();
}
void ExpoLayout::removeCell(ExpoCell *cell)
{
m_cells.removeOne(cell);
scheduleUpdate();
polish();
}
void ExpoLayout::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
{
if (newGeometry.size() != oldGeometry.size()) {
scheduleUpdate();
polish();
}
QQuickItem::geometryChanged(newGeometry, oldGeometry);
}

View file

@ -9,7 +9,6 @@
#include <QObject>
#include <QQuickItem>
#include <QRect>
#include <QTimer>
#include <optional>
@ -21,6 +20,7 @@ class ExpoLayout : public QQuickItem
Q_PROPERTY(LayoutMode mode READ mode WRITE setMode NOTIFY modeChanged)
Q_PROPERTY(bool fillGaps READ fillGaps WRITE setFillGaps NOTIFY fillGapsChanged)
Q_PROPERTY(int spacing READ spacing WRITE setSpacing NOTIFY spacingChanged)
Q_PROPERTY(bool ready READ isReady NOTIFY readyChanged)
public:
enum LayoutMode : uint {
@ -44,17 +44,18 @@ public:
void addCell(ExpoCell *cell);
void removeCell(ExpoCell *cell);
bool isReady() const;
void setReady();
protected:
void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) override;
public Q_SLOTS:
void update();
void scheduleUpdate();
void updatePolish() override;
Q_SIGNALS:
void modeChanged();
void fillGapsChanged();
void spacingChanged();
void readyChanged();
private:
void calculateWindowTransformationsClosest();
@ -63,9 +64,9 @@ private:
QList<ExpoCell *> m_cells;
LayoutMode m_mode = LayoutNatural;
QTimer m_updateTimer;
int m_accuracy = 20;
int m_spacing = 10;
bool m_ready = false;
bool m_fillGaps = false;
};

View file

@ -125,8 +125,5 @@ FocusScope {
id: stackModel
}
Component.onCompleted: {
// Delay starting the effect to let the window heap arrange thumbnails.
Qt.callLater(container.start);
}
Component.onCompleted: start();
}

View file

@ -27,6 +27,7 @@ FocusScope {
property real padding: 0
required property bool organized
readonly property bool effectiveOrganized: expoLayout.ready && organized
ExpoLayout {
id: expoLayout
@ -50,7 +51,7 @@ FocusScope {
readonly property bool selected: heap.selectedIndex == index
state: {
if (heap.organized) {
if (heap.effectiveOrganized) {
return "active";
}
return client.minimized ? "initial-minimized" : "initial";