From b0c26cc4245e91b60ebc506e9d77dc2180ffe2ec Mon Sep 17 00:00:00 2001 From: Vlad Zahorodnii Date: Tue, 31 Aug 2021 13:41:36 +0300 Subject: [PATCH] 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. --- src/effects/overview/expolayout.cpp | 57 ++++++++++++++----------- src/effects/overview/expolayout.h | 13 +++--- src/effects/overview/qml/ScreenView.qml | 5 +-- src/effects/overview/qml/WindowHeap.qml | 3 +- 4 files changed, 42 insertions(+), 36 deletions(-) diff --git a/src/effects/overview/expolayout.cpp b/src/effects/overview/expolayout.cpp index 5f843a4e33..51f76959fa 100644 --- a/src/effects/overview/expolayout.cpp +++ b/src/effects/overview/expolayout.cpp @@ -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); } diff --git a/src/effects/overview/expolayout.h b/src/effects/overview/expolayout.h index e6e52cedd5..35914c555d 100644 --- a/src/effects/overview/expolayout.h +++ b/src/effects/overview/expolayout.h @@ -9,7 +9,6 @@ #include #include #include -#include #include @@ -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 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; }; diff --git a/src/effects/overview/qml/ScreenView.qml b/src/effects/overview/qml/ScreenView.qml index 77832123a6..eedbc19feb 100644 --- a/src/effects/overview/qml/ScreenView.qml +++ b/src/effects/overview/qml/ScreenView.qml @@ -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(); } diff --git a/src/effects/overview/qml/WindowHeap.qml b/src/effects/overview/qml/WindowHeap.qml index 849c3974e3..709149a36f 100644 --- a/src/effects/overview/qml/WindowHeap.qml +++ b/src/effects/overview/qml/WindowHeap.qml @@ -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";