on xenial help sign in
fixed problem destroying cached menu model.
0b65bb2Nick Dedekind
plugins/Unity/Indicators/CachedUnityMenuModel.qml+32−24
@@ -18,43 +18,51 @@
18 */
18 */
19
19
20import QtQuick 2.0
20import QtQuick 2.0
21−import QMenuModel 0.1 as QMenuModel
21+import QMenuModel 0.1
22import Unity.Indicators 0.1 as Indicators
22import Unity.Indicators 0.1 as Indicators
23
23
24// Make sure we don't duplicate models.
24// Make sure we don't duplicate models.
25Item {
25Item {
26 id: cachedModel
26 id: cachedModel
27− property string busName: ""
27+ property string busName
28− property string actionsObjectPath: ""
28+ property string actionsObjectPath
29− property string menuObjectPath: ""
29+ property string menuObjectPath
30−
31 readonly property bool ready: busName!=="" && actionsObjectPath!=="" && menuObjectPath!==""
30 readonly property bool ready: busName!=="" && actionsObjectPath!=="" && menuObjectPath!==""
32
31
33− property QtObject model: {
32+ property UnityMenuModel model: {
34− if (!ready) {
35− return null;
33+ if (!ready) return null;
34+
35+ var newModel = Indicators.UnityMenuModelCache.model(menuObjectPath);
36+ if (!newModel) {
37+ newModel = modelComponent.createObject(null,
38+ {
39+ "busName": cachedModel.busName,
40+ "menuObjectPath": cachedModel.menuObjectPath,
41+ "actions": { "indicator": cachedModel.actionsObjectPath },
42+ });
43+ Indicators.UnityMenuModelCache.registerModel(newModel.menuObjectPath, newModel);
36 }
44 }
45+ return newModel;
46+ }
47+
48+ QtObject {
49+ id: d
50+ property UnityMenuModel oldModel: null
51+ }
37
52
38− var component = Indicators.UnityMenuModelCache.model(menuObjectPath);
53+ onModelChanged: {
39− if (!component) {
54+ if (model !== d.oldModel) {
40− component = modelComponent.createObject(cachedModel);
55+ if (d.oldModel) Indicators.UnityMenuModelCache.deref(d.oldModel);
41− return component;
56+ if (model) Indicators.UnityMenuModelCache.ref(model);
42 }
57 }
43− return component;
58+ d.oldModel = model;
59+ }
60+ Component.onDestruction: {
61+ if (model) Indicators.UnityMenuModelCache.deref(model);
44 }
62 }
45
63
46 Component {
64 Component {
47 id: modelComponent
65 id: modelComponent
48−
49− QMenuModel.UnityMenuModel {
66+ UnityMenuModel {}
50− id: unityModel
51− busName: cachedModel.busName
52− actions: { "indicator": cachedModel.actionsObjectPath }
53− menuObjectPath: cachedModel.menuObjectPath
54−
55− Component.onCompleted: {
56− Indicators.UnityMenuModelCache.registerModel(cachedModel.menuObjectPath, unityModel);
57− }
58− }
59 }
67 }
60}
68}
plugins/Unity/Indicators/unitymenumodelcache.cpp+24−2
@@ -20,6 +20,8 @@
20#include "unitymenumodelcache.h"
20#include "unitymenumodelcache.h"
21#include <unitymenumodel.h>
21#include <unitymenumodel.h>
22
22
23+#include <QQmlEngine>
24+
23UnityMenuModelCache::UnityMenuModelCache(QObject* parent)
25UnityMenuModelCache::UnityMenuModelCache(QObject* parent)
24 : QObject(parent)
26 : QObject(parent)
25{
27{
@@ -27,9 +29,9 @@ UnityMenuModelCache::UnityMenuModelCache(QObject* parent)
27
29
28UnityMenuModelCache::~UnityMenuModelCache()
30UnityMenuModelCache::~UnityMenuModelCache()
29{
31{
32+ qDeleteAll(m_menuModels);
30}
33}
31
34
32−
33UnityMenuModel* UnityMenuModelCache::model(const QString& path) const
35UnityMenuModel* UnityMenuModelCache::model(const QString& path) const
34{
36{
35 return m_menuModels.value(path, NULL);
37 return m_menuModels.value(path, NULL);
@@ -37,6 +39,26 @@ UnityMenuModel* UnityMenuModelCache::model(const QString& path) const
37
39
38void UnityMenuModelCache::registerModel(const QString& path, UnityMenuModel* menuModel)
40void UnityMenuModelCache::registerModel(const QString& path, UnityMenuModel* menuModel)
39{
41{
42+ QQmlEngine::setObjectOwnership(menuModel, QQmlEngine::CppOwnership);
40 menuModel->setParent(this);
43 menuModel->setParent(this);
41 m_menuModels[path] = menuModel;
44 m_menuModels[path] = menuModel;
42−}
45+}
46+
47+void UnityMenuModelCache::ref(UnityMenuModel* menuModel)
48+{
49+ m_refs[menuModel] = m_refs.value(menuModel, 0) + 1;
50+}
51+
52+void UnityMenuModelCache::deref(UnityMenuModel* menuModel)
53+{
54+ if (m_refs.contains(menuModel)) {
55+ if (m_refs[menuModel]-- == 0) {
56+ m_refs.remove(menuModel);
57+ QList<QString> keys = m_menuModels.keys(menuModel);
58+ Q_FOREACH(const QString& key, keys) {
59+ m_menuModels.remove(key);
60+ }
61+ delete menuModel;
62+ }
63+ }
64+}
plugins/Unity/Indicators/unitymenumodelcache.h+4
@@ -37,8 +37,12 @@ public:
37 Q_INVOKABLE UnityMenuModel* model(const QString& path) const;
37 Q_INVOKABLE UnityMenuModel* model(const QString& path) const;
38 Q_INVOKABLE void registerModel(const QString& path, UnityMenuModel* menuModel);
38 Q_INVOKABLE void registerModel(const QString& path, UnityMenuModel* menuModel);
39
39
40+ Q_INVOKABLE void ref(UnityMenuModel* menuModel);
41+ Q_INVOKABLE void deref(UnityMenuModel* menuModel);
42+
40private:
43private:
41 QHash<QString, UnityMenuModel*> m_menuModels;
44 QHash<QString, UnityMenuModel*> m_menuModels;
45+ QHash<UnityMenuModel*, uint> m_refs;
42};
46};
43
47
44#endif // UNITYMENUMODELCACHE_H
48#endif // UNITYMENUMODELCACHE_H