Merge lp:~dandrader/unity8/runningAppsEndClose into lp:unity8
- runningAppsEndClose
- Merge into trunk
Status: | Superseded |
---|---|
Proposed branch: | lp:~dandrader/unity8/runningAppsEndClose |
Merge into: | lp:unity8 |
Diff against target: |
1251 lines (+607/-131) 15 files modified
Dash/Apps/RunningApplicationsGrid.qml (+18/-11) Dash/DashApps.qml (+0/-1) Dash/GenericScopeView.qml (+0/-1) plugins/Ubuntu/Gestures/CMakeLists.txt (+1/-0) plugins/Ubuntu/Gestures/PressedOutsideNotifier.cpp (+118/-0) plugins/Ubuntu/Gestures/PressedOutsideNotifier.h (+62/-0) plugins/Ubuntu/Gestures/plugin.cpp (+2/-0) tests/plugins/Ubuntu/Gestures/CMakeLists.txt (+21/-18) tests/plugins/Ubuntu/Gestures/GestureTest.cpp (+44/-0) tests/plugins/Ubuntu/Gestures/GestureTest.h (+44/-0) tests/plugins/Ubuntu/Gestures/tst_DirectionalDragArea.cpp (+67/-99) tests/plugins/Ubuntu/Gestures/tst_PressedOutsideNotifier.cpp (+146/-0) tests/plugins/Ubuntu/Gestures/tst_PressedOutsideNotifier.qml (+61/-0) tests/qmltests/CMakeLists.txt (+3/-1) tests/qmltests/Dash/Apps/tst_RunningApplicationsGrid.qml (+20/-0) |
To merge this branch: | bzr merge lp:~dandrader/unity8/runningAppsEndClose |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
PS Jenkins bot (community) | continuous-integration | Approve | |
Michał Sawicz | Needs Information | ||
Review via email: mp+196006@code.launchpad.net |
This proposal has been superseded by a proposal from 2013-11-22.
Commit message
Dash: disable app termination mode on click outside thumbnails
To leave the termination mode you can now just mouse/touch press anywhere
outside the running applications' thumbnails
The other way, which still works, is long-pressing a thumbnail once more.
Description of the change
Fixes bug 1193414.
InverseMouseArea is not fit for this job (e.g. doesn't work with touches when in topMostMode), thus I created a simple, light-weight, PressedOutsideN
Most of the diff is about tests and some test refactoring.
PS Jenkins bot (ps-jenkins) wrote : | # |
- 542. By Albert Astals Cid
-
Do not include the QtQml megaheader
Include only qqml.h which is what we need in these files.
Approved by PS Jenkins bot, Michał Sawicz.
Michał Sawicz (saviq) wrote : | # |
tst_PressedOuts
BUT... Isn't InverseMouseArea supposed to do the same thing?
- 543. By Launchpad Translations on behalf of unity-team
-
Launchpad automatic translations update.
Daniel d'Andrada (dandrader) wrote : | # |
> tst_PressedOuts
Fixed.
> BUT... Isn't InverseMouseArea supposed to do the same thing?
Kind-of, but it's hindered by all the promises its API makes (it's a bit of a mess IMHO) and doesn't really work for that case. Have you read the description?
e.g.: It would have, for instance, to monitor touch events and translate them to mouse events himself because it's a Inverse*Mouse*Area. When its topMost property is on it listens for input events at a level before QQuickWindow is able to synthesize touch events out of mouse events.
Thus instead of trying to have it working for our case it's easier to come up with something concise and simple designed to fit perfectly with our needs. Since we're not a library, we're free to do this kind of things, which is good.
I don't see the point in striving to use InverseMouseArea just for the sake of using it because it already exists. If it's about improving InverseMouseArea itself, I'm not too hopeful.
Albert Astals Cid (aacid) wrote : | # |
> e.g.: It would have, for instance, to monitor touch events and translate them
> to mouse events himself because it's a Inverse*Mouse*Area. When its topMost
> property is on it listens for input events at a level before QQuickWindow is
> able to synthesize touch events out of mouse events.
But didn't you have a patch for Qt to fix that?
Daniel d'Andrada (dandrader) wrote : | # |
> > e.g.: It would have, for instance, to monitor touch events and translate
> them
> > to mouse events himself because it's a Inverse*Mouse*Area. When its topMost
> > property is on it listens for input events at a level before QQuickWindow is
> > able to synthesize touch events out of mouse events.
>
> But didn't you have a patch for Qt to fix that?
No. That's a different topic. But maybe InverseMouseArea does it to workaround that bug.
Albert Astals Cid (aacid) wrote : | # |
> > > e.g.: It would have, for instance, to monitor touch events and translate
> > them
> > > to mouse events himself because it's a Inverse*Mouse*Area. When its
> topMost
> > > property is on it listens for input events at a level before QQuickWindow
> is
> > > able to synthesize touch events out of mouse events.
> >
> > But didn't you have a patch for Qt to fix that?
>
> No. That's a different topic. But maybe InverseMouseArea does it to workaround
> that bug.
Oh, it was my understanding that you where making the synthezised events go properly through the event stack again and thus they'd be caught by the InverseMouseArea and everything would just work.
Daniel d'Andrada (dandrader) wrote : | # |
> > > > e.g.: It would have, for instance, to monitor touch events and translate
> > > them
> > > > to mouse events himself because it's a Inverse*Mouse*Area. When its
> > topMost
> > > > property is on it listens for input events at a level before
> QQuickWindow
> > is
> > > > able to synthesize touch events out of mouse events.
> > >
> > > But didn't you have a patch for Qt to fix that?
> >
> > No. That's a different topic. But maybe InverseMouseArea does it to
> workaround
> > that bug.
>
> Oh, it was my understanding that you where making the synthezised events go
> properly through the event stack again and thus they'd be caught by the
> InverseMouseArea and everything would just work.
A topMost InverseMouseArea listens for events at QGuiApplication level (a bad idea, IMHO). synthesized mouse events from QQuickWindow will never to that high up, and they shouldn't.
- 544. By Omer Akram
-
make the non working code in the screen unlocker helper work.
Approved by PS Jenkins bot, Christopher Lee, Michael Zanetti.
Daniel d'Andrada (dandrader) wrote : | # |
> > > > > e.g.: It would have, for instance, to monitor touch events and
> translate
> > > > them
> > > > > to mouse events himself because it's a Inverse*Mouse*Area. When its
> > > topMost
> > > > > property is on it listens for input events at a level before
> > QQuickWindow
> > > is
> > > > > able to synthesize touch events out of mouse events.
> > > >
> > > > But didn't you have a patch for Qt to fix that?
> > >
> > > No. That's a different topic. But maybe InverseMouseArea does it to
> > workaround
> > > that bug.
> >
> > Oh, it was my understanding that you where making the synthezised events go
> > properly through the event stack again and thus they'd be caught by the
> > InverseMouseArea and everything would just work.
>
> A topMost InverseMouseArea listens for events at QGuiApplication level (a bad
> idea, IMHO). synthesized mouse events from QQuickWindow will never to that
> high up, and they shouldn't.
And even if it listened at the right level (rootItem), it still wouldn't work if there a touch-aware item in the scene that accepts the touches. In that situation QQuickWindow wound't synthesize mouse events out of the touch events because there's no need to.
Albert Astals Cid (aacid) wrote : | # |
ok, in my opinion we should still fix InverseMouseArea to do what we want, i mean, what about all the other people out there that want to do exactly this? InverseMouseArea is supposed to do it, so why not fix it and then use it?
Daniel d'Andrada (dandrader) wrote : | # |
> And even if it listened at the right level (rootItem), it still wouldn't work
> if there a touch-aware item in the scene that accepts the touches. In that
> situation QQuickWindow wound't synthesize mouse events out of the touch events
> because there's no need to.
Ah, and for listening at the "right level", that's when you would need my fix.
Daniel d'Andrada (dandrader) wrote : | # |
> ok, in my opinion we should still fix InverseMouseArea to do what we want, i
> mean, what about all the other people out there that want to do exactly this?
> InverseMouseArea is supposed to do it, so why not fix it and then use it?
Can't we do both?
1 - fix our UI *now*, which is what matters to the final user and people trying to sell our phone demoing it.
2 - Fix InverseMouseArea, so that application developer have better building blocks to build their ubuntu apps.
The thing is that item 2 requires much work because InverseMouseArea is meant to cover much more cases and has a more complex API. And we might have to sit around until my QQuickItem event dispatch fix is available in ubuntu repos, translating into even more time.
Item 1 is what the bug that this patch fixes is all about.
Item 2 is a bonus.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:538
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
UNSTABLE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 545. By Nicolas d'Offay
-
Search history is now persistent across all scopes and remains in QML. Fixes: https:/
/bugs.launchpad .net/bugs/ 1226221. Approved by PS Jenkins bot, Albert Astals Cid.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:539
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:539
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 546. By Albert Astals Cid
-
Don't do stuff if our parent context is gone
We'll be gone soon too (and crash probably) so don't do anything.
This looks a bit like a workaround, wait for 5.2 better painting/dispatching
loop to see if this is not needed anymore, we find a better way to do it,
or we decide this is fine.Approved by PS Jenkins bot, Nick Dedekind.
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:539
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 547. By Michael Zanetti
-
drop all references to LighDM from the Lockscreen
This should make it generic enough to allow reusing it for SIM PIN entry
.Approved by PS Jenkins bot, Mirco Müller.
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:539
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 548. By Lars Karlitski
-
Allow setting different indicator positions for different profiles.
Approved by PS Jenkins bot, Nick Dedekind.
Michał Sawicz (saviq) wrote : | # |
Please split out the unrelated refactoring changes into a separate MP.
- 549. By Mirco Müller
-
Fixes bug #1200569. Fixes: https:/
/bugs.launchpad .net/bugs/ 1200569. Approved by PS Jenkins bot, Michael Zanetti.
- 550. By Daniel d'Andrada
-
Refactor Ubuntu.Gesture tests to share common logic
Take the common part out of tst_Directional
DragArea and put
it into a separate base class, GestureTest, so that it can
be shared with other, future, tests.In CMakeLists.txt, create a macro out of DirectionalDragArea build script
to be used by future tests with similar requirements and structure.Also add the "m_" prefix to member variables.
Daniel d'Andrada (dandrader) wrote : | # |
> Please split out the unrelated refactoring changes into a separate MP.
And there it is:
https:/
- 551. By Daniel d'Andrada
-
More GestureTest and tst_Directional
DragArea refactoring - Move more stuff to GestureTest base class
- add tryFoo make command
- Let the qml file dictate the scene/window size, not the c++ code - 552. By Daniel d'Andrada
-
Some string-related improvements
- Use QString instead of raw char array
- s/QLatin1String/QStringLiteral to optimize code - 553. By Daniel d'Andrada
-
Dash: disable app termination mode on click outside thumbnails
To leave the termination mode you can now just mouse/touch press anywhere
outside the running applications' thumbnailsThe other way, which still works, is long-pressing a thumbnail once more.
- 554. By Daniel d'Andrada
-
Put canEnableTermin
ationMode stuff back To cover a minor "visual glitch" in a specific corner case
- 555. By Daniel d'Andrada
-
Add a Q_ASSERT to state that we really don't expect it to be null
as opposed to "we forget to handle the null case"
Unmerged revisions
Preview Diff
1 | === modified file 'Dash/Apps/RunningApplicationsGrid.qml' |
2 | --- Dash/Apps/RunningApplicationsGrid.qml 2013-10-02 11:01:49 +0000 |
3 | +++ Dash/Apps/RunningApplicationsGrid.qml 2013-11-22 10:45:28 +0000 |
4 | @@ -17,6 +17,8 @@ |
5 | import QtQuick 2.0 |
6 | import "../../Components" |
7 | |
8 | +import Ubuntu.Gestures 0.1 |
9 | + |
10 | ResponsiveFlowView { |
11 | id: root |
12 | clip: true |
13 | @@ -50,13 +52,6 @@ |
14 | } |
15 | } |
16 | |
17 | - property bool canEnableTerminationMode: true |
18 | - |
19 | - onCanEnableTerminationModeChanged: { |
20 | - if (!canEnableTerminationMode) |
21 | - terminationModeEnabled = false |
22 | - } |
23 | - |
24 | // when false, it means it's on activation mode |
25 | property bool terminationModeEnabled: false |
26 | |
27 | @@ -78,10 +73,7 @@ |
28 | } |
29 | application: model |
30 | onRequestedActivationMode: { root.terminationModeEnabled = false } |
31 | - onRequestedTerminationMode: { |
32 | - if (canEnableTerminationMode) |
33 | - root.terminationModeEnabled = true |
34 | - } |
35 | + onRequestedTerminationMode: { root.terminationModeEnabled = true } |
36 | onRequestedApplicationTermination: { |
37 | shell.applicationManager.stopApplication(model.appId) |
38 | } |
39 | @@ -100,4 +92,19 @@ |
40 | move: Transition { |
41 | NumberAnimation { properties: "x,y"; duration: 400; easing.type: Easing.OutCubic } |
42 | } |
43 | + |
44 | + MouseArea { |
45 | + anchors.fill: parent |
46 | + z: -1 // behind all RunningApplicationTiles |
47 | + enabled: root.terminationModeEnabled |
48 | + onPressed: { root.terminationModeEnabled = false; } |
49 | + } |
50 | + |
51 | + PressedOutsideNotifier { |
52 | + anchors.fill: parent |
53 | + enabled: root.terminationModeEnabled |
54 | + onPressedOutside: { |
55 | + root.terminationModeEnabled = false; |
56 | + } |
57 | + } |
58 | } |
59 | |
60 | === modified file 'Dash/DashApps.qml' |
61 | --- Dash/DashApps.qml 2013-11-11 10:24:51 +0000 |
62 | +++ Dash/DashApps.qml 2013-11-22 10:45:28 +0000 |
63 | @@ -44,7 +44,6 @@ |
64 | |
65 | property var firstModel: mainStageApplicationsModel |
66 | property var secondModel: sideStageApplicationModel |
67 | - property bool canEnableTerminationMode: scopeView.isCurrent |
68 | |
69 | model: dummyVisibilityModifier |
70 | filterRole: 0 |
71 | |
72 | === modified file 'Dash/GenericScopeView.qml' |
73 | --- Dash/GenericScopeView.qml 2013-11-19 14:33:40 +0000 |
74 | +++ Dash/GenericScopeView.qml 2013-11-22 10:45:28 +0000 |
75 | @@ -151,7 +151,6 @@ |
76 | // TODO: the running apps grid doesn't support standard scope results model yet |
77 | item.firstModel = Qt.binding(function() { return results.firstModel }) |
78 | item.secondModel = Qt.binding(function() { return results.secondModel }) |
79 | - item.canEnableTerminationMode = Qt.binding(function() { return scopeView.isCurrent }) |
80 | } else { |
81 | item.model = Qt.binding(function() { return results }) |
82 | } |
83 | |
84 | === modified file 'plugins/Ubuntu/Gestures/CMakeLists.txt' |
85 | --- plugins/Ubuntu/Gestures/CMakeLists.txt 2013-10-22 15:56:37 +0000 |
86 | +++ plugins/Ubuntu/Gestures/CMakeLists.txt 2013-11-22 10:45:28 +0000 |
87 | @@ -6,6 +6,7 @@ |
88 | AxisVelocityCalculator.cpp |
89 | Direction.cpp |
90 | DirectionalDragArea.cpp |
91 | + PressedOutsideNotifier.cpp |
92 | TimeSource.cpp |
93 | ) |
94 | |
95 | |
96 | === added file 'plugins/Ubuntu/Gestures/PressedOutsideNotifier.cpp' |
97 | --- plugins/Ubuntu/Gestures/PressedOutsideNotifier.cpp 1970-01-01 00:00:00 +0000 |
98 | +++ plugins/Ubuntu/Gestures/PressedOutsideNotifier.cpp 2013-11-22 10:45:28 +0000 |
99 | @@ -0,0 +1,118 @@ |
100 | +/* |
101 | + * Copyright (C) 2013 Canonical, Ltd. |
102 | + * |
103 | + * This program is free software; you can redistribute it and/or modify |
104 | + * it under the terms of the GNU General Public License as published by |
105 | + * the Free Software Foundation; version 3. |
106 | + * |
107 | + * This program is distributed in the hope that it will be useful, |
108 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
109 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
110 | + * GNU General Public License for more details. |
111 | + * |
112 | + * You should have received a copy of the GNU General Public License |
113 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
114 | + */ |
115 | + |
116 | +#include "PressedOutsideNotifier.h" |
117 | + |
118 | +#include <QMouseEvent> |
119 | + |
120 | +PressedOutsideNotifier::PressedOutsideNotifier(QQuickItem *parent) |
121 | + : QQuickItem(parent) |
122 | +{ |
123 | + connect(this, &QQuickItem::enabledChanged, |
124 | + this, &PressedOutsideNotifier::setupOrTearDownEventFiltering); |
125 | + |
126 | + m_signalEmissionTimer.setSingleShot(true); |
127 | + m_signalEmissionTimer.setInterval(0); // times out on the next iteration of the event loop |
128 | + connect(&m_signalEmissionTimer, &QTimer::timeout, |
129 | + this, &PressedOutsideNotifier::pressedOutside); |
130 | +} |
131 | + |
132 | +bool PressedOutsideNotifier::eventFilter(QObject *watched, QEvent *event) |
133 | +{ |
134 | + Q_UNUSED(watched); |
135 | + Q_ASSERT(watched == m_filteredWindow); |
136 | + |
137 | + // We are already going to emit pressedOutside() anyway, thus no need |
138 | + // for new checks. |
139 | + // This case takes place when a QTouchEvent comes in and isn't handled by any item, |
140 | + // causing QQuickWindow to synthesize a QMouseEvent out of it, which would |
141 | + // be filtered by us as well and count as a second press, which is wrong. |
142 | + if (m_signalEmissionTimer.isActive()) { |
143 | + return false; |
144 | + } |
145 | + |
146 | + switch (event->type()) { |
147 | + case QEvent::MouseButtonPress: { |
148 | + QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event); |
149 | + QPointF p = mapFromScene(mouseEvent->windowPos()); |
150 | + if (!contains(p)) { |
151 | + m_signalEmissionTimer.start(); |
152 | + } |
153 | + break; |
154 | + } |
155 | + case QEvent::TouchBegin: |
156 | + processFilteredTouchBegin(static_cast<QTouchEvent*>(event)); |
157 | + default: |
158 | + break; |
159 | + } |
160 | + |
161 | + // let the event be handled further |
162 | + return false; |
163 | +} |
164 | + |
165 | +void PressedOutsideNotifier::itemChange(ItemChange change, const ItemChangeData &value) |
166 | +{ |
167 | + if (change == QQuickItem::ItemSceneChange) { |
168 | + setupOrTearDownEventFiltering(); |
169 | + } |
170 | + |
171 | + QQuickItem::itemChange(change, value); |
172 | +} |
173 | + |
174 | +void PressedOutsideNotifier::setupOrTearDownEventFiltering() |
175 | +{ |
176 | + if (isEnabled() && window()) { |
177 | + setupEventFiltering(); |
178 | + } else if (m_filteredWindow) { |
179 | + tearDownEventFiltering(); |
180 | + } |
181 | +} |
182 | + |
183 | +void PressedOutsideNotifier::setupEventFiltering() |
184 | +{ |
185 | + QQuickWindow *currentWindow = window(); |
186 | + |
187 | + if (currentWindow == m_filteredWindow) |
188 | + return; |
189 | + |
190 | + if (m_filteredWindow) { |
191 | + m_filteredWindow->removeEventFilter(this); |
192 | + } |
193 | + |
194 | + currentWindow->installEventFilter(this); |
195 | + m_filteredWindow = currentWindow; |
196 | +} |
197 | + |
198 | +void PressedOutsideNotifier::tearDownEventFiltering() |
199 | +{ |
200 | + m_filteredWindow->removeEventFilter(this); |
201 | + m_filteredWindow.clear(); |
202 | +} |
203 | + |
204 | +void PressedOutsideNotifier::processFilteredTouchBegin(QTouchEvent *event) |
205 | +{ |
206 | + const QList<QTouchEvent::TouchPoint> &touchPoints = event->touchPoints(); |
207 | + for (int i = 0; i < touchPoints.count(); ++i) { |
208 | + const QTouchEvent::TouchPoint &touchPoint = touchPoints.at(i); |
209 | + if (touchPoint.state() == Qt::TouchPointPressed) { |
210 | + QPointF p = mapFromScene(touchPoint.pos()); |
211 | + if (!contains(p)) { |
212 | + m_signalEmissionTimer.start(); |
213 | + return; |
214 | + } |
215 | + } |
216 | + } |
217 | +} |
218 | |
219 | === added file 'plugins/Ubuntu/Gestures/PressedOutsideNotifier.h' |
220 | --- plugins/Ubuntu/Gestures/PressedOutsideNotifier.h 1970-01-01 00:00:00 +0000 |
221 | +++ plugins/Ubuntu/Gestures/PressedOutsideNotifier.h 2013-11-22 10:45:28 +0000 |
222 | @@ -0,0 +1,62 @@ |
223 | +/* |
224 | + * Copyright (C) 2013 Canonical, Ltd. |
225 | + * |
226 | + * This program is free software; you can redistribute it and/or modify |
227 | + * it under the terms of the GNU General Public License as published by |
228 | + * the Free Software Foundation; version 3. |
229 | + * |
230 | + * This program is distributed in the hope that it will be useful, |
231 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
232 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
233 | + * GNU General Public License for more details. |
234 | + * |
235 | + * You should have received a copy of the GNU General Public License |
236 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
237 | + */ |
238 | + |
239 | +#ifndef PRESSED_OUTSIDE_NOTIFIER_H |
240 | +#define PRESSED_OUTSIDE_NOTIFIER_H |
241 | + |
242 | +#include <QQuickItem> |
243 | + |
244 | +#include <QQuickWindow> |
245 | +#include <QPointer> |
246 | +#include <QTimer> |
247 | + |
248 | +#include "UbuntuGesturesGlobal.h" |
249 | + |
250 | +/* |
251 | + Notifies when a point, mouse or touch, is pressed outside its area. |
252 | + |
253 | + Only enable it while needed. |
254 | + */ |
255 | +class UBUNTUGESTURES_EXPORT PressedOutsideNotifier : public QQuickItem { |
256 | + Q_OBJECT |
257 | + |
258 | +public: |
259 | + PressedOutsideNotifier(QQuickItem * parent = nullptr); |
260 | + |
261 | + // From QObject |
262 | + bool eventFilter(QObject *watched, QEvent *event) override; |
263 | + |
264 | +Q_SIGNALS: |
265 | + void pressedOutside(); |
266 | + |
267 | +protected: |
268 | + void itemChange(ItemChange change, const ItemChangeData &value) override; |
269 | + |
270 | +private Q_SLOTS: |
271 | + void setupOrTearDownEventFiltering(); |
272 | + |
273 | +private: |
274 | + void setupEventFiltering(); |
275 | + void tearDownEventFiltering(); |
276 | + void processFilteredTouchBegin(QTouchEvent *event); |
277 | + |
278 | + QPointer<QQuickWindow> m_filteredWindow; |
279 | + |
280 | + // Emits pressedOutside() signal on timeout |
281 | + QTimer m_signalEmissionTimer; |
282 | +}; |
283 | + |
284 | +#endif // PRESSED_OUTSIDE_NOTIFIER_H |
285 | |
286 | === modified file 'plugins/Ubuntu/Gestures/plugin.cpp' |
287 | --- plugins/Ubuntu/Gestures/plugin.cpp 2013-06-17 13:45:28 +0000 |
288 | +++ plugins/Ubuntu/Gestures/plugin.cpp 2013-11-22 10:45:28 +0000 |
289 | @@ -18,6 +18,7 @@ |
290 | #include "AxisVelocityCalculator.h" |
291 | #include "Direction.h" |
292 | #include "DirectionalDragArea.h" |
293 | +#include "PressedOutsideNotifier.h" |
294 | |
295 | #include <qqml.h> |
296 | |
297 | @@ -32,4 +33,5 @@ |
298 | qmlRegisterSingletonType<Direction>(uri, 0, 1, "Direction", directionSingleton); |
299 | qmlRegisterType<DirectionalDragArea>(uri, 0, 1, "DirectionalDragArea"); |
300 | qmlRegisterType<AxisVelocityCalculator>(uri, 0, 1, "AxisVelocityCalculator"); |
301 | + qmlRegisterType<PressedOutsideNotifier>(uri, 0, 1, "PressedOutsideNotifier"); |
302 | } |
303 | |
304 | === modified file 'tests/plugins/Ubuntu/Gestures/CMakeLists.txt' |
305 | --- tests/plugins/Ubuntu/Gestures/CMakeLists.txt 2013-06-11 18:22:43 +0000 |
306 | +++ tests/plugins/Ubuntu/Gestures/CMakeLists.txt 2013-11-22 10:45:28 +0000 |
307 | @@ -1,33 +1,33 @@ |
308 | -########## tst_DirectionalDragArea |
309 | +include(QmlTest) |
310 | |
311 | include_directories( |
312 | ${CMAKE_SOURCE_DIR}/plugins/Ubuntu/Gestures |
313 | ${CMAKE_CURRENT_BINARY_DIR} |
314 | ) |
315 | |
316 | -set(testCommand |
317 | - LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/plugins/Ubuntu/Gestures |
318 | - ${CMAKE_CURRENT_BINARY_DIR}/DirectionalDragAreaTestExec |
319 | - -o ${CMAKE_BINARY_DIR}/DirectionalDragAreaTest.xml,xunitxml |
320 | - -o -,txt) |
321 | - |
322 | -add_custom_target(testDirectionalDragArea ${testCommand}) |
323 | -add_dependencies(qmluitests testDirectionalDragArea) |
324 | -add_dependencies(testDirectionalDragArea DirectionalDragAreaTestExec UbutunGesturesTestQmlFiles) |
325 | - |
326 | -add_executable(DirectionalDragAreaTestExec tst_DirectionalDragArea.cpp) |
327 | -qt5_use_modules(DirectionalDragAreaTestExec Test Core Qml Gui Quick) |
328 | -target_link_libraries(DirectionalDragAreaTestExec UbuntuGestureQml) |
329 | - |
330 | -add_definitions(-DUBUNTU_GESTURES_PLUGIN_DIR="${CMAKE_BINARY_DIR}/plugins") |
331 | - |
332 | file(GLOB qmlFiles *.qml) |
333 | add_custom_target(UbuntuGesturesTestQmlFiles ALL |
334 | COMMAND cp ${qmlFiles} ${CMAKE_CURRENT_BINARY_DIR} |
335 | DEPENDS ${qmlFiles} |
336 | ) |
337 | |
338 | -########## other tests |
339 | +add_definitions(-DUBUNTU_GESTURES_PLUGIN_DIR="${CMAKE_BINARY_DIR}/plugins") |
340 | + |
341 | +macro(add_gesture_ui_test CLASSNAME) |
342 | + set(testCommand |
343 | + LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/plugins/Ubuntu/Gestures |
344 | + ${CMAKE_CURRENT_BINARY_DIR}/${CLASSNAME}TestExec |
345 | + -o ${CMAKE_BINARY_DIR}/${CLASSNAME}Test.xml,xunitxml |
346 | + -o -,txt) |
347 | + |
348 | + add_custom_target(test${CLASSNAME} ${testCommand}) |
349 | + add_dependencies(qmluitests test${CLASSNAME}) |
350 | + add_dependencies(test${CLASSNAME} ${CLASSNAME}TestExec UbuntuGesturesTestQmlFiles) |
351 | + |
352 | + add_executable(${CLASSNAME}TestExec tst_${CLASSNAME}.cpp GestureTest.cpp) |
353 | + qt5_use_modules(${CLASSNAME}TestExec Test Core Qml Gui Quick) |
354 | + target_link_libraries(${CLASSNAME}TestExec UbuntuGestureQml) |
355 | +endmacro(add_gesture_ui_test) |
356 | |
357 | macro(add_gesture_test CLASSNAME) |
358 | set(testCommand |
359 | @@ -43,5 +43,8 @@ |
360 | target_link_libraries(${CLASSNAME}TestExec UbuntuGestureQml) |
361 | endmacro(add_gesture_test) |
362 | |
363 | +add_gesture_ui_test(DirectionalDragArea) |
364 | +add_gesture_ui_test(PressedOutsideNotifier) |
365 | +add_manual_qml_test(. PressedOutsideNotifier IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins) |
366 | add_gesture_test(Damper) |
367 | add_gesture_test(AxisVelocityCalculator) |
368 | |
369 | === added file 'tests/plugins/Ubuntu/Gestures/GestureTest.cpp' |
370 | --- tests/plugins/Ubuntu/Gestures/GestureTest.cpp 1970-01-01 00:00:00 +0000 |
371 | +++ tests/plugins/Ubuntu/Gestures/GestureTest.cpp 2013-11-22 10:45:28 +0000 |
372 | @@ -0,0 +1,44 @@ |
373 | +/* |
374 | + * Copyright (C) 2013 Canonical, Ltd. |
375 | + * |
376 | + * This program is free software; you can redistribute it and/or modify |
377 | + * it under the terms of the GNU General Public License as published by |
378 | + * the Free Software Foundation; version 3. |
379 | + * |
380 | + * This program is distributed in the hope that it will be useful, |
381 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
382 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
383 | + * GNU General Public License for more details. |
384 | + * |
385 | + * You should have received a copy of the GNU General Public License |
386 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
387 | + */ |
388 | + |
389 | +#include "GestureTest.h" |
390 | + |
391 | +#include <qpa/qwindowsysteminterface.h> |
392 | +#include <QQmlEngine> |
393 | +#include <QQuickView> |
394 | + |
395 | +void GestureTest::initTestCase() |
396 | +{ |
397 | + if (!m_device) { |
398 | + m_device = new QTouchDevice; |
399 | + m_device->setType(QTouchDevice::TouchScreen); |
400 | + QWindowSystemInterface::registerTouchDevice(m_device); |
401 | + } |
402 | +} |
403 | + |
404 | +void GestureTest::init() |
405 | +{ |
406 | + m_view = new QQuickView(0); |
407 | + m_view->setResizeMode(QQuickView::SizeRootObjectToView); |
408 | + m_view->resize(600, 600); |
409 | + m_view->engine()->addImportPath(QLatin1String(UBUNTU_GESTURES_PLUGIN_DIR)); |
410 | +} |
411 | + |
412 | +void GestureTest::cleanup() |
413 | +{ |
414 | + delete m_view; |
415 | + m_view = nullptr; |
416 | +} |
417 | |
418 | === added file 'tests/plugins/Ubuntu/Gestures/GestureTest.h' |
419 | --- tests/plugins/Ubuntu/Gestures/GestureTest.h 1970-01-01 00:00:00 +0000 |
420 | +++ tests/plugins/Ubuntu/Gestures/GestureTest.h 2013-11-22 10:45:28 +0000 |
421 | @@ -0,0 +1,44 @@ |
422 | +/* |
423 | + * Copyright (C) 2013 Canonical, Ltd. |
424 | + * |
425 | + * This program is free software; you can redistribute it and/or modify |
426 | + * it under the terms of the GNU General Public License as published by |
427 | + * the Free Software Foundation; version 3. |
428 | + * |
429 | + * This program is distributed in the hope that it will be useful, |
430 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
431 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
432 | + * GNU General Public License for more details. |
433 | + * |
434 | + * You should have received a copy of the GNU General Public License |
435 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
436 | + */ |
437 | + |
438 | +#ifndef GESTURETEST_H |
439 | +#endif // GESTURETEST_H |
440 | + |
441 | +#include <QObject> |
442 | + |
443 | +class QQuickView; |
444 | +class QTouchDevice; |
445 | + |
446 | +/* |
447 | + The common stuff among tests come here |
448 | + */ |
449 | +class GestureTest : public QObject |
450 | +{ |
451 | + Q_OBJECT |
452 | +public: |
453 | + GestureTest() : QObject(), m_device(nullptr), m_view(nullptr) {} |
454 | + |
455 | +protected Q_SLOTS: |
456 | + void initTestCase(); // will be called before the first test function is executed |
457 | + virtual void init(); // called right before each and every test function is executed |
458 | + virtual void cleanup(); // called right after each and every test function is executed |
459 | + |
460 | +protected: |
461 | + QTouchDevice *m_device; |
462 | + QQuickView *m_view; |
463 | +}; |
464 | + |
465 | +#define GESTURETEST_H |
466 | |
467 | === modified file 'tests/plugins/Ubuntu/Gestures/tst_DirectionalDragArea.cpp' |
468 | --- tests/plugins/Ubuntu/Gestures/tst_DirectionalDragArea.cpp 2013-10-23 12:25:40 +0000 |
469 | +++ tests/plugins/Ubuntu/Gestures/tst_DirectionalDragArea.cpp 2013-11-22 10:45:28 +0000 |
470 | @@ -16,13 +16,14 @@ |
471 | |
472 | #include <QtTest/QtTest> |
473 | #include <QtCore/QObject> |
474 | -#include <qpa/qwindowsysteminterface.h> |
475 | #include <QtQuick/QQuickView> |
476 | #include <QtQml/QQmlEngine> |
477 | #include <QPointer> |
478 | |
479 | #include <DirectionalDragArea.h> |
480 | |
481 | +#include "GestureTest.h" |
482 | + |
483 | using namespace UbuntuGestures; |
484 | |
485 | class FakeTimer : public AbstractTimer |
486 | @@ -61,15 +62,11 @@ |
487 | qint64 m_msecsSinceReference; |
488 | }; |
489 | |
490 | -class tst_DirectionalDragArea: public QObject |
491 | +class tst_DirectionalDragArea: public GestureTest |
492 | { |
493 | Q_OBJECT |
494 | public: |
495 | - tst_DirectionalDragArea() : device(0) { } |
496 | private Q_SLOTS: |
497 | - void initTestCase(); // will be called before the first test function is executed |
498 | - void cleanupTestCase(); // will be called after the last test function was executed. |
499 | - |
500 | void init(); // called right before each and every test function is executed |
501 | void cleanup(); // called right after each and every test function is executed |
502 | |
503 | @@ -87,36 +84,18 @@ |
504 | void ignoreOldFinger(); |
505 | |
506 | private: |
507 | - QQuickView *createView(); |
508 | void passTime(qint64 timeSpan); |
509 | - QQuickView *view; |
510 | - QTouchDevice *device; |
511 | FakeTimer *fakeTimer; |
512 | QSharedPointer<FakeTimeSource> fakeTimeSource; |
513 | }; |
514 | |
515 | -void tst_DirectionalDragArea::initTestCase() |
516 | -{ |
517 | - if (!device) { |
518 | - device = new QTouchDevice; |
519 | - device->setType(QTouchDevice::TouchScreen); |
520 | - QWindowSystemInterface::registerTouchDevice(device); |
521 | - } |
522 | - |
523 | - view = 0; |
524 | -} |
525 | - |
526 | -void tst_DirectionalDragArea::cleanupTestCase() |
527 | -{ |
528 | -} |
529 | - |
530 | void tst_DirectionalDragArea::init() |
531 | { |
532 | - view = createView(); |
533 | - view->setSource(QUrl::fromLocalFile("edgeDragExample.qml")); |
534 | - view->show(); |
535 | - QVERIFY(QTest::qWaitForWindowExposed(view)); |
536 | - QVERIFY(view->rootObject() != 0); |
537 | + GestureTest::init(); |
538 | + m_view->setSource(QUrl::fromLocalFile("edgeDragExample.qml")); |
539 | + m_view->show(); |
540 | + QVERIFY(QTest::qWaitForWindowExposed(m_view)); |
541 | + QVERIFY(m_view->rootObject() != 0); |
542 | qApp->processEvents(); |
543 | |
544 | fakeTimeSource.reset(new FakeTimeSource); |
545 | @@ -125,23 +104,12 @@ |
546 | |
547 | void tst_DirectionalDragArea::cleanup() |
548 | { |
549 | - delete view; |
550 | - view = 0; |
551 | - |
552 | delete fakeTimer; |
553 | fakeTimer = 0; |
554 | |
555 | fakeTimeSource.reset(); |
556 | -} |
557 | - |
558 | -QQuickView *tst_DirectionalDragArea::createView() |
559 | -{ |
560 | - QQuickView *window = new QQuickView(0); |
561 | - window->setResizeMode(QQuickView::SizeRootObjectToView); |
562 | - window->resize(600, 600); |
563 | - window->engine()->addImportPath(QLatin1String(UBUNTU_GESTURES_PLUGIN_DIR)); |
564 | - |
565 | - return window; |
566 | + |
567 | + GestureTest::cleanup(); |
568 | } |
569 | |
570 | void tst_DirectionalDragArea::passTime(qint64 timeSpan) |
571 | @@ -217,14 +185,14 @@ |
572 | QFETCH(bool, expectGestureRecognition); |
573 | |
574 | DirectionalDragArea *edgeDragArea = |
575 | - view->rootObject()->findChild<DirectionalDragArea*>(dragAreaObjectName); |
576 | + m_view->rootObject()->findChild<DirectionalDragArea*>(dragAreaObjectName); |
577 | QVERIFY(edgeDragArea != 0); |
578 | edgeDragArea->setRecognitionTimer(fakeTimer); |
579 | edgeDragArea->setTimeSource(fakeTimeSource); |
580 | |
581 | QSignalSpy draggingSpy(edgeDragArea, SIGNAL(draggingChanged(bool))); |
582 | |
583 | - QPointF initialTouchPos = calculateInitialTouchPos(edgeDragArea, view); |
584 | + QPointF initialTouchPos = calculateInitialTouchPos(edgeDragArea, m_view); |
585 | QPointF touchPoint = initialTouchPos; |
586 | |
587 | qreal desiredDragDistance = edgeDragArea->distanceThreshold()*dragDistanceFactor; |
588 | @@ -235,7 +203,7 @@ |
589 | int totalMovementSteps = qCeil(desiredDragDistance / movementStepDistance); |
590 | int movementTimeStepMs = (edgeDragArea->compositionTime() * 1.5f) / totalMovementSteps; |
591 | |
592 | - QTest::touchEvent(view, device).press(0, touchPoint.toPoint()); |
593 | + QTest::touchEvent(m_view, m_device).press(0, touchPoint.toPoint()); |
594 | |
595 | QCOMPARE(draggingSpy.count(), 1); |
596 | QCOMPARE(edgeDragArea->dragging(), true); |
597 | @@ -245,13 +213,13 @@ |
598 | // in order to make it easier to leave it by dragging at an angle |
599 | // slightly bigger than the widening angle |
600 | touchPoint += createTouchDeviation(edgeDragArea); |
601 | - QTest::touchEvent(view, device).move(0, touchPoint.toPoint()); |
602 | + QTest::touchEvent(m_view, m_device).move(0, touchPoint.toPoint()); |
603 | } |
604 | |
605 | for (int i = 0; i < totalMovementSteps; ++i) { |
606 | touchPoint += touchMovement; |
607 | passTime(movementTimeStepMs); |
608 | - QTest::touchEvent(view, device).move(0, touchPoint.toPoint()); |
609 | + QTest::touchEvent(m_view, m_device).move(0, touchPoint.toPoint()); |
610 | } |
611 | |
612 | if (expectGestureRecognition) |
613 | @@ -262,7 +230,7 @@ |
614 | QCOMPARE(draggingSpy.count(), 2); |
615 | } |
616 | |
617 | - QTest::touchEvent(view, device).release(0, touchPoint.toPoint()); |
618 | + QTest::touchEvent(m_view, m_device).release(0, touchPoint.toPoint()); |
619 | |
620 | QCOMPARE(draggingSpy.count(), 2); |
621 | QCOMPARE(edgeDragArea->dragging(), false); |
622 | @@ -326,12 +294,12 @@ |
623 | void tst_DirectionalDragArea::dragWithShortDirectionChange() |
624 | { |
625 | DirectionalDragArea *edgeDragArea = |
626 | - view->rootObject()->findChild<DirectionalDragArea*>("hpDragArea"); |
627 | + m_view->rootObject()->findChild<DirectionalDragArea*>("hpDragArea"); |
628 | QVERIFY(edgeDragArea != 0); |
629 | edgeDragArea->setRecognitionTimer(fakeTimer); |
630 | edgeDragArea->setTimeSource(fakeTimeSource); |
631 | |
632 | - QPointF initialTouchPos = calculateInitialTouchPos(edgeDragArea, view); |
633 | + QPointF initialTouchPos = calculateInitialTouchPos(edgeDragArea, m_view); |
634 | QPointF touchPoint = initialTouchPos; |
635 | |
636 | qreal desiredDragDistance = edgeDragArea->distanceThreshold()*2.0; |
637 | @@ -341,32 +309,32 @@ |
638 | int touchStepTimeMs = (touchStepDistance / (edgeDragArea->minSpeed() * 5.0f)) * 1000.0f; |
639 | QPointF touchMovement = dragDirectionVector * touchStepDistance; |
640 | |
641 | - QTest::touchEvent(view, device).press(0, touchPoint.toPoint()); |
642 | + QTest::touchEvent(m_view, m_device).press(0, touchPoint.toPoint()); |
643 | |
644 | // Move a bit in the proper direction |
645 | for (int i=0; i < 3; ++i) { |
646 | touchPoint += touchMovement; |
647 | passTime(touchStepTimeMs); |
648 | - QTest::touchEvent(view, device).move(0, touchPoint.toPoint()); |
649 | + QTest::touchEvent(m_view, m_device).move(0, touchPoint.toPoint()); |
650 | } |
651 | |
652 | // Then a sudden and small movement to the opposite direction |
653 | touchPoint -= touchMovement*0.2; |
654 | passTime(touchStepTimeMs*0.2); |
655 | - QTest::touchEvent(view, device).move(0, touchPoint.toPoint()); |
656 | + QTest::touchEvent(m_view, m_device).move(0, touchPoint.toPoint()); |
657 | |
658 | // And then resume movment in the correct direction until it crosses the distance and time |
659 | // thresholds. |
660 | do { |
661 | touchPoint += touchMovement; |
662 | passTime(touchStepTimeMs); |
663 | - QTest::touchEvent(view, device).move(0, touchPoint.toPoint()); |
664 | + QTest::touchEvent(m_view, m_device).move(0, touchPoint.toPoint()); |
665 | } while ((touchPoint - initialTouchPos).manhattanLength() < desiredDragDistance |
666 | || fakeTimeSource->m_msecsSinceReference < (edgeDragArea->compositionTime() * 1.5f)); |
667 | |
668 | QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::Recognized); |
669 | |
670 | - QTest::touchEvent(view, device).release(0, touchPoint.toPoint()); |
671 | + QTest::touchEvent(m_view, m_device).release(0, touchPoint.toPoint()); |
672 | } |
673 | |
674 | /* |
675 | @@ -380,7 +348,7 @@ |
676 | QFETCH(int, expectedStatusAfterSpeedCheck); |
677 | |
678 | DirectionalDragArea *edgeDragArea = |
679 | - view->rootObject()->findChild<DirectionalDragArea*>("hpDragArea"); |
680 | + m_view->rootObject()->findChild<DirectionalDragArea*>("hpDragArea"); |
681 | QVERIFY(edgeDragArea != 0); |
682 | edgeDragArea->setRecognitionTimer(fakeTimer); |
683 | edgeDragArea->setTimeSource(fakeTimeSource); |
684 | @@ -391,7 +359,7 @@ |
685 | |
686 | edgeDragArea->setMinSpeed(minSpeed); |
687 | |
688 | - QPointF initialTouchPos = calculateInitialTouchPos(edgeDragArea, view); |
689 | + QPointF initialTouchPos = calculateInitialTouchPos(edgeDragArea, m_view); |
690 | QPointF touchPoint = initialTouchPos; |
691 | |
692 | QPointF dragDirectionVector(1.0, 0.0); |
693 | @@ -399,13 +367,13 @@ |
694 | qreal distanceStep = (speed / 1000.0f) * timeStepMsecs; |
695 | QPointF touchMovement = dragDirectionVector * distanceStep; |
696 | |
697 | - QTest::touchEvent(view, device).press(0, touchPoint.toPoint()); |
698 | + QTest::touchEvent(m_view, m_device).press(0, touchPoint.toPoint()); |
699 | |
700 | // Move for a while to ensure our speed check is performed a couple of times |
701 | for (int i=0; i < 20; ++i) { |
702 | touchPoint += touchMovement; |
703 | passTime(timeStepMsecs); |
704 | - QTest::touchEvent(view, device).move(0, touchPoint.toPoint()); |
705 | + QTest::touchEvent(m_view, m_device).move(0, touchPoint.toPoint()); |
706 | } |
707 | |
708 | QCOMPARE((int)edgeDragArea->status(), expectedStatusAfterSpeedCheck); |
709 | @@ -429,7 +397,7 @@ |
710 | void tst_DirectionalDragArea::recognitionTimerUsage() |
711 | { |
712 | DirectionalDragArea *edgeDragArea = |
713 | - view->rootObject()->findChild<DirectionalDragArea*>("hpDragArea"); |
714 | + m_view->rootObject()->findChild<DirectionalDragArea*>("hpDragArea"); |
715 | QVERIFY(edgeDragArea != 0); |
716 | edgeDragArea->setRecognitionTimer(fakeTimer); |
717 | edgeDragArea->setTimeSource(fakeTimeSource); |
718 | @@ -439,7 +407,7 @@ |
719 | |
720 | int timeStepMs = 5; // some arbitrary small value. |
721 | |
722 | - QPointF initialTouchPos = calculateInitialTouchPos(edgeDragArea, view); |
723 | + QPointF initialTouchPos = calculateInitialTouchPos(edgeDragArea, m_view); |
724 | QPointF touchPoint = initialTouchPos; |
725 | |
726 | QPointF dragDirectionVector(1.0, 0.0); |
727 | @@ -448,7 +416,7 @@ |
728 | QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::WaitingForTouch); |
729 | QVERIFY(!fakeTimer->isRunning()); |
730 | |
731 | - QTest::touchEvent(view, device).press(0, touchPoint.toPoint()); |
732 | + QTest::touchEvent(m_view, m_device).press(0, touchPoint.toPoint()); |
733 | |
734 | QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::Undecided); |
735 | QVERIFY(fakeTimer->isRunning()); |
736 | @@ -461,7 +429,7 @@ |
737 | |
738 | touchPoint += touchMovement; |
739 | passTime(timeStepMs); |
740 | - QTest::touchEvent(view, device).move(0, touchPoint.toPoint()); |
741 | + QTest::touchEvent(m_view, m_device).move(0, touchPoint.toPoint()); |
742 | } |
743 | |
744 | QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::Recognized); |
745 | @@ -475,7 +443,7 @@ |
746 | void tst_DirectionalDragArea::maxSilenceTime() |
747 | { |
748 | DirectionalDragArea *edgeDragArea = |
749 | - view->rootObject()->findChild<DirectionalDragArea*>("hpDragArea"); |
750 | + m_view->rootObject()->findChild<DirectionalDragArea*>("hpDragArea"); |
751 | QVERIFY(edgeDragArea != 0); |
752 | edgeDragArea->setRecognitionTimer(fakeTimer); |
753 | edgeDragArea->setTimeSource(fakeTimeSource); |
754 | @@ -483,10 +451,10 @@ |
755 | // Make sure this property is not disabled |
756 | edgeDragArea->setMaxSilenceTime(100); |
757 | |
758 | - QPointF initialTouchPos = calculateInitialTouchPos(edgeDragArea, view); |
759 | + QPointF initialTouchPos = calculateInitialTouchPos(edgeDragArea, m_view); |
760 | QPointF touchPoint = initialTouchPos; |
761 | |
762 | - QTest::touchEvent(view, device).press(0, touchPoint.toPoint()); |
763 | + QTest::touchEvent(m_view, m_device).press(0, touchPoint.toPoint()); |
764 | |
765 | QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::Undecided); |
766 | QVERIFY(fakeTimer->isRunning()); |
767 | @@ -506,20 +474,20 @@ |
768 | void tst_DirectionalDragArea::sceneXAndX() |
769 | { |
770 | DirectionalDragArea *edgeDragArea = |
771 | - view->rootObject()->findChild<DirectionalDragArea*>("hnDragArea"); |
772 | + m_view->rootObject()->findChild<DirectionalDragArea*>("hnDragArea"); |
773 | QVERIFY(edgeDragArea != 0); |
774 | edgeDragArea->setRecognitionTimer(fakeTimer); |
775 | edgeDragArea->setTimeSource(fakeTimeSource); |
776 | |
777 | - QPointF touchScenePos(view->width() - (edgeDragArea->width()/2.0f), view->height()/2.0f); |
778 | + QPointF touchScenePos(m_view->width() - (edgeDragArea->width()/2.0f), m_view->height()/2.0f); |
779 | |
780 | - QTest::touchEvent(view, device).press(0, touchScenePos.toPoint()); |
781 | + QTest::touchEvent(m_view, m_device).press(0, touchScenePos.toPoint()); |
782 | |
783 | QSignalSpy touchXSpy(edgeDragArea, SIGNAL(touchXChanged(qreal))); |
784 | QSignalSpy touchSceneXSpy(edgeDragArea, SIGNAL(touchSceneXChanged(qreal))); |
785 | |
786 | - touchScenePos.rx() = view->width() / 2; |
787 | - QTest::touchEvent(view, device).move(0, touchScenePos.toPoint()); |
788 | + touchScenePos.rx() = m_view->width() / 2; |
789 | + QTest::touchEvent(m_view, m_device).move(0, touchScenePos.toPoint()); |
790 | |
791 | QCOMPARE(touchXSpy.count(), 1); |
792 | QCOMPARE(touchSceneXSpy.count(), 1); |
793 | @@ -534,20 +502,20 @@ |
794 | void tst_DirectionalDragArea::sceneYAndY() |
795 | { |
796 | DirectionalDragArea *edgeDragArea = |
797 | - view->rootObject()->findChild<DirectionalDragArea*>("vnDragArea"); |
798 | + m_view->rootObject()->findChild<DirectionalDragArea*>("vnDragArea"); |
799 | QVERIFY(edgeDragArea != 0); |
800 | edgeDragArea->setRecognitionTimer(fakeTimer); |
801 | edgeDragArea->setTimeSource(fakeTimeSource); |
802 | |
803 | - QPointF touchScenePos(view->width()/2.0f, view->height() - (edgeDragArea->height()/2.0f)); |
804 | + QPointF touchScenePos(m_view->width()/2.0f, m_view->height() - (edgeDragArea->height()/2.0f)); |
805 | |
806 | - QTest::touchEvent(view, device).press(0, touchScenePos.toPoint()); |
807 | + QTest::touchEvent(m_view, m_device).press(0, touchScenePos.toPoint()); |
808 | |
809 | QSignalSpy touchYSpy(edgeDragArea, SIGNAL(touchYChanged(qreal))); |
810 | QSignalSpy touchSceneYSpy(edgeDragArea, SIGNAL(touchSceneYChanged(qreal))); |
811 | |
812 | - touchScenePos.ry() = view->height() / 2; |
813 | - QTest::touchEvent(view, device).move(0, touchScenePos.toPoint()); |
814 | + touchScenePos.ry() = m_view->height() / 2; |
815 | + QTest::touchEvent(m_view, m_device).move(0, touchScenePos.toPoint()); |
816 | |
817 | QCOMPARE(touchYSpy.count(), 1); |
818 | QCOMPARE(touchSceneYSpy.count(), 1); |
819 | @@ -564,27 +532,27 @@ |
820 | void tst_DirectionalDragArea::twoFingerTap() |
821 | { |
822 | DirectionalDragArea *edgeDragArea = |
823 | - view->rootObject()->findChild<DirectionalDragArea*>("hpDragArea"); |
824 | + m_view->rootObject()->findChild<DirectionalDragArea*>("hpDragArea"); |
825 | QVERIFY(edgeDragArea != 0); |
826 | edgeDragArea->setRecognitionTimer(fakeTimer); |
827 | edgeDragArea->setTimeSource(fakeTimeSource); |
828 | |
829 | // Make touches evenly spaced along the edgeDragArea |
830 | - QPoint touchAPos(edgeDragArea->width()/2.0f, view->height()*0.33f); |
831 | - QPoint touchBPos(edgeDragArea->width()/2.0f, view->height()*0.66f); |
832 | + QPoint touchAPos(edgeDragArea->width()/2.0f, m_view->height()*0.33f); |
833 | + QPoint touchBPos(edgeDragArea->width()/2.0f, m_view->height()*0.66f); |
834 | |
835 | qint64 timeStepMsecs = 5; // some arbitrary, small value |
836 | |
837 | // Perform the first two-finger tap |
838 | // NB: using move() instead of stationary() becasue in the latter you cannot provide |
839 | // the touch position and therefore it's left with some garbage numbers. |
840 | - QTest::touchEvent(view, device) |
841 | + QTest::touchEvent(m_view, m_device) |
842 | .press(0, touchAPos); |
843 | |
844 | QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::Undecided); |
845 | |
846 | passTime(timeStepMsecs); |
847 | - QTest::touchEvent(view, device) |
848 | + QTest::touchEvent(m_view, m_device) |
849 | .move(0, touchAPos) |
850 | .press(1, touchBPos); |
851 | |
852 | @@ -593,14 +561,14 @@ |
853 | QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::WaitingForTouch); |
854 | |
855 | passTime(timeStepMsecs); |
856 | - QTest::touchEvent(view, device) |
857 | + QTest::touchEvent(m_view, m_device) |
858 | .release(0, touchAPos) |
859 | .move(1, touchBPos); |
860 | |
861 | QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::WaitingForTouch); |
862 | |
863 | passTime(timeStepMsecs); |
864 | - QTest::touchEvent(view, device) |
865 | + QTest::touchEvent(m_view, m_device) |
866 | .release(1, touchBPos); |
867 | |
868 | QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::WaitingForTouch); |
869 | @@ -608,27 +576,27 @@ |
870 | // Perform the second two-finger tap |
871 | |
872 | passTime(timeStepMsecs); |
873 | - QTest::touchEvent(view, device) |
874 | + QTest::touchEvent(m_view, m_device) |
875 | .press(0, touchAPos); |
876 | |
877 | QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::Undecided); |
878 | |
879 | passTime(timeStepMsecs); |
880 | - QTest::touchEvent(view, device) |
881 | + QTest::touchEvent(m_view, m_device) |
882 | .move(0, touchAPos) |
883 | .press(1, touchBPos); |
884 | |
885 | QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::WaitingForTouch); |
886 | |
887 | passTime(timeStepMsecs); |
888 | - QTest::touchEvent(view, device) |
889 | + QTest::touchEvent(m_view, m_device) |
890 | .release(0, touchAPos) |
891 | .move(1, touchBPos); |
892 | |
893 | QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::WaitingForTouch); |
894 | |
895 | passTime(timeStepMsecs); |
896 | - QTest::touchEvent(view, device) |
897 | + QTest::touchEvent(m_view, m_device) |
898 | .release(1, touchBPos); |
899 | |
900 | QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::WaitingForTouch); |
901 | @@ -642,7 +610,7 @@ |
902 | */ |
903 | void tst_DirectionalDragArea::movingDDA() |
904 | { |
905 | - QQuickItem *rightwardsLauncher = view->rootObject()->findChild<QQuickItem*>("rightwardsLauncher"); |
906 | + QQuickItem *rightwardsLauncher = m_view->rootObject()->findChild<QQuickItem*>("rightwardsLauncher"); |
907 | Q_ASSERT(rightwardsLauncher != 0); |
908 | |
909 | DirectionalDragArea *edgeDragArea = |
910 | @@ -651,7 +619,7 @@ |
911 | edgeDragArea->setRecognitionTimer(fakeTimer); |
912 | edgeDragArea->setTimeSource(fakeTimeSource); |
913 | |
914 | - QPointF initialTouchPos = calculateInitialTouchPos(edgeDragArea, view); |
915 | + QPointF initialTouchPos = calculateInitialTouchPos(edgeDragArea, m_view); |
916 | QPointF touchPoint = initialTouchPos; |
917 | |
918 | qreal desiredDragDistance = edgeDragArea->distanceThreshold()*2.0f; |
919 | @@ -662,7 +630,7 @@ |
920 | int totalMovementSteps = qCeil(desiredDragDistance / movementStepDistance); |
921 | int movementTimeStepMs = (edgeDragArea->compositionTime() * 1.5f) / totalMovementSteps; |
922 | |
923 | - QTest::touchEvent(view, device).press(0, touchPoint.toPoint()); |
924 | + QTest::touchEvent(m_view, m_device).press(0, touchPoint.toPoint()); |
925 | |
926 | // Move it far ahead along the direction of the gesture |
927 | // rightwardsLauncher is a parent of our DirectionalDragArea. So moving it will move our DDA |
928 | @@ -671,12 +639,12 @@ |
929 | for (int i = 0; i < totalMovementSteps; ++i) { |
930 | touchPoint += touchMovement; |
931 | passTime(movementTimeStepMs); |
932 | - QTest::touchEvent(view, device).move(0, touchPoint.toPoint()); |
933 | + QTest::touchEvent(m_view, m_device).move(0, touchPoint.toPoint()); |
934 | } |
935 | |
936 | QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::Recognized); |
937 | |
938 | - QTest::touchEvent(view, device).release(0, touchPoint.toPoint()); |
939 | + QTest::touchEvent(m_view, m_device).release(0, touchPoint.toPoint()); |
940 | } |
941 | |
942 | /* |
943 | @@ -686,16 +654,16 @@ |
944 | void tst_DirectionalDragArea::ignoreOldFinger() |
945 | { |
946 | DirectionalDragArea *edgeDragArea = |
947 | - view->rootObject()->findChild<DirectionalDragArea*>("hpDragArea"); |
948 | + m_view->rootObject()->findChild<DirectionalDragArea*>("hpDragArea"); |
949 | Q_ASSERT(edgeDragArea != 0); |
950 | edgeDragArea->setRecognitionTimer(fakeTimer); |
951 | edgeDragArea->setTimeSource(fakeTimeSource); |
952 | |
953 | // Make touches evenly spaced along the edgeDragArea |
954 | - QPoint touch0Pos(edgeDragArea->width()/2.0f, view->height()*0.33f); |
955 | - QPoint touch1Pos(edgeDragArea->width()/2.0f, view->height()*0.66f); |
956 | + QPoint touch0Pos(edgeDragArea->width()/2.0f, m_view->height()*0.33f); |
957 | + QPoint touch1Pos(edgeDragArea->width()/2.0f, m_view->height()*0.66f); |
958 | |
959 | - QTest::touchEvent(view, device).press(0, touch0Pos); |
960 | + QTest::touchEvent(m_view, m_device).press(0, touch0Pos); |
961 | |
962 | QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::Undecided); |
963 | |
964 | @@ -712,7 +680,7 @@ |
965 | int totalMovementSteps = qCeil(desiredDragDistance / movementStepDistance); |
966 | int movementTimeStepMs = (edgeDragArea->compositionTime() * 1.5f) / totalMovementSteps; |
967 | |
968 | - QTest::touchEvent(view, device) |
969 | + QTest::touchEvent(m_view, m_device) |
970 | .move(0, touch0Pos) |
971 | .press(1, touch1Pos); |
972 | |
973 | @@ -721,14 +689,14 @@ |
974 | for (int i = 0; i < totalMovementSteps; ++i) { |
975 | touch1Pos += touchMovement.toPoint(); |
976 | passTime(movementTimeStepMs); |
977 | - QTest::touchEvent(view, device) |
978 | + QTest::touchEvent(m_view, m_device) |
979 | .move(0, touch0Pos) |
980 | .move(1, touch1Pos); |
981 | } |
982 | |
983 | QCOMPARE((int)edgeDragArea->status(), (int)DirectionalDragArea::Recognized); |
984 | |
985 | - QTest::touchEvent(view, device) |
986 | + QTest::touchEvent(m_view, m_device) |
987 | .move(0, touch0Pos) |
988 | .release(1, touch1Pos); |
989 | |
990 | |
991 | === added file 'tests/plugins/Ubuntu/Gestures/tst_PressedOutsideNotifier.cpp' |
992 | --- tests/plugins/Ubuntu/Gestures/tst_PressedOutsideNotifier.cpp 1970-01-01 00:00:00 +0000 |
993 | +++ tests/plugins/Ubuntu/Gestures/tst_PressedOutsideNotifier.cpp 2013-11-22 10:45:28 +0000 |
994 | @@ -0,0 +1,146 @@ |
995 | +/* |
996 | + * Copyright (C) 2013 Canonical, Ltd. |
997 | + * |
998 | + * This program is free software; you can redistribute it and/or modify |
999 | + * it under the terms of the GNU General Public License as published by |
1000 | + * the Free Software Foundation; version 3. |
1001 | + * |
1002 | + * This program is distributed in the hope that it will be useful, |
1003 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1004 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1005 | + * GNU General Public License for more details. |
1006 | + * |
1007 | + * You should have received a copy of the GNU General Public License |
1008 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1009 | + */ |
1010 | + |
1011 | +#include "GestureTest.h" |
1012 | + |
1013 | +#include <PressedOutsideNotifier.h> |
1014 | + |
1015 | +#include <QQuickItem> |
1016 | +#include <QQuickView> |
1017 | +#include <QtTest> |
1018 | + |
1019 | +class tst_PressedOutsideNotifier: public GestureTest |
1020 | +{ |
1021 | + Q_OBJECT |
1022 | +private Q_SLOTS: |
1023 | + void init(); // called right before each and every test function is executed |
1024 | + |
1025 | + void touchOutsideAreaTriggersSignal(); |
1026 | + void touchInsideAreaHasNoEffect(); |
1027 | + void mousePressOutsideAreaTriggersSignal(); |
1028 | + void mousePresssInsideAreaHasNoEffect(); |
1029 | + void nothingHappensWhileDisabled(); |
1030 | + |
1031 | +private: |
1032 | + QQuickItem *m_blueRect; |
1033 | + PressedOutsideNotifier *m_notifier; |
1034 | +}; |
1035 | + |
1036 | +void tst_PressedOutsideNotifier::init() |
1037 | +{ |
1038 | + GestureTest::init(); |
1039 | + m_view->setSource(QUrl::fromLocalFile("tst_PressedOutsideNotifier.qml")); |
1040 | + m_view->show(); |
1041 | + QVERIFY(QTest::qWaitForWindowExposed(m_view)); |
1042 | + QVERIFY(m_view->rootObject() != 0); |
1043 | + qApp->processEvents(); |
1044 | + |
1045 | + m_blueRect = m_view->rootObject()->findChild<QQuickItem*>("blueRect"); |
1046 | + Q_ASSERT(m_blueRect != nullptr); |
1047 | + |
1048 | + m_notifier = |
1049 | + m_view->rootObject()->findChild<PressedOutsideNotifier*>("pressedOutsideNotifier"); |
1050 | + Q_ASSERT(m_notifier != nullptr); |
1051 | +} |
1052 | + |
1053 | +void tst_PressedOutsideNotifier::touchOutsideAreaTriggersSignal() |
1054 | +{ |
1055 | + QPoint touch0 = QPoint(m_blueRect->x() - 50, m_blueRect->y() - 50); |
1056 | + |
1057 | + QSignalSpy pressedOutsideSpy(m_notifier, SIGNAL(pressedOutside())); |
1058 | + |
1059 | + QTest::touchEvent(m_view, m_device) |
1060 | + .press(0, touch0); |
1061 | + |
1062 | + qApp->processEvents(); |
1063 | + |
1064 | + QCOMPARE(pressedOutsideSpy.count(), 1); |
1065 | + |
1066 | + QTest::touchEvent(m_view, m_device) |
1067 | + .release(0, touch0); |
1068 | +} |
1069 | + |
1070 | +void tst_PressedOutsideNotifier::touchInsideAreaHasNoEffect() |
1071 | +{ |
1072 | + QPoint touch0 = QPoint(m_blueRect->x() + m_blueRect->width()*0.5, |
1073 | + m_blueRect->y() + m_blueRect->height()*0.5); |
1074 | + |
1075 | + QSignalSpy pressedOutsideSpy(m_notifier, SIGNAL(pressedOutside())); |
1076 | + |
1077 | + QTest::touchEvent(m_view, m_device) |
1078 | + .press(0, touch0); |
1079 | + |
1080 | + qApp->processEvents(); |
1081 | + |
1082 | + QCOMPARE(pressedOutsideSpy.count(), 0); |
1083 | + |
1084 | + QTest::touchEvent(m_view, m_device) |
1085 | + .release(0, touch0); |
1086 | +} |
1087 | + |
1088 | +void tst_PressedOutsideNotifier::mousePressOutsideAreaTriggersSignal() |
1089 | +{ |
1090 | + QPoint mousePos = QPoint(m_blueRect->x() - 50, m_blueRect->y() - 50); |
1091 | + |
1092 | + QSignalSpy pressedOutsideSpy(m_notifier, SIGNAL(pressedOutside())); |
1093 | + |
1094 | + QTest::mousePress(m_view, Qt::LeftButton, 0 /*modifiers*/, mousePos); |
1095 | + |
1096 | + qApp->processEvents(); |
1097 | + |
1098 | + QCOMPARE(pressedOutsideSpy.count(), 1); |
1099 | + |
1100 | + QTest::mouseRelease(m_view, Qt::LeftButton, 0 /*modifiers*/, mousePos); |
1101 | +} |
1102 | + |
1103 | +void tst_PressedOutsideNotifier::mousePresssInsideAreaHasNoEffect() |
1104 | +{ |
1105 | + QPoint mousePos = QPoint(m_blueRect->x() + m_blueRect->width()*0.5, |
1106 | + m_blueRect->y() + m_blueRect->height()*0.5); |
1107 | + |
1108 | + QSignalSpy pressedOutsideSpy(m_notifier, SIGNAL(pressedOutside())); |
1109 | + |
1110 | + QTest::mousePress(m_view, Qt::LeftButton, 0 /*modifiers*/, mousePos); |
1111 | + |
1112 | + qApp->processEvents(); |
1113 | + |
1114 | + QCOMPARE(pressedOutsideSpy.count(), 0); |
1115 | + |
1116 | + QTest::mouseRelease(m_view, Qt::LeftButton, 0 /*modifiers*/, mousePos); |
1117 | +} |
1118 | + |
1119 | +void tst_PressedOutsideNotifier::nothingHappensWhileDisabled() |
1120 | +{ |
1121 | + QPoint touch0 = QPoint(m_blueRect->x() - 50, m_blueRect->y() - 50); |
1122 | + |
1123 | + QSignalSpy pressedOutsideSpy(m_notifier, SIGNAL(pressedOutside())); |
1124 | + |
1125 | + m_notifier->setEnabled(false); |
1126 | + |
1127 | + QTest::touchEvent(m_view, m_device) |
1128 | + .press(0, touch0); |
1129 | + |
1130 | + qApp->processEvents(); |
1131 | + |
1132 | + QCOMPARE(pressedOutsideSpy.count(), 0); |
1133 | + |
1134 | + QTest::touchEvent(m_view, m_device) |
1135 | + .release(0, touch0); |
1136 | +} |
1137 | + |
1138 | +QTEST_MAIN(tst_PressedOutsideNotifier) |
1139 | + |
1140 | +#include "tst_PressedOutsideNotifier.moc" |
1141 | |
1142 | === added file 'tests/plugins/Ubuntu/Gestures/tst_PressedOutsideNotifier.qml' |
1143 | --- tests/plugins/Ubuntu/Gestures/tst_PressedOutsideNotifier.qml 1970-01-01 00:00:00 +0000 |
1144 | +++ tests/plugins/Ubuntu/Gestures/tst_PressedOutsideNotifier.qml 2013-11-22 10:45:28 +0000 |
1145 | @@ -0,0 +1,61 @@ |
1146 | +/* |
1147 | + * Copyright (C) 2013 Canonical, Ltd. |
1148 | + * |
1149 | + * This program is free software; you can redistribute it and/or modify |
1150 | + * it under the terms of the GNU General Public License as published by |
1151 | + * the Free Software Foundation; version 3. |
1152 | + * |
1153 | + * This program is distributed in the hope that it will be useful, |
1154 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1155 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1156 | + * GNU General Public License for more details. |
1157 | + * |
1158 | + * You should have received a copy of the GNU General Public License |
1159 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1160 | + */ |
1161 | + |
1162 | +import QtQuick 2.0 |
1163 | +import Ubuntu.Gestures 0.1 |
1164 | + |
1165 | +/* |
1166 | + NB: If you change positions or sizes here make sure |
1167 | + tst_PressedOutsideNotifier.cpp is updated accordingly |
1168 | + */ |
1169 | + |
1170 | +Rectangle { |
1171 | + width: 600 |
1172 | + height: 600 |
1173 | + color: "white" |
1174 | + |
1175 | + Rectangle { |
1176 | + id: blueRect |
1177 | + objectName: "blueRect" |
1178 | + color: "blue" |
1179 | + x: 100 |
1180 | + y: 100 |
1181 | + width: 200 |
1182 | + height: 200 |
1183 | + |
1184 | + Timer { |
1185 | + id: resetColorTimer |
1186 | + interval: 300 |
1187 | + repeat: false |
1188 | + onTriggered: { |
1189 | + blueRect.color = "blue"; |
1190 | + } |
1191 | + } |
1192 | + |
1193 | + function blinkRed() { |
1194 | + blueRect.color = "red"; |
1195 | + resetColorTimer.start(); |
1196 | + } |
1197 | + |
1198 | + PressedOutsideNotifier { |
1199 | + objectName: "pressedOutsideNotifier" |
1200 | + anchors.fill: parent |
1201 | + onPressedOutside: { |
1202 | + blueRect.blinkRed(); |
1203 | + } |
1204 | + } |
1205 | + } |
1206 | +} |
1207 | |
1208 | === modified file 'tests/qmltests/CMakeLists.txt' |
1209 | --- tests/qmltests/CMakeLists.txt 2013-11-19 09:43:35 +0000 |
1210 | +++ tests/qmltests/CMakeLists.txt 2013-11-22 10:45:28 +0000 |
1211 | @@ -46,7 +46,9 @@ |
1212 | add_qml_test(Dash GenericScopeView IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS}) |
1213 | add_qml_test(Dash FilterGrids IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/plugins ${CMAKE_CURRENT_SOURCE_DIR}/plugins |
1214 | ${CMAKE_BINARY_DIR}/tests/mocks) |
1215 | -add_qml_test(Dash/Apps RunningApplicationsGrid IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/tests/mocks) |
1216 | +add_qml_test(Dash/Apps RunningApplicationsGrid IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} |
1217 | + ${CMAKE_BINARY_DIR}/tests/mocks |
1218 | + ${CMAKE_BINARY_DIR}/plugins) |
1219 | add_qml_test(Dash/Apps AppPreview IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/tests/mocks) |
1220 | add_qml_test(Dash/Movie MoviePreview IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/tests/mocks) |
1221 | add_qml_test(Greeter Lockscreen IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS} |
1222 | |
1223 | === modified file 'tests/qmltests/Dash/Apps/tst_RunningApplicationsGrid.qml' |
1224 | --- tests/qmltests/Dash/Apps/tst_RunningApplicationsGrid.qml 2013-10-25 07:59:15 +0000 |
1225 | +++ tests/qmltests/Dash/Apps/tst_RunningApplicationsGrid.qml 2013-11-22 10:45:28 +0000 |
1226 | @@ -239,5 +239,25 @@ |
1227 | return findChild(runningApplicationsGrid, "runningAppTile Calendar") |
1228 | != undefined |
1229 | } |
1230 | + |
1231 | + // While in termination mode, if you click outside any of the tiles, the |
1232 | + // termination mode is disabled (i.e. we switch back to activation mode). |
1233 | + function test_clickOutsideTilesDisablesTerminationMode() { |
1234 | + runningApplicationsGrid.terminationModeEnabled = true |
1235 | + |
1236 | + var calendarTile = findChild(runningApplicationsGrid, "runningAppTile Calendar") |
1237 | + verify(calendarTile != undefined) |
1238 | + |
1239 | + verify(runningApplicationsGrid.terminationModeEnabled); |
1240 | + |
1241 | + // Click on the bottom right corner of the grid, where there's no |
1242 | + // RunningApplicationTile lying around |
1243 | + mouseClick(runningApplicationsGrid, |
1244 | + runningApplicationsGrid.width - 1, runningApplicationsGrid.height - 1); |
1245 | + |
1246 | + wait(0) // spin event loop to ensure that any pending signal emission went through |
1247 | + |
1248 | + verify(!runningApplicationsGrid.terminationModeEnabled); |
1249 | + } |
1250 | } |
1251 | } |
FAILED: Continuous integration, rev:537 jenkins. qa.ubuntu. com/job/ unity8- ci/1685/ jenkins. qa.ubuntu. com/job/ generic- mediumtests- trusty/ 930/console jenkins. qa.ubuntu. com/job/ generic- mediumtests- trusty- touch/914/ console jenkins. qa.ubuntu. com/job/ unity-phablet- qmluitests- trusty/ 335/console jenkins. qa.ubuntu. com/job/ unity8- trusty- amd64-ci/ 208/console jenkins. qa.ubuntu. com/job/ unity8- trusty- armhf-ci/ 209/console jenkins. qa.ubuntu. com/job/ unity8- trusty- i386-ci/ 208/console jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- trusty- amd64/930/ console jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- trusty- armhf/914/ console
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/unity8- ci/1685/ rebuild
http://