on xenial help sign in
Work around AnimatedSprite infinite loop bug

https://bugreports.qt.io/browse/QTBUG-53937 Only change AnimatedSprite source once all other properties are up to date (ie, in sync with the new source) The nature of QML is such that property changes happen one by one and not in a atomic batch.

commit0ec559bb541b95d79e5cd6347b70459544ac26f3 authorDaniel d'Andrada <daniel.dandrada@canonical.com> dateWed 8 Jun 2016, 17:01 (10 years ago) parent5668f71
3 files changed+27−3
plugins/Cursor/Cursor.qml+4−1 plugins/Cursor/CursorImageInfo.cpp+15−2 plugins/Cursor/CursorImageInfo.h+8
plugins/Cursor/Cursor.qml+4−1
@@ -29,7 +29,10 @@ MousePointer {
2929 AnimatedSprite {
3030 x: -imageInfo.hotspot.x
3131 y: -imageInfo.hotspot.y
32− source: "image://cursor/" + mousePointer.themeName + "/" + mousePointer.cursorName
32+
33+ // The only reason of the ready property is to work around https://bugreports.qt.io/browse/QTBUG-53937
34+ source: imageInfo.ready ? "image://cursor/" + mousePointer.themeName + "/" + mousePointer.cursorName
35+ : ""
3336
3437 interpolate: false
3538
plugins/Cursor/CursorImageInfo.cpp+15−2
@@ -27,24 +27,28 @@ CursorImageInfo::CursorImageInfo(QObject *parent)
2727void CursorImageInfo::setCursorName(const QString &cursorName)
2828{
2929 if (cursorName != m_cursorName) {
30+ scheduleUpdate();
3031 m_cursorName = cursorName;
3132 Q_EMIT cursorNameChanged();
32− scheduleUpdate();
3333 }
3434}
3535
3636void CursorImageInfo::setThemeName(const QString &themeName)
3737{
3838 if (m_themeName != themeName) {
39+ scheduleUpdate();
3940 m_themeName = themeName;
4041 Q_EMIT themeNameChanged();
41− scheduleUpdate();
4242 }
4343}
4444
4545void CursorImageInfo::scheduleUpdate()
4646{
4747 if (!m_updateTimer.isActive()) {
48+ if (m_ready) {
49+ m_ready = false;
50+ Q_EMIT readyChanged();
51+ }
4852 m_updateTimer.start();
4953 }
5054}
@@ -58,6 +62,10 @@ void CursorImageInfo::update()
5862 Q_EMIT frameHeightChanged();
5963 Q_EMIT frameCountChanged();
6064 Q_EMIT frameDurationChanged();
65+
66+ Q_ASSERT(!m_ready);
67+ m_ready = true;
68+ Q_EMIT readyChanged();
6169}
6270
6371QPoint CursorImageInfo::hotspot() const
@@ -104,3 +112,8 @@ int CursorImageInfo::frameDuration() const
104112 return 0;
105113 }
106114}
115+
116+bool CursorImageInfo::ready() const
117+{
118+ return m_ready;
119+}
plugins/Cursor/CursorImageInfo.h+8
@@ -36,6 +36,10 @@ class CursorImageInfo : public QObject
3636 Q_PROPERTY(int frameCount READ frameCount NOTIFY frameCountChanged)
3737 Q_PROPERTY(int frameDuration READ frameDuration NOTIFY frameDurationChanged)
3838
39+ // Will be true when all properties are in sync and false while they're
40+ // being updated to reflect a change in themeName or cursorName.
41+ Q_PROPERTY(bool ready READ ready NOTIFY readyChanged)
42+
3943public:
4044 CursorImageInfo(QObject *parent = nullptr);
4145
@@ -50,6 +54,7 @@ public:
5054 qreal frameHeight() const;
5155 int frameCount() const;
5256 int frameDuration() const;
57+ bool ready() const;
5358
5459Q_SIGNALS:
5560 void themeNameChanged();
@@ -59,6 +64,7 @@ Q_SIGNALS:
5964 void frameHeightChanged();
6065 void frameCountChanged();
6166 void frameDurationChanged();
67+ void readyChanged();
6268
6369private Q_SLOTS:
6470 void update();
@@ -71,6 +77,8 @@ private:
7177 QString m_cursorName;
7278
7379 CursorImage *m_cursorImage{nullptr};
80+
81+ bool m_ready{false};
7482};
7583
7684#endif // CURSOR_IMAGE_INFO_H