on xenial help sign in
revert notification pausing -- it needs more thinking
517e29aMichael Terry
debian/control+1−1
@@ -131,7 +131,7 @@ Depends: qml-module-qtquick-layouts,
131 qtdeclarative5-ubuntu-settings-components (>= 0.7),
131 qtdeclarative5-ubuntu-settings-components (>= 0.7),
132 qtdeclarative5-ubuntu-thumbnailer0.1 | ubuntu-thumbnailer-impl,
132 qtdeclarative5-ubuntu-thumbnailer0.1 | ubuntu-thumbnailer-impl,
133 qtdeclarative5-ubuntu-ui-toolkit-plugin (>= 1.3.1845) | qtdeclarative5-ubuntu-ui-toolkit-plugin-gles (>= 1.3.1845),
133 qtdeclarative5-ubuntu-ui-toolkit-plugin (>= 1.3.1845) | qtdeclarative5-ubuntu-ui-toolkit-plugin-gles (>= 1.3.1845),
134− qtdeclarative5-unity-notifications-plugin (>= 0.1.4) | unity-notifications-impl,
134+ qtdeclarative5-unity-notifications-plugin (>= 0.1.2) | unity-notifications-impl,
135 ubuntu-thumbnailer-impl-0,
135 ubuntu-thumbnailer-impl-0,
136 unity-application-impl-15,
136 unity-application-impl-15,
137 unity-notifications-impl-3,
137 unity-notifications-impl-3,
qml/Shell.qml−6
@@ -667,12 +667,6 @@ Item {
667 y: topmostIsFullscreen ? 0 : panel.panelHeight
667 y: topmostIsFullscreen ? 0 : panel.panelHeight
668 height: parent.height - (topmostIsFullscreen ? 0 : panel.panelHeight)
668 height: parent.height - (topmostIsFullscreen ? 0 : panel.panelHeight)
669
669
670− Binding {
671− target: NotificationBackend.Model
672− property: "paused"
673− value: tutorial.running
674− }
675−
676 states: [
670 states: [
677 State {
671 State {
678 name: "narrow"
672 name: "narrow"
tests/mocks/Unity/Notifications/MockNotificationModel.cpp+5−23
@@ -31,14 +31,14 @@
31
31
32using namespace unity::shell::notifications;
32using namespace unity::shell::notifications;
33
33
34−MockNotificationModel::MockNotificationModel(QObject *parent)
34+MockNotificationModel::MockNotificationModel(QObject *parent) : QAbstractListModel(parent) {
35− : QAbstractListModel(parent)
36− , m_paused(false)
37−{
38}
35}
39
36
40MockNotificationModel::~MockNotificationModel() {
37MockNotificationModel::~MockNotificationModel() {
38+ Q_FOREACH(MockNotification *n, m_queue) {
39+ n->deleteLater();
40+ }
41− clear();
41+ m_queue.clear();
42}
42}
43
43
44int MockNotificationModel::rowCount(const QModelIndex &) const {
44int MockNotificationModel::rowCount(const QModelIndex &) const {
@@ -89,17 +89,6 @@ QVariant MockNotificationModel::data(const QModelIndex &index, int role) const {
89 }
89 }
90}
90}
91
91
92−bool MockNotificationModel::getPaused() const {
93− return m_paused;
94−}
95−
96−void MockNotificationModel::setPaused(bool paused) {
97− if (m_paused != paused) {
98− m_paused = paused;
99− Q_EMIT pausedChanged(paused);
100− }
101−}
102−
103void MockNotificationModel::append(MockNotification* n) {
92void MockNotificationModel::append(MockNotification* n) {
104 int location = m_queue.size();
93 int location = m_queue.size();
105 QModelIndex insertionPoint = QModelIndex();
94 QModelIndex insertionPoint = QModelIndex();
@@ -118,13 +107,6 @@ MockNotification* MockNotificationModel::getNotification(int id) const {
118 return nullptr;
107 return nullptr;
119}
108}
120
109
121−void MockNotificationModel::clear() {
122− Q_FOREACH(MockNotification *n, m_queue) {
123− n->deleteLater();
124− }
125− m_queue.clear();
126−}
127−
128void MockNotificationModel::remove(const int id) {
110void MockNotificationModel::remove(const int id) {
129 for(int i = 0; i < m_queue.size(); i++) {
111 for(int i = 0; i < m_queue.size(); i++) {
130 if(m_queue[i]->getID() == id) {
112 if(m_queue[i]->getID() == id) {
tests/mocks/Unity/Notifications/MockNotificationModel.h−8
@@ -30,7 +30,6 @@ class MockNotification;
30class MockNotificationModel : public QAbstractListModel {
30class MockNotificationModel : public QAbstractListModel {
31 Q_OBJECT
31 Q_OBJECT
32 Q_PROPERTY(int count READ getCount)
32 Q_PROPERTY(int count READ getCount)
33− Q_PROPERTY(bool paused READ getPaused WRITE setPaused NOTIFY pausedChanged)
34
33
35public:
34public:
36 MockNotificationModel(QObject *parent=nullptr);
35 MockNotificationModel(QObject *parent=nullptr);
@@ -40,9 +39,6 @@ public:
40 QVariant data(const QModelIndex &index, int role) const override;
39 QVariant data(const QModelIndex &index, int role) const override;
41 QHash<int, QByteArray> roleNames() const override;
40 QHash<int, QByteArray> roleNames() const override;
42
41
43− bool getPaused() const;
44− void setPaused(bool paused);
45−
46 Q_INVOKABLE void append(MockNotification* n);
42 Q_INVOKABLE void append(MockNotification* n);
47 MockNotification* getNotification(int id) const;
43 MockNotification* getNotification(int id) const;
48
44
@@ -54,8 +50,6 @@ public:
54 Q_INVOKABLE void remove(const int id);
50 Q_INVOKABLE void remove(const int id);
55 Q_INVOKABLE void removeSecond();
51 Q_INVOKABLE void removeSecond();
56
52
57− Q_INVOKABLE void clear(); // only in mock
58−
59 int getCount() const;
53 int getCount() const;
60
54
61Q_SIGNALS:
55Q_SIGNALS:
@@ -69,11 +63,9 @@ private Q_SLOTS:
69
63
70Q_SIGNALS:
64Q_SIGNALS:
71 void queueSizeChanged(int newSize);
65 void queueSizeChanged(int newSize);
72− void pausedChanged(bool paused);
73
66
74private:
67private:
75 QList<MockNotification*> m_queue;
68 QList<MockNotification*> m_queue;
76− bool m_paused;
77 void removeInternal(int loc);
69 void removeInternal(int loc);
78};
70};
79
71
tests/mocks/Unity/Notifications/plugin.cpp+1−6
@@ -24,15 +24,10 @@
24
24
25#include <QtQml/qqml.h>
25#include <QtQml/qqml.h>
26
26
27−static QObject* modelProvider(QQmlEngine* /* engine */, QJSEngine* /* scriptEngine */)
28−{
29− return new MockNotificationModel;
30−}
31−
32void TestNotificationPlugin::registerTypes(const char* uri)
27void TestNotificationPlugin::registerTypes(const char* uri)
33{
28{
34 // @uri Unity.Notifications
29 // @uri Unity.Notifications
35 qmlRegisterType<MockNotification>(uri, 1, 0, "Notification");
30 qmlRegisterType<MockNotification>(uri, 1, 0, "Notification");
36− qmlRegisterSingletonType<MockNotificationModel>(uri, 1, 0, "Model", modelProvider);
31+ qmlRegisterType<MockNotificationModel>(uri, 1, 0, "NotificationModel");
37 qmlRegisterType<ActionModel>(uri, 1, 0, "ActionModel");
32 qmlRegisterType<ActionModel>(uri, 1, 0, "ActionModel");
38}
33}
tests/qmltests/Notifications/tst_Notifications.qml+49−45
@@ -34,19 +34,23 @@ Item {
34 Row {
34 Row {
35 id: rootRow
35 id: rootRow
36
36
37+ NotificationModel {
38+ id: mockModel
39+
37− // add the default/PlaceHolder notification to the model
40+ // add the default/PlaceHolder notification to the model
38− Component.onCompleted: {
41+ Component.onCompleted: {
39− var component = Qt.createComponent("Notification.qml")
42+ var component = Qt.createComponent("Notification.qml")
40− var n = component.createObject("notification", {"nid": index++,
43+ var n = component.createObject("notification", {"nid": index++,
41− "type": Notification.PlaceHolder,
44+ "type": Notification.PlaceHolder,
42− "hints": {},
45+ "hints": {},
43− "summary": "",
46+ "summary": "",
44− "body": "",
47+ "body": "",
45− "icon": "",
48+ "icon": "",
46− "secondaryIcon": "",
49+ "secondaryIcon": "",
47− "rawActions": []})
50+ "rawActions": []})
48− n.completed.connect(Model.onCompleted)
51+ n.completed.connect(mockModel.onCompleted)
49− Model.append(n)
52+ append(n)
53+ }
50 }
54 }
51
55
52 function add2over1SnapDecisionNotification() {
56 function add2over1SnapDecisionNotification() {
@@ -61,8 +65,8 @@ Item {
61 "rawActions": ["ok_id", "Ok",
65 "rawActions": ["ok_id", "Ok",
62 "snooze_id", "Snooze",
66 "snooze_id", "Snooze",
63 "view_id", "View"]})
67 "view_id", "View"]})
64− n.completed.connect(Model.onCompleted)
68+ n.completed.connect(mockModel.onCompleted)
65− Model.append(n)
69+ mockModel.append(n)
66 }
70 }
67
71
68 function addEphemeralNotification() {
72 function addEphemeralNotification() {
@@ -75,8 +79,8 @@ Item {
75 "icon": "../../tests/graphics/avatars/amanda.png",
79 "icon": "../../tests/graphics/avatars/amanda.png",
76 "secondaryIcon": "../../tests/graphics/applicationIcons/facebook.png",
80 "secondaryIcon": "../../tests/graphics/applicationIcons/facebook.png",
77 "rawActions": ["reply_id", "Dummy"]})
81 "rawActions": ["reply_id", "Dummy"]})
78− n.completed.connect(Model.onCompleted)
82+ n.completed.connect(mockModel.onCompleted)
79− Model.append(n)
83+ mockModel.append(n)
80 }
84 }
81
85
82 function addEphemeralNonShapedIconNotification() {
86 function addEphemeralNonShapedIconNotification() {
@@ -89,8 +93,8 @@ Item {
89 "icon": "../../tests/graphics/applicationIcons/contacts-app.png",
93 "icon": "../../tests/graphics/applicationIcons/contacts-app.png",
90 "secondaryIcon": "",
94 "secondaryIcon": "",
91 "rawActions": ["reply_id", "Dummy"]})
95 "rawActions": ["reply_id", "Dummy"]})
92− n.completed.connect(Model.onCompleted)
96+ n.completed.connect(mockModel.onCompleted)
93− Model.append(n)
97+ mockModel.append(n)
94 }
98 }
95
99
96 function addEphemeralIconSummaryNotification() {
100 function addEphemeralIconSummaryNotification() {
@@ -103,8 +107,8 @@ Item {
103 "icon": "../../tests/graphics/applicationIcons/facebook.png",
107 "icon": "../../tests/graphics/applicationIcons/facebook.png",
104 "secondaryIcon": "",
108 "secondaryIcon": "",
105 "rawActions": ["reply_id", "Dummy"]})
109 "rawActions": ["reply_id", "Dummy"]})
106− n.completed.connect(Model.onCompleted)
110+ n.completed.connect(mockModel.onCompleted)
107− Model.append(n)
111+ mockModel.append(n)
108 }
112 }
109
113
110 function addInteractiveNotification() {
114 function addInteractiveNotification() {
@@ -117,8 +121,8 @@ Item {
117 "icon": "../../tests/graphics/avatars/anna_olsson.png",
121 "icon": "../../tests/graphics/avatars/anna_olsson.png",
118 "secondaryIcon": "",
122 "secondaryIcon": "",
119 "rawActions": ["reply_id", "Dummy"]})
123 "rawActions": ["reply_id", "Dummy"]})
120− n.completed.connect(Model.onCompleted)
124+ n.completed.connect(mockModel.onCompleted)
121− Model.append(n)
125+ mockModel.append(n)
122 }
126 }
123
127
124 function addConfirmationNotification() {
128 function addConfirmationNotification() {
@@ -132,8 +136,8 @@ Item {
132 "secondaryIcon": "",
136 "secondaryIcon": "",
133 "value": 50,
137 "value": 50,
134 "rawActions": ["reply_id", "Dummy"]})
138 "rawActions": ["reply_id", "Dummy"]})
135− n.completed.connect(Model.onCompleted)
139+ n.completed.connect(mockModel.onCompleted)
136− Model.append(n)
140+ mockModel.append(n)
137 }
141 }
138
142
139 function add2ndConfirmationNotification() {
143 function add2ndConfirmationNotification() {
@@ -148,19 +152,19 @@ Item {
148 "secondaryIcon": "",
152 "secondaryIcon": "",
149 "value": 85,
153 "value": 85,
150 "rawActions": ["reply_id", "Dummy"]})
154 "rawActions": ["reply_id", "Dummy"]})
151− n.completed.connect(Model.onCompleted)
155+ n.completed.connect(mockModel.onCompleted)
152− Model.append(n)
156+ mockModel.append(n)
153 }
157 }
154
158
155 function clearNotifications() {
159 function clearNotifications() {
156− while(Model.count > 1) {
160+ while(mockModel.count > 1) {
157 remove1stNotification()
161 remove1stNotification()
158 }
162 }
159 }
163 }
160
164
161 function remove1stNotification() {
165 function remove1stNotification() {
162− if (Model.count > 1) {
166+ if (mockModel.count > 1) {
163− Model.removeSecond()
167+ mockModel.removeSecond()
164 }
168 }
165 }
169 }
166
170
@@ -182,7 +186,7 @@ Item {
182 margin: units.gu(1)
186 margin: units.gu(1)
183
187
184 anchors.fill: parent
188 anchors.fill: parent
185− model: Model
189+ model: mockModel
186 hasMouse: fakeMouseCB.checked
190 hasMouse: fakeMouseCB.checked
187 inverseMode: inverseModeCB.checked
191 inverseMode: inverseModeCB.checked
188 }
192 }
@@ -554,7 +558,7 @@ Item {
554 SignalSpy {
558 SignalSpy {
555 id: actionSpy
559 id: actionSpy
556
560
557− target: Model
561+ target: mockModel
558 signalName: "actionInvoked"
562 signalName: "actionInvoked"
559 }
563 }
560
564
@@ -565,19 +569,19 @@ Item {
565
569
566 function test_NotificationRenderer(data) {
570 function test_NotificationRenderer(data) {
567 // make sure the clicks on mocked notifications can be checked against by "actionSpy" (mimicking the NotificationServer component)
571 // make sure the clicks on mocked notifications can be checked against by "actionSpy" (mimicking the NotificationServer component)
568− data.n.actionInvoked.connect(Model.actionInvoked)
572+ data.n.actionInvoked.connect(mockModel.actionInvoked)
569
573
570 // hook up notification's completed-signal with model's onCompleted-slot, so that remove() (model) happens on close() (notification)
574 // hook up notification's completed-signal with model's onCompleted-slot, so that remove() (model) happens on close() (notification)
571− data.n.completed.connect(Model.onCompleted)
575+ data.n.completed.connect(mockModel.onCompleted)
572
576
573 // populate model with some mock notifications
577 // populate model with some mock notifications
574− Model.append(data.n)
578+ mockModel.append(data.n)
575
579
576 // make sure the view is properly updated before going on
580 // make sure the view is properly updated before going on
577 notifications.forceLayout();
581 notifications.forceLayout();
578 waitForRendering(notifications);
582 waitForRendering(notifications);
579
583
580− var notification = findChild(notifications, "notification" + (Model.count - 1))
584+ var notification = findChild(notifications, "notification" + (mockModel.count - 1))
581 verify(notification !== undefined, "notification wasn't found");
585 verify(notification !== undefined, "notification wasn't found");
582
586
583 waitForRendering(notification);
587 waitForRendering(notification);
@@ -623,7 +627,7 @@ Item {
623
627
624 // After clicking the state of notifications can change so let's wait
628 // After clicking the state of notifications can change so let's wait
625 // for their height animations to finish before continuing
629 // for their height animations to finish before continuing
626− for (var i = 0; i < Model.count; ++i) {
630+ for (var i = 0; i < mockModel.count; ++i) {
627 var n = findChild(notifications, "notification" + i)
631 var n = findChild(notifications, "notification" + i)
628 tryCompare(n, "height", n.state === "contracted" ? units.gu(10) : n.implicitHeight);
632 tryCompare(n, "height", n.state === "contracted" ? units.gu(10) : n.implicitHeight);
629 }
633 }
@@ -681,16 +685,16 @@ Item {
681
685
682 // swipe-to-dismiss check
686 // swipe-to-dismiss check
683 waitForRendering(notification)
687 waitForRendering(notification)
684− var before = Model.count
688+ var before = mockModel.count
685 var dragStart = notification.width * 0.25;
689 var dragStart = notification.width * 0.25;
686 var dragEnd = notification.width;
690 var dragEnd = notification.width;
687 var dragY = notification.height / 2;
691 var dragY = notification.height / 2;
688 touchFlick(notification, dragStart, dragY, dragEnd, dragY)
692 touchFlick(notification, dragStart, dragY, dragEnd, dragY)
689 waitForRendering(notification)
693 waitForRendering(notification)
690 if ((data.n.type === Notification.SnapDecision && notification.state === "expanded") || data.n.type === Notification.Confirmation) {
694 if ((data.n.type === Notification.SnapDecision && notification.state === "expanded") || data.n.type === Notification.Confirmation) {
691− tryCompare(Model, "count", before)
695+ tryCompare(mockModel, "count", before)
692 } else {
696 } else {
693− tryCompare(Model, "count", before - 1)
697+ tryCompare(mockModel, "count", before - 1)
694 }
698 }
695 }
699 }
696
700
@@ -701,27 +705,27 @@ Item {
701
705
702 function test_clickToClose(data) {
706 function test_clickToClose(data) {
703 // populate model with some mock notifications
707 // populate model with some mock notifications
704− Model.append(data.n)
708+ mockModel.append(data.n)
705
709
706 // make sure the view is properly updated before going on
710 // make sure the view is properly updated before going on
707 notifications.forceLayout();
711 notifications.forceLayout();
708 waitForRendering(notifications);
712 waitForRendering(notifications);
709
713
710− var notification = findChild(notifications, "notification" + (Model.count - 1))
714+ var notification = findChild(notifications, "notification" + (mockModel.count - 1))
711 verify(!!notification, "notification wasn't found");
715 verify(!!notification, "notification wasn't found");
712
716
713 // click-to-dismiss check
717 // click-to-dismiss check
714 waitForRendering(notification);
718 waitForRendering(notification);
715− var before = Model.count;
719+ var before = mockModel.count;
716 var canBeClosed = notification.canBeClosed;
720 var canBeClosed = notification.canBeClosed;
717 mouseClick(notification);
721 mouseClick(notification);
718
722
719 if (canBeClosed) {
723 if (canBeClosed) {
720 // closing the notification, the model count should be one less
724 // closing the notification, the model count should be one less
721− tryCompare(Model, "count", before - 1)
725+ tryCompare(mockModel, "count", before - 1)
722 } else {
726 } else {
723 // not closing, model stays the same
727 // not closing, model stays the same
724− tryCompare(Model, "count", before)
728+ tryCompare(mockModel, "count", before)
725 }
729 }
726 }
730 }
727
731
tests/qmltests/Tutorial/tst_Tutorial.qml+24−13
@@ -22,7 +22,7 @@ import Ubuntu.Components 1.3
22import Ubuntu.Components.ListItems 1.3
22import Ubuntu.Components.ListItems 1.3
23import Ubuntu.Telephony 0.1 as Telephony
23import Ubuntu.Telephony 0.1 as Telephony
24import Unity.Application 0.1
24import Unity.Application 0.1
25−import Unity.Notifications 1.0 as NotificationBackend
25+import Unity.Notifications 1.0
26import Unity.Test 0.1 as UT
26import Unity.Test 0.1 as UT
27import Utils 0.1
27import Utils 0.1
28
28
@@ -57,21 +57,30 @@ Rectangle {
57 }
57 }
58
58
59 Component {
59 Component {
60− id: notification
60+ id: mockNotification
61− NotificationBackend.Notification {
61+ QtObject {}
62− nid: 1
62+ }
63− type: NotificationBackend.Notification.Confirmation
63+
64− summary: ""
64+ ListModel {
65− body: ""
65+ id: mockNotificationsModel
66− icon: ""
66+
67− secondaryIcon: ""
67+ function getRaw(id) {
68− value: 0
68+ return mockNotification.createObject(mockNotificationsModel)
69− rawActions: []
70 }
69 }
71 }
70 }
72
71
73 function addNotification() {
72 function addNotification() {
74− NotificationBackend.Model.append(notification.createObject());
73+ var n = {
74+ type: Notification.Confirmation,
75+ hints: {},
76+ summary: "",
77+ body: "",
78+ icon: "",
79+ secondaryIcon: "",
80+ actions: []
81+ };
82+
83+ mockNotificationsModel.append(n);
75 }
84 }
76
85
77 Component.onCompleted: {
86 Component.onCompleted: {
@@ -277,11 +286,11 @@ Rectangle {
277
286
278 // kill all (fake) running apps
287 // kill all (fake) running apps
279 killApps();
288 killApps();
280− NotificationBackend.Model.clear();
281
289
282 // reload our test subject to get it in a fresh state once again
290 // reload our test subject to get it in a fresh state once again
283 shellLoader.active = true;
291 shellLoader.active = true;
284
292
293+ mockNotificationsModel.clear();
285 tryCompare(shellLoader, "status", Loader.Ready);
294 tryCompare(shellLoader, "status", Loader.Ready);
286 removeTimeConstraintsFromDirectionalDragAreas(shellLoader.item);
295 removeTimeConstraintsFromDirectionalDragAreas(shellLoader.item);
287 }
296 }
@@ -723,6 +732,8 @@ Rectangle {
723 var tutorial = findChild(shell, "tutorial");
732 var tutorial = findChild(shell, "tutorial");
724 verify(!tutorial.delayed);
733 verify(!tutorial.delayed);
725
734
735+ var notifications = findChild(shell, "notificationList");
736+ notifications.model = mockNotificationsModel;
726 addNotification();
737 addNotification();
727
738
728 tryCompare(tutorial, "delayed", true);
739 tryCompare(tutorial, "delayed", true);
tests/qmltests/tst_Shell.qml+1−18
@@ -25,7 +25,7 @@ import Ubuntu.Telephony 0.1 as Telephony
25import Unity.Application 0.1
25import Unity.Application 0.1
26import Unity.Connectivity 0.1
26import Unity.Connectivity 0.1
27import Unity.Indicators 0.1
27import Unity.Indicators 0.1
28−import Unity.Notifications 1.0 as NotificationBackend
28+import Unity.Notifications 1.0
29import Unity.Launcher 0.1
29import Unity.Launcher 0.1
30import Unity.Test 0.1
30import Unity.Test 0.1
31import Powerd 0.1
31import Powerd 0.1
@@ -349,8 +349,6 @@ Rectangle {
349 ListModel {
349 ListModel {
350 id: mockNotificationsModel
350 id: mockNotificationsModel
351
351
352− property bool paused
353−
354 signal actionInvoked(string actionId)
352 signal actionInvoked(string actionId)
355
353
356 function getRaw(id) {
354 function getRaw(id) {
@@ -1289,21 +1287,6 @@ Rectangle {
1289 tryCompare(tutorial, "paused", false);
1287 tryCompare(tutorial, "paused", false);
1290 }
1288 }
1291
1289
1292− function test_notificationsPausedDuringTutorial() {
1293− loadShell("phone");
1294− swipeAwayGreeter();
1295− verify(!NotificationBackend.Model.paused);
1296−
1297− AccountsService.demoEdges = true;
1298− var tutorialLeft = findChild(shell, "tutorialLeft");
1299− var tutorialLeftTimer = findInvisibleChild(tutorialLeft, "tutorialLeftTimer");
1300− tutorialLeftTimer.interval = 0;
1301− tryCompare(NotificationBackend.Model, "paused", true);
1302−
1303− AccountsService.demoEdges = false;
1304− tryCompare(NotificationBackend.Model, "paused", false);
1305− }
1306−
1307 function test_tapOnRightEdgeReachesApplicationSurface() {
1290 function test_tapOnRightEdgeReachesApplicationSurface() {
1308 loadShell("phone");
1291 loadShell("phone");
1309 swipeAwayGreeter();
1292 swipeAwayGreeter();