Merge lp:~lukas-kde/unity-notifications/fix-1453958 into lp:unity-notifications
- fix-1453958
- Merge into trunk
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | Pete Woods | ||||
Approved revision: | 231 | ||||
Merged at revision: | 236 | ||||
Proposed branch: | lp:~lukas-kde/unity-notifications/fix-1453958 | ||||
Merge into: | lp:unity-notifications | ||||
Diff against target: |
422 lines (+145/-93) 9 files modified
include/ActionModel.h (+4/-4) include/Notification.h (+3/-0) include/NotificationModel.h (+3/-3) include/NotificationPlugin.h (+2/-2) src/Notification.cpp (+3/-3) src/NotificationModel.cpp (+45/-37) src/NotificationServer.cpp (+6/-6) test/CMakeLists.txt (+0/-1) test/notificationtest.cpp (+79/-37) |
||||
To merge this branch: | bzr merge lp:~lukas-kde/unity-notifications/fix-1453958 | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Pete Woods | Approve | ||
Review via email: mp+274163@code.launchpad.net |
Commit message
Merge and rebase older code to fix notifications crashing on closing
Description of the change
Merge and rebase older code to fix notifications crashing on closing
Cf. https:/
Original message from lp:~macslow/unity-notifications/fix-1453958:
Plugged memory-leaks causing the backend to crash the unity8-
Checklist:
* Are there any related MPs required for this MP to build/function as expected? Please list.
No
* Did you perform an exploratory manual test run of your code change and any related functionality?
Yes
* Did you make sure that your branch does not contain spurious tags?
Yes
* If you changed the packaging (debian), did you subscribe the ubuntu-unity team to this MP?
Yes
* If you changed the UI, has there been a design review?
N/A
Lukáš Tinkl (lukas-kde) wrote : | # |
> When making a QSharedPointer use deleteLater, you should really pass in a
> custom deleter like so:
>
> QSharedPointer<
>
> i.e. at object creation time. It's risky to grab the raw pointer from a shared
> pointer and ask it to delete at some point.
Ack, &QObject:
- 229. By Lukáš Tinkl
-
specify &QObject:
:deleteLater deleter at construction,
clear the shared pointer on destruction instead
Pete Woods (pete-woods) wrote : | # |
Technically you don't even need the ::clear, as it will go out of scope naturally, (it's erased from the map, and the stack variable n goes out of scope). If you can be bothered, I would also remove all calls to n->clear();
- 230. By Lukáš Tinkl
-
remove the superfluous clear()
Lukáš Tinkl (lukas-kde) wrote : | # |
> Technically you don't even need the ::clear, as it will go out of scope
> naturally, (it's erased from the map, and the stack variable n goes out of
> scope). If you can be bothered, I would also remove all calls to n->clear();
Done
- 231. By Lukáš Tinkl
-
add missing override keywords
Pete Woods (pete-woods) : | # |
Pete Woods (pete-woods) wrote : | # |
Thanks for the fixes!
Preview Diff
1 | === modified file 'include/ActionModel.h' | |||
2 | --- include/ActionModel.h 2015-06-16 08:11:33 +0000 | |||
3 | +++ include/ActionModel.h 2015-10-13 14:11:48 +0000 | |||
4 | @@ -23,16 +23,16 @@ | |||
5 | 23 | 23 | ||
6 | 24 | class ActionModel : public QStringListModel { | 24 | class ActionModel : public QStringListModel { |
7 | 25 | Q_OBJECT | 25 | Q_OBJECT |
8 | 26 | Q_ENUMS(ActionsRoles) | ||
9 | 26 | 27 | ||
10 | 27 | public: | 28 | public: |
11 | 28 | ActionModel(QObject *parent=nullptr); | 29 | ActionModel(QObject *parent=nullptr); |
12 | 29 | virtual ~ActionModel(); | 30 | virtual ~ActionModel(); |
13 | 30 | 31 | ||
17 | 31 | virtual int rowCount(const QModelIndex &index) const; | 32 | virtual int rowCount(const QModelIndex &index) const override; |
18 | 32 | virtual QVariant data(const QModelIndex &index, int role) const; | 33 | virtual QVariant data(const QModelIndex &index, int role) const override; |
19 | 33 | virtual QHash<int, QByteArray> roleNames() const; | 34 | virtual QHash<int, QByteArray> roleNames() const override; |
20 | 34 | 35 | ||
21 | 35 | Q_ENUMS(ActionsRoles) | ||
22 | 36 | enum ActionsRoles { | 36 | enum ActionsRoles { |
23 | 37 | RoleActionLabel = Qt::UserRole + 1, | 37 | RoleActionLabel = Qt::UserRole + 1, |
24 | 38 | RoleActionId = Qt::UserRole + 2 | 38 | RoleActionId = Qt::UserRole + 2 |
25 | 39 | 39 | ||
26 | === modified file 'include/Notification.h' | |||
27 | --- include/Notification.h 2015-06-23 09:16:23 +0000 | |||
28 | +++ include/Notification.h 2015-10-13 14:11:48 +0000 | |||
29 | @@ -125,4 +125,7 @@ | |||
30 | 125 | QString filterText(const QString& text); | 125 | QString filterText(const QString& text); |
31 | 126 | }; | 126 | }; |
32 | 127 | 127 | ||
33 | 128 | Q_DECLARE_METATYPE(Notification::Urgency) | ||
34 | 129 | Q_DECLARE_METATYPE(Notification::Type) | ||
35 | 130 | |||
36 | 128 | #endif /* NOTIFICATION_HPP_ */ | 131 | #endif /* NOTIFICATION_HPP_ */ |
37 | 129 | 132 | ||
38 | === modified file 'include/NotificationModel.h' | |||
39 | --- include/NotificationModel.h 2015-06-23 09:18:43 +0000 | |||
40 | +++ include/NotificationModel.h 2015-10-13 14:11:48 +0000 | |||
41 | @@ -40,9 +40,9 @@ | |||
42 | 40 | NotificationModel(QObject *parent=nullptr); | 40 | NotificationModel(QObject *parent=nullptr); |
43 | 41 | virtual ~NotificationModel(); | 41 | virtual ~NotificationModel(); |
44 | 42 | 42 | ||
48 | 43 | virtual int rowCount(const QModelIndex &parent) const; | 43 | virtual int rowCount(const QModelIndex &parent) const override; |
49 | 44 | virtual QVariant data(const QModelIndex &index, int role) const; | 44 | virtual QVariant data(const QModelIndex &index, int role) const override; |
50 | 45 | virtual QHash<int, QByteArray> roleNames() const; | 45 | virtual QHash<int, QByteArray> roleNames() const override; |
51 | 46 | 46 | ||
52 | 47 | void insertNotification(const QSharedPointer<Notification> &n); | 47 | void insertNotification(const QSharedPointer<Notification> &n); |
53 | 48 | QList<QSharedPointer<Notification>> getAllNotifications() const; | 48 | QList<QSharedPointer<Notification>> getAllNotifications() const; |
54 | 49 | 49 | ||
55 | === modified file 'include/NotificationPlugin.h' | |||
56 | --- include/NotificationPlugin.h 2013-09-03 12:41:34 +0000 | |||
57 | +++ include/NotificationPlugin.h 2015-10-13 14:11:48 +0000 | |||
58 | @@ -28,8 +28,8 @@ | |||
59 | 28 | Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface") | 28 | Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface") |
60 | 29 | 29 | ||
61 | 30 | public: | 30 | public: |
64 | 31 | void registerTypes(const char *uri); | 31 | void registerTypes(const char *uri) override; |
65 | 32 | void initializeEngine(QQmlEngine *engine, const char *uri); | 32 | void initializeEngine(QQmlEngine *engine, const char *uri) override; |
66 | 33 | }; | 33 | }; |
67 | 34 | 34 | ||
68 | 35 | #endif // NOTIFICATIONS_PLUGIN_H | 35 | #endif // NOTIFICATIONS_PLUGIN_H |
69 | 36 | 36 | ||
70 | === modified file 'src/Notification.cpp' | |||
71 | --- src/Notification.cpp 2015-07-06 18:13:16 +0000 | |||
72 | +++ src/Notification.cpp 2015-10-13 14:11:48 +0000 | |||
73 | @@ -53,7 +53,7 @@ | |||
74 | 53 | p->body = "default text"; | 53 | p->body = "default text"; |
75 | 54 | p->server = nullptr; | 54 | p->server = nullptr; |
76 | 55 | p->value = -2; | 55 | p->value = -2; |
78 | 56 | p->actionsModel = new ActionModel(); | 56 | p->actionsModel = new ActionModel(this); |
79 | 57 | } | 57 | } |
80 | 58 | 58 | ||
81 | 59 | Notification::Notification(NotificationID id, int displayTime, const Urgency ur, const QString &text, Type type, NotificationServer *srv, QObject *parent) : | 59 | Notification::Notification(NotificationID id, int displayTime, const Urgency ur, const QString &text, Type type, NotificationServer *srv, QObject *parent) : |
82 | @@ -65,12 +65,12 @@ | |||
83 | 65 | p->server = srv; | 65 | p->server = srv; |
84 | 66 | p->value = -2; | 66 | p->value = -2; |
85 | 67 | p->displayTime = displayTime; | 67 | p->displayTime = displayTime; |
87 | 68 | p->actionsModel = new ActionModel(); | 68 | p->actionsModel = new ActionModel(this); |
88 | 69 | } | 69 | } |
89 | 70 | 70 | ||
90 | 71 | Notification::Notification(NotificationID id, int displayTime, const Urgency ur, Type type, NotificationServer *srv, QObject *parent) : | 71 | Notification::Notification(NotificationID id, int displayTime, const Urgency ur, Type type, NotificationServer *srv, QObject *parent) : |
91 | 72 | Notification(id, displayTime, ur, QString(), type, srv, parent){ | 72 | Notification(id, displayTime, ur, QString(), type, srv, parent){ |
93 | 73 | p->actionsModel = new ActionModel(); | 73 | p->actionsModel = new ActionModel(this); |
94 | 74 | } | 74 | } |
95 | 75 | 75 | ||
96 | 76 | Notification::~Notification() { | 76 | Notification::~Notification() { |
97 | 77 | 77 | ||
98 | === modified file 'src/NotificationModel.cpp' | |||
99 | --- src/NotificationModel.cpp 2015-06-23 09:18:43 +0000 | |||
100 | +++ src/NotificationModel.cpp 2015-10-13 14:11:48 +0000 | |||
101 | @@ -46,7 +46,8 @@ | |||
102 | 46 | } | 46 | } |
103 | 47 | 47 | ||
104 | 48 | NotificationModel::NotificationModel(QObject *parent) : QAbstractListModel(parent), p(new NotificationModelPrivate) { | 48 | NotificationModel::NotificationModel(QObject *parent) : QAbstractListModel(parent), p(new NotificationModelPrivate) { |
106 | 49 | p->displayedNotifications.append(QSharedPointer<Notification>(new Notification(0, -1, Notification::Normal, QString(), Notification::PlaceHolder))); | 49 | p->displayedNotifications.append(QSharedPointer<Notification>(new Notification(0, -1, Notification::Normal, QString(), Notification::PlaceHolder), |
107 | 50 | &QObject::deleteLater)); | ||
108 | 50 | connect(&(p->timer), SIGNAL(timeout()), this, SLOT(timeout())); | 51 | connect(&(p->timer), SIGNAL(timeout()), this, SLOT(timeout())); |
109 | 51 | p->timer.setSingleShot(true); | 52 | p->timer.setSingleShot(true); |
110 | 52 | } | 53 | } |
111 | @@ -74,41 +75,41 @@ | |||
112 | 74 | QVariant NotificationModel::data(const QModelIndex &index, int role) const { | 75 | QVariant NotificationModel::data(const QModelIndex &index, int role) const { |
113 | 75 | //printf("Data %d.\n", index.row()); | 76 | //printf("Data %d.\n", index.row()); |
114 | 76 | if (!index.isValid()) | 77 | if (!index.isValid()) |
116 | 77 | return QVariant(); | 78 | return QVariant(); |
117 | 78 | 79 | ||
118 | 79 | switch(role) { | 80 | switch(role) { |
119 | 80 | case ModelInterface::RoleType: | 81 | case ModelInterface::RoleType: |
121 | 81 | return QVariant(p->displayedNotifications[index.row()]->getType()); | 82 | return p->displayedNotifications[index.row()]->getType(); |
122 | 82 | 83 | ||
123 | 83 | case ModelInterface::RoleUrgency: | 84 | case ModelInterface::RoleUrgency: |
125 | 84 | return QVariant(p->displayedNotifications[index.row()]->getUrgency()); | 85 | return p->displayedNotifications[index.row()]->getUrgency(); |
126 | 85 | 86 | ||
127 | 86 | case ModelInterface::RoleId: | 87 | case ModelInterface::RoleId: |
129 | 87 | return QVariant(p->displayedNotifications[index.row()]->getID()); | 88 | return p->displayedNotifications[index.row()]->getID(); |
130 | 88 | 89 | ||
131 | 89 | case ModelInterface::RoleSummary: | 90 | case ModelInterface::RoleSummary: |
133 | 90 | return QVariant(p->displayedNotifications[index.row()]->getSummary()); | 91 | return p->displayedNotifications[index.row()]->getSummary(); |
134 | 91 | 92 | ||
135 | 92 | case ModelInterface::RoleBody: | 93 | case ModelInterface::RoleBody: |
137 | 93 | return QVariant(p->displayedNotifications[index.row()]->getBody()); | 94 | return p->displayedNotifications[index.row()]->getBody(); |
138 | 94 | 95 | ||
139 | 95 | case ModelInterface::RoleValue: | 96 | case ModelInterface::RoleValue: |
141 | 96 | return QVariant(p->displayedNotifications[index.row()]->getValue()); | 97 | return p->displayedNotifications[index.row()]->getValue(); |
142 | 97 | 98 | ||
143 | 98 | case ModelInterface::RoleIcon: | 99 | case ModelInterface::RoleIcon: |
145 | 99 | return QVariant(p->displayedNotifications[index.row()]->getIcon()); | 100 | return p->displayedNotifications[index.row()]->getIcon(); |
146 | 100 | 101 | ||
147 | 101 | case ModelInterface::RoleSecondaryIcon: | 102 | case ModelInterface::RoleSecondaryIcon: |
149 | 102 | return QVariant(p->displayedNotifications[index.row()]->getSecondaryIcon()); | 103 | return p->displayedNotifications[index.row()]->getSecondaryIcon(); |
150 | 103 | 104 | ||
151 | 104 | case ModelInterface::RoleActions: | 105 | case ModelInterface::RoleActions: |
152 | 105 | return QVariant::fromValue(p->displayedNotifications[index.row()]->getActions()); | 106 | return QVariant::fromValue(p->displayedNotifications[index.row()]->getActions()); |
153 | 106 | 107 | ||
154 | 107 | case ModelInterface::RoleHints: | 108 | case ModelInterface::RoleHints: |
156 | 108 | return QVariant(p->displayedNotifications[index.row()]->getHints()); | 109 | return p->displayedNotifications[index.row()]->getHints(); |
157 | 109 | 110 | ||
158 | 110 | case ModelInterface::RoleNotification: | 111 | case ModelInterface::RoleNotification: |
160 | 111 | return QVariant(p->displayedNotifications[index.row()]); | 112 | return QVariant::fromValue(p->displayedNotifications[index.row()]); |
161 | 112 | 113 | ||
162 | 113 | default: | 114 | default: |
163 | 114 | return QVariant(); | 115 | return QVariant(); |
164 | @@ -269,37 +270,44 @@ | |||
165 | 269 | } | 270 | } |
166 | 270 | 271 | ||
167 | 271 | void NotificationModel::removeNotification(const NotificationID id) { | 272 | void NotificationModel::removeNotification(const NotificationID id) { |
193 | 272 | for(int i=0; i<p->ephemeralQueue.size(); i++) { | 273 | for (int i = 0; i < p->displayedNotifications.size(); i++) { |
169 | 273 | if(p->ephemeralQueue[i]->getID() == id) { | ||
170 | 274 | p->ephemeralQueue.erase(p->ephemeralQueue.begin() + i); | ||
171 | 275 | Q_EMIT queueSizeChanged(queued()); | ||
172 | 276 | return; | ||
173 | 277 | } | ||
174 | 278 | } | ||
175 | 279 | |||
176 | 280 | for(int i=0; i<p->snapQueue.size(); i++) { | ||
177 | 281 | if(p->snapQueue[i]->getID() == id) { | ||
178 | 282 | p->snapQueue.erase(p->snapQueue.begin() + i); | ||
179 | 283 | Q_EMIT queueSizeChanged(queued()); | ||
180 | 284 | return; | ||
181 | 285 | } | ||
182 | 286 | } | ||
183 | 287 | |||
184 | 288 | for(int i=0; i<p->interactiveQueue.size(); i++) { | ||
185 | 289 | if(p->interactiveQueue[i]->getID() == id) { | ||
186 | 290 | p->interactiveQueue.erase(p->interactiveQueue.begin() + i); | ||
187 | 291 | Q_EMIT queueSizeChanged(queued()); | ||
188 | 292 | return; | ||
189 | 293 | } | ||
190 | 294 | } | ||
191 | 295 | |||
192 | 296 | for(int i=0; i<p->displayedNotifications.size(); i++) { | ||
194 | 297 | if(p->displayedNotifications[i]->getID() == id) { | 274 | if(p->displayedNotifications[i]->getID() == id) { |
195 | 298 | deleteFromVisible(i); | 275 | deleteFromVisible(i); |
196 | 299 | timeout(); // Simulate a timeout so visual state is updated. | 276 | timeout(); // Simulate a timeout so visual state is updated. |
197 | 300 | return; | 277 | return; |
198 | 301 | } | 278 | } |
199 | 302 | } | 279 | } |
200 | 280 | |||
201 | 281 | for (auto it = p->ephemeralQueue.begin(); it != p->ephemeralQueue.end(); ++it) { | ||
202 | 282 | QSharedPointer<Notification> n = *it; | ||
203 | 283 | |||
204 | 284 | if (n && n->getID() == id) { | ||
205 | 285 | p->ephemeralQueue.erase(it); | ||
206 | 286 | Q_EMIT queueSizeChanged(queued()); | ||
207 | 287 | return; | ||
208 | 288 | } | ||
209 | 289 | } | ||
210 | 290 | |||
211 | 291 | for (auto it = p->snapQueue.begin(); it != p->snapQueue.end(); ++it) { | ||
212 | 292 | QSharedPointer<Notification> n = *it; | ||
213 | 293 | |||
214 | 294 | if (n && n->getID() == id) { | ||
215 | 295 | p->snapQueue.erase(it); | ||
216 | 296 | Q_EMIT queueSizeChanged(queued()); | ||
217 | 297 | return; | ||
218 | 298 | } | ||
219 | 299 | } | ||
220 | 300 | |||
221 | 301 | for (auto it = p->interactiveQueue.begin(); it != p->interactiveQueue.end(); ++it) { | ||
222 | 302 | QSharedPointer<Notification> n = *it; | ||
223 | 303 | |||
224 | 304 | if (n && n->getID() == id) { | ||
225 | 305 | p->interactiveQueue.erase(it); | ||
226 | 306 | Q_EMIT queueSizeChanged(queued()); | ||
227 | 307 | return; | ||
228 | 308 | } | ||
229 | 309 | } | ||
230 | 310 | |||
231 | 303 | // The ID was not found in any queue. Should it be an error case or not? | 311 | // The ID was not found in any queue. Should it be an error case or not? |
232 | 304 | } | 312 | } |
233 | 305 | 313 | ||
234 | 306 | 314 | ||
235 | === modified file 'src/NotificationServer.cpp' | |||
236 | --- src/NotificationServer.cpp 2015-07-06 18:13:16 +0000 | |||
237 | +++ src/NotificationServer.cpp 2015-10-13 14:11:48 +0000 | |||
238 | @@ -144,7 +144,7 @@ | |||
239 | 144 | expireTimeout = 5000; | 144 | expireTimeout = 5000; |
240 | 145 | } | 145 | } |
241 | 146 | 146 | ||
243 | 147 | QSharedPointer<Notification> n(new Notification(id, expireTimeout, urg, ntype, this)); | 147 | QSharedPointer<Notification> n(new Notification(id, expireTimeout, urg, ntype, this), &QObject::deleteLater); |
244 | 148 | connect(n.data(), SIGNAL(dataChanged(unsigned int)), this, SLOT(onDataChanged(unsigned int))); | 148 | connect(n.data(), SIGNAL(dataChanged(unsigned int)), this, SLOT(onDataChanged(unsigned int))); |
245 | 149 | connect(n.data(), SIGNAL(completed(unsigned int)), this, SLOT(onCompleted(unsigned int))); | 149 | connect(n.data(), SIGNAL(completed(unsigned int)), this, SLOT(onCompleted(unsigned int))); |
246 | 150 | 150 | ||
247 | @@ -156,15 +156,15 @@ | |||
248 | 156 | // Spec forbids zero as return value. | 156 | // Spec forbids zero as return value. |
249 | 157 | if(idCounter == 0) { | 157 | if(idCounter == 0) { |
250 | 158 | idCounter = 1; | 158 | idCounter = 1; |
252 | 159 | } | 159 | } |
253 | 160 | } | 160 | } |
254 | 161 | 161 | ||
255 | 162 | QString NotificationServer::messageSender() { | 162 | QString NotificationServer::messageSender() { |
256 | 163 | QString sender(LOCAL_OWNER); | 163 | QString sender(LOCAL_OWNER); |
261 | 164 | if (calledFromDBus()) { | 164 | if (calledFromDBus()) { |
262 | 165 | sender = message().service(); | 165 | sender = message().service(); |
263 | 166 | } | 166 | } |
264 | 167 | return sender; | 167 | return sender; |
265 | 168 | } | 168 | } |
266 | 169 | 169 | ||
267 | 170 | bool NotificationServer::isCmdLine() { | 170 | bool NotificationServer::isCmdLine() { |
268 | 171 | 171 | ||
269 | === modified file 'test/CMakeLists.txt' | |||
270 | --- test/CMakeLists.txt 2015-06-01 09:42:45 +0000 | |||
271 | +++ test/CMakeLists.txt 2015-10-13 14:11:48 +0000 | |||
272 | @@ -1,4 +1,3 @@ | |||
273 | 1 | |||
274 | 2 | function(add_notification_test NAME) | 1 | function(add_notification_test NAME) |
275 | 3 | add_executable(${NAME} "${NAME}.cpp") | 2 | add_executable(${NAME} "${NAME}.cpp") |
276 | 4 | 3 | ||
277 | 5 | 4 | ||
278 | === modified file 'test/notificationtest.cpp' | |||
279 | --- test/notificationtest.cpp 2014-10-09 08:26:38 +0000 | |||
280 | +++ test/notificationtest.cpp 2015-10-13 14:11:48 +0000 | |||
281 | @@ -1,5 +1,6 @@ | |||
282 | 1 | #include "Notification.h" | 1 | #include "Notification.h" |
283 | 2 | #include "NotificationModel.h" | 2 | #include "NotificationModel.h" |
284 | 3 | #include "NotificationServer.h" | ||
285 | 3 | 4 | ||
286 | 4 | #include <QtTest/QtTest> | 5 | #include <QtTest/QtTest> |
287 | 5 | 6 | ||
288 | @@ -24,6 +25,7 @@ | |||
289 | 24 | void testConfirmationValue(); | 25 | void testConfirmationValue(); |
290 | 25 | void testTextFilter(); | 26 | void testTextFilter(); |
291 | 26 | void testTextFilter_data(); | 27 | void testTextFilter_data(); |
292 | 28 | void testReverseClose(); | ||
293 | 27 | }; | 29 | }; |
294 | 28 | 30 | ||
295 | 29 | void TestNotifications::testSimpleInsertion() { | 31 | void TestNotifications::testSimpleInsertion() { |
296 | @@ -55,43 +57,50 @@ | |||
297 | 55 | } | 57 | } |
298 | 56 | 58 | ||
299 | 57 | void TestNotifications::testOrder() { | 59 | void TestNotifications::testOrder() { |
337 | 58 | const int timeout = 5000; | 60 | const int timeout = 1000; |
338 | 59 | QSharedPointer<Notification> n1(new Notification(1, timeout, Notification::Low, "low", Notification::Ephemeral)); | 61 | static NotificationModel *m = new NotificationModel(this); |
339 | 60 | QSharedPointer<Notification> n2(new Notification(2, timeout, Notification::Normal, "high", Notification::Ephemeral)); | 62 | static NotificationServer *s = new NotificationServer(QDBusConnection::sessionBus(), *m); |
340 | 61 | QSharedPointer<Notification> n3(new Notification(3, timeout, Notification::Critical, "critical", Notification::Ephemeral)); | 63 | QStringList actions = QStringList(); |
341 | 62 | NotificationModel m; | 64 | QVariantMap hints; |
342 | 63 | 65 | int id[3]; | |
343 | 64 | m.insertNotification(n1); | 66 | |
344 | 65 | QVERIFY(m.showingNotification(n1->getID())); | 67 | hints[URGENCY_HINT] = QVariant::fromValue(Notification::Urgency::Low); |
345 | 66 | 68 | id[0] = s->Notify ("test-name-low", 0, "icon-low", "summary-low", "body-low", actions, hints, timeout); | |
346 | 67 | m.insertNotification(n2); | 69 | QVERIFY(m->showingNotification(id[0])); |
347 | 68 | QVERIFY(!m.showingNotification(n1->getID())); | 70 | |
348 | 69 | QVERIFY(m.showingNotification(n2->getID())); | 71 | hints[URGENCY_HINT] = QVariant::fromValue(Notification::Urgency::Normal); |
349 | 70 | QVERIFY(m.queued() == 1); | 72 | id[1] = s->Notify ("test-name-normal", 0, "icon-normal", "summary-normal", "body-normal", actions, hints, timeout); |
350 | 71 | 73 | QVERIFY(!m->showingNotification(id[0])); | |
351 | 72 | m.insertNotification(n3); | 74 | QVERIFY(m->showingNotification(id[1])); |
352 | 73 | QVERIFY(!m.showingNotification(n1->getID())); | 75 | QVERIFY(m->queued() == 1); |
353 | 74 | QVERIFY(!m.showingNotification(n2->getID())); | 76 | |
354 | 75 | QVERIFY(m.showingNotification(n3->getID())); | 77 | hints[URGENCY_HINT] = QVariant::fromValue(Notification::Urgency::Critical); |
355 | 76 | QCOMPARE(m.queued(), 2); | 78 | id[2] = s->Notify ("test-name-critical", 0, "icon-critical", "summary-critical", "body-critical", actions, hints, timeout); |
356 | 77 | 79 | QVERIFY(!m->showingNotification(id[0])); | |
357 | 78 | m.removeNotification(n3->getID()); | 80 | QVERIFY(!m->showingNotification(id[1])); |
358 | 79 | QVERIFY(!m.showingNotification(n1->getID())); | 81 | QVERIFY(m->showingNotification(id[2])); |
359 | 80 | QVERIFY(m.showingNotification(n2->getID())); | 82 | QCOMPARE(m->queued(), 2); |
360 | 81 | QVERIFY(!m.showingNotification(n3->getID())); | 83 | |
361 | 82 | QCOMPARE(m.queued(), 1); | 84 | m->removeNotification(id[2]); |
362 | 83 | 85 | QVERIFY(!m->showingNotification(id[0])); | |
363 | 84 | m.removeNotification(n2->getID()); | 86 | QVERIFY(m->showingNotification(id[1])); |
364 | 85 | QVERIFY(m.showingNotification(n1->getID())); | 87 | QVERIFY(!m->showingNotification(id[2])); |
365 | 86 | QVERIFY(!m.showingNotification(n2->getID())); | 88 | QCOMPARE(m->queued(), 1); |
366 | 87 | QVERIFY(!m.showingNotification(n3->getID())); | 89 | |
367 | 88 | QCOMPARE(m.queued(), 0); | 90 | m->removeNotification(id[1]); |
368 | 89 | 91 | QVERIFY(m->showingNotification(id[0])); | |
369 | 90 | m.removeNotification(n1->getID()); | 92 | QVERIFY(!m->showingNotification(id[1])); |
370 | 91 | QVERIFY(!m.showingNotification(n1->getID())); | 93 | QVERIFY(!m->showingNotification(id[2])); |
371 | 92 | QVERIFY(!m.showingNotification(n2->getID())); | 94 | QCOMPARE(m->queued(), 0); |
372 | 93 | QVERIFY(!m.showingNotification(n3->getID())); | 95 | |
373 | 94 | QCOMPARE(m.queued(), 0); | 96 | m->removeNotification(id[0]); |
374 | 97 | QVERIFY(!m->showingNotification(id[0])); | ||
375 | 98 | QVERIFY(!m->showingNotification(id[1])); | ||
376 | 99 | QVERIFY(!m->showingNotification(id[2])); | ||
377 | 100 | QCOMPARE(m->queued(), 0); | ||
378 | 101 | |||
379 | 102 | delete s; | ||
380 | 103 | delete m; | ||
381 | 95 | } | 104 | } |
382 | 96 | 105 | ||
383 | 97 | void TestNotifications::testHas() { | 106 | void TestNotifications::testHas() { |
384 | @@ -259,5 +268,38 @@ | |||
385 | 259 | QCOMPARE(n.getBody(), result); | 268 | QCOMPARE(n.getBody(), result); |
386 | 260 | } | 269 | } |
387 | 261 | 270 | ||
388 | 271 | void TestNotifications::testReverseClose() { | ||
389 | 272 | const int timeout = 1000; | ||
390 | 273 | const int max = 20; | ||
391 | 274 | static NotificationModel *m = new NotificationModel(); | ||
392 | 275 | static NotificationServer *s = new NotificationServer(QDBusConnection::sessionBus(), *m); | ||
393 | 276 | QStringList actions = QStringList(); | ||
394 | 277 | QVariantMap hints; | ||
395 | 278 | int before = m->numNotifications(); | ||
396 | 279 | |||
397 | 280 | for (int i = 1; i <= max; i++) { | ||
398 | 281 | s->Notify ("test-app-name", | ||
399 | 282 | 0, | ||
400 | 283 | "test-icon", | ||
401 | 284 | "test-summary", | ||
402 | 285 | "test-body", | ||
403 | 286 | actions, | ||
404 | 287 | hints, | ||
405 | 288 | timeout); | ||
406 | 289 | } | ||
407 | 290 | |||
408 | 291 | QCOMPARE(m->numNotifications(), max+1); | ||
409 | 292 | |||
410 | 293 | for (int i = max; i >= 1; i--) { | ||
411 | 294 | m->getNotification(i)->close(); | ||
412 | 295 | QCOMPARE(m->numNotifications(), i); | ||
413 | 296 | } | ||
414 | 297 | |||
415 | 298 | QCOMPARE(m->numNotifications(), before); | ||
416 | 299 | |||
417 | 300 | delete s; | ||
418 | 301 | delete m; | ||
419 | 302 | } | ||
420 | 303 | |||
421 | 262 | QTEST_MAIN(TestNotifications) | 304 | QTEST_MAIN(TestNotifications) |
422 | 263 | #include "notificationtest.moc" | 305 | #include "notificationtest.moc" |
When making a QSharedPointer use deleteLater, you should really pass in a custom deleter like so:
QSharedPoint er<MyClass> instance(new Myclass(param), &QObject: :deleteLater)
i.e. at object creation time. It's risky to grab the raw pointer from a shared pointer and ask it to delete at some point.