Merge lp:~mzanetti/unity8/dash-as-app into lp:unity8
- dash-as-app
- Merge into trunk
Status: | Rejected |
---|---|
Rejected by: | Michael Zanetti |
Proposed branch: | lp:~mzanetti/unity8/dash-as-app |
Merge into: | lp:unity8 |
Prerequisite: | lp:~mzanetti/unity8/drop-running-apps-from-dash |
Diff against target: |
2874 lines (+972/-763) (has conflicts) 51 files modified
CMakeLists.txt (+1/-0) data/CMakeLists.txt (+5/-2) data/unity8-dash.conf (+22/-0) data/unity8-dash.desktop.in (+9/-0) data/unity8.conf (+1/-7) debian/unity8.install (+3/-0) plugins/Unity/CMakeLists.txt (+1/-0) plugins/Unity/DashCommunicator/CMakeLists.txt (+19/-0) plugins/Unity/DashCommunicator/dashcommunicator.cpp (+43/-0) plugins/Unity/DashCommunicator/dashcommunicator.h (+35/-0) plugins/Unity/DashCommunicator/dashcommunicatorservice.cpp (+30/-0) plugins/Unity/DashCommunicator/dashcommunicatorservice.h (+38/-0) plugins/Unity/DashCommunicator/dbusdashcommunicatorservice.cpp (+39/-0) plugins/Unity/DashCommunicator/dbusdashcommunicatorservice.h (+39/-0) plugins/Unity/DashCommunicator/plugin.cpp (+31/-0) plugins/Unity/DashCommunicator/plugin.h (+34/-0) plugins/Unity/DashCommunicator/qmldir (+3/-0) plugins/Unity/Launcher/launchermodel.cpp (+5/-0) qml/Components/EdgeDemo.qml (+5/-6) qml/Dash/Dash.qml (+8/-0) qml/Dash/DashApplication.qml (+13/-0) qml/Dash/GenericScopeView.qml (+1/-1) qml/Dash/ScopeListView.qml (+0/-5) qml/Launcher/Launcher.qml (+2/-3) qml/Shell.qml (+23/-124) qml/Stages/PhoneStage.qml (+60/-26) qml/Stages/SpreadDelegate.qml (+6/-0) qml/Stages/TabletStage.qml (+82/-36) qml/Stages/TransformedSpreadDelegate.qml (+6/-5) qml/Stages/TransformedTabletSpreadDelegate.qml (+29/-1) src/CMakeLists.txt (+1/-0) src/Dash/CMakeLists.txt (+12/-0) src/Dash/main.cpp (+49/-0) tests/mocks/Unity/Application/ApplicationInfo.cpp (+0/-62) tests/mocks/Unity/Application/ApplicationInfo.h (+0/-10) tests/mocks/Unity/Application/ApplicationManager.cpp (+15/-142) tests/mocks/Unity/Application/ApplicationManager.h (+0/-16) tests/mocks/Unity/Application/ApplicationScreenshotProvider.cpp (+1/-1) tests/mocks/Unity/CMakeLists.txt (+1/-0) tests/mocks/Unity/DashCommunicator/CMakeLists.txt (+18/-0) tests/mocks/Unity/DashCommunicator/dashcommunicator.cpp (+37/-0) tests/mocks/Unity/DashCommunicator/dashcommunicator.h (+39/-0) tests/mocks/Unity/DashCommunicator/dashcommunicatorservice.cpp (+33/-0) tests/mocks/Unity/DashCommunicator/dashcommunicatorservice.h (+36/-0) tests/mocks/Unity/DashCommunicator/plugin.cpp (+31/-0) tests/mocks/Unity/DashCommunicator/plugin.h (+34/-0) tests/mocks/Unity/DashCommunicator/qmldir (+3/-0) tests/qmltests/Dash/tst_Dash.qml (+19/-0) tests/qmltests/Stages/tst_PhoneStage.qml (+3/-2) tests/qmltests/tst_Shell.qml (+43/-277) tests/qmltests/tst_ShellWithPin.qml (+4/-37) Text conflict in debian/changelog |
To merge this branch: | bzr merge lp:~mzanetti/unity8/dash-as-app |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
PS Jenkins bot (community) | continuous-integration | Needs Fixing | |
Michael Zanetti (community) | Disapprove | ||
Daniel d'Andrada (community) | Needs Fixing | ||
Michał Sawicz | Needs Fixing | ||
Review via email: mp+227868@code.launchpad.net |
Commit message
Split the dash from the shell into a separate app
Description of the change
### Notes for reviewers ###
* It depends on QtCompositor (silo 6). Alternatively this and qtcomp rc can be installed through ppa:unity-
* Adds an upstart script to autolaunch and respawn the dash app.
* Introduces a new plugin DashCommunicator which consists of a server and a client part, to be used to communicate between shell and dash.
* Adds a mock plugin for the DashCommunicator plugin
* Drops a whole bunch of useless stuff from MockApplication
* Adds a fake unity8-dash app (screenshot) to MockApplication
* Drops some code and tests for stages in/out dragging, given the dash is a regular app now, the stages are always visible now.
* Updates/simplifies shell and dash tests for the split app scenario.
* Does some slight updates to the Stages to keep the Dash behind the current app when not in spread mode so a left edge flick still shows the dash behind the app.
### Still TODO ###
* Make autopilot work again
### Checklist ###
* Are there any related MPs required for this MP to build/function as expected? Please list.
https:/
* Did you perform an exploratory manual test run of your code change and any related functionality?
Yes, works fine for me, except launching apps from dash and AP (see TODO section)
* 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?
I added the additional binary and upstart script to installs, to be reviewed.
* If you changed the UI, has there been a design review?
Vesa is on holiday atm. I tried to keep UI changes as minimal as possible to fulfill the design request of adding the dash into the spread. So should be good I hope.
- 1123. By Michael Zanetti
-
review-fixes for upstart script
Michael Zanetti (mzanetti) wrote : | # |
> See inline.
Fixed/replied.
>
> Now, on DashCommunicator... I was wondering if we should instead register a
> scope:/// url handler, and then just dispatch scope:/
> needed.
>
> Only tricky part would be on left edge, when we should bring the dash in from
> the left with your finger, url-dispatcher would request focus, but we should
> ignore that request then.
I agree the url handler sounds like a useful/required thing for the future, however, as you already mentioned it adds complexity. I tend to think we need both in the long run.
Michael Zanetti (mzanetti) wrote : | # |
inline...
- 1124. By Michael Zanetti
-
merge prereq
- 1125. By Michael Zanetti
-
merge prereq
Daniel d'Andrada (dandrader) : | # |
Daniel d'Andrada (dandrader) wrote : | # |
Repeating as the inline comments don't work so well.
In SpreadDelegate.qml
"""
1114 + objectName: "surfaceContainer" + index
"""
Using index from inside SpreadDelegate breaks encapsulation. You can achive the same result in tst_Shell.qml by fetching first "appDelegate0" and then fecthing the "surfaceContainer" from within "appDelegate0".
- 1126. By Michael Zanetti
-
fix review comment and test
Michael Zanetti (mzanetti) wrote : | # |
thanks Daniel. Fixed it.
Daniel d'Andrada (dandrader) wrote : | # |
Solved the issue I found. But as I didn't actually go through the full diff at all I'll just unblock it by abstaining.
Daniel d'Andrada (dandrader) wrote : | # |
$ make tryShell
1 - launch an app from the launcher
2 - tap on it
<vkb shows up>
3 - do a left edge drag
expected result:
vkb should go away as soon as the app window starts moving righwards.
Just like when you start a right-edge gesture.
actual result:
vkb goes away only once you finish the gesture
vkb going away means the MirSurfaceItem losing focus which on its turn means the SpreadDelegate.
- 1127. By Michael Zanetti
-
make the spread non-interactive when dragging from left
Michael Zanetti (mzanetti) wrote : | # |
> $ make tryShell
> 1 - launch an app from the launcher
> 2 - tap on it
> <vkb shows up>
> 3 - do a left edge drag
>
> expected result:
> vkb should go away as soon as the app window starts moving righwards.
> Just like when you start a right-edge gesture.
>
> actual result:
> vkb goes away only once you finish the gesture
>
> vkb going away means the MirSurfaceItem losing focus which on its turn means
> the SpreadDelegate.
another good catch. fixed.
Michael Zanetti (mzanetti) wrote : | # |
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1122
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Unmerged revisions
- 1127. By Michael Zanetti
-
make the spread non-interactive when dragging from left
- 1126. By Michael Zanetti
-
fix review comment and test
- 1125. By Michael Zanetti
-
merge prereq
- 1124. By Michael Zanetti
-
merge prereq
- 1123. By Michael Zanetti
-
review-fixes for upstart script
- 1122. By Michael Zanetti
-
one more fix for the side stage
- 1121. By Michael Zanetti
-
more fixes for tablet mode
- 1120. By Michael Zanetti
-
small fix for tablet stage
- 1119. By Michael Zanetti
-
fix some visual glitches in the tabletstage
- 1118. By Michael Zanetti
-
don't bahave xTranslate when dragging the side stage
Preview Diff
1 | === modified file 'CMakeLists.txt' |
2 | --- CMakeLists.txt 2014-06-11 15:36:51 +0000 |
3 | +++ CMakeLists.txt 2014-07-28 15:50:22 +0000 |
4 | @@ -96,6 +96,7 @@ |
5 | declare_autopilot_test(shell unity8.shell ${CMAKE_SOURCE_DIR}/tests/autopilot/) |
6 | |
7 | set(SHELL_APP unity8) |
8 | +set(DASH_APP unity8-dash) |
9 | set(SCOPE_TOOL unity-scope-tool) |
10 | |
11 | include_directories( |
12 | |
13 | === modified file 'data/CMakeLists.txt' |
14 | --- data/CMakeLists.txt 2014-06-11 15:36:51 +0000 |
15 | +++ data/CMakeLists.txt 2014-07-28 15:50:22 +0000 |
16 | @@ -1,7 +1,10 @@ |
17 | -# generate desktop file |
18 | +# generate desktop files |
19 | configure_file(${SHELL_APP}.desktop.in ${CMAKE_CURRENT_BINARY_DIR}/${SHELL_APP}.desktop @ONLY) |
20 | +configure_file(${DASH_APP}.desktop.in ${CMAKE_CURRENT_BINARY_DIR}/${DASH_APP}.desktop @ONLY) |
21 | |
22 | # install desktop files |
23 | -install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${SHELL_APP}.desktop |
24 | +install(FILES |
25 | + ${CMAKE_CURRENT_BINARY_DIR}/${SHELL_APP}.desktop |
26 | + ${CMAKE_CURRENT_BINARY_DIR}/${DASH_APP}.desktop |
27 | DESTINATION ${CMAKE_INSTALL_DATADIR}/applications |
28 | ) |
29 | |
30 | === added file 'data/unity8-dash.conf' |
31 | --- data/unity8-dash.conf 1970-01-01 00:00:00 +0000 |
32 | +++ data/unity8-dash.conf 2014-07-28 15:50:22 +0000 |
33 | @@ -0,0 +1,22 @@ |
34 | +description "Unity Shell v8 Dash" |
35 | +author "Michael Zanetti <michael.zanetti@canonical.com>" |
36 | + |
37 | +emits scope-ui-starting |
38 | + |
39 | +start on started unity8 |
40 | +stop on stopping unity8 |
41 | + |
42 | +kill timeout 120 |
43 | + |
44 | +respawn |
45 | + |
46 | +pre-start script |
47 | + if [ -z "$UNITY_SCOPES_LIST" ]; then |
48 | + # FIXME: remove once we have this in dconf |
49 | + initctl set-env UNITY_SCOPES_LIST="scopes;clickscope;musicaggregator;videoaggregator" |
50 | + fi |
51 | + |
52 | + initctl emit scope-ui-starting |
53 | +end script |
54 | + |
55 | +exec ${BINARY:-unity8-dash} $ARGS --desktop_file_hint=/usr/share/applications/unity8-dash.desktop |
56 | |
57 | === added file 'data/unity8-dash.desktop.in' |
58 | --- data/unity8-dash.desktop.in 1970-01-01 00:00:00 +0000 |
59 | +++ data/unity8-dash.desktop.in 2014-07-28 15:50:22 +0000 |
60 | @@ -0,0 +1,9 @@ |
61 | +[Desktop Entry] |
62 | +Type=Application |
63 | +Name=Unity 8 Dash |
64 | +Comment=The converged Unity shell dash |
65 | +Exec=@CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_BINDIR@/unity8-dash |
66 | +Terminal=false |
67 | +Icon=unity8 |
68 | +NoDisplay=true |
69 | +X-Ubuntu-Touch=true |
70 | |
71 | === modified file 'data/unity8.conf' |
72 | --- data/unity8.conf 2014-07-16 15:51:56 +0000 |
73 | +++ data/unity8.conf 2014-07-28 15:50:22 +0000 |
74 | @@ -1,7 +1,7 @@ |
75 | description "Unity Shell v8" |
76 | author "Ricardo Mendoza <ricmm@ubuntu.com>" |
77 | |
78 | -emits scope-ui-starting indicator-services-start |
79 | +emits indicator-services-start |
80 | |
81 | start on ((xsession SESSION=ubuntu-touch) or (xsession SESSION=ubuntu-touch-surfaceflinger)) and started dbus |
82 | stop on desktop-end |
83 | @@ -34,11 +34,6 @@ |
84 | gdbus call --session --dest org.freedesktop.DBus --object-path /org/freedesktop/DBus --method org.freedesktop.DBus.UpdateActivationEnvironment "@a{ss} {'MIR_SOCKET': '$MIR_SERVER_FILE'}" |
85 | fi |
86 | |
87 | - if [ -z "$UNITY_SCOPES_LIST" ]; then |
88 | - # FIXME: remove once we have this in dconf |
89 | - initctl set-env UNITY_SCOPES_LIST="scopes;clickscope;musicaggregator;videoaggregator" |
90 | - fi |
91 | - |
92 | # Remove the socket if still there |
93 | if [ -S "$MIR_SERVER_FILE" ]; then |
94 | rm "$MIR_SERVER_FILE" |
95 | @@ -46,7 +41,6 @@ |
96 | |
97 | initctl set-env --global MIR_SERVER_PROMPT_FILE=1 |
98 | |
99 | - initctl emit scope-ui-starting |
100 | initctl emit --no-wait indicator-services-start |
101 | end script |
102 | |
103 | |
104 | === modified file 'debian/unity8.install' |
105 | --- debian/unity8.install 2014-06-11 15:36:51 +0000 |
106 | +++ debian/unity8.install 2014-07-28 15:50:22 +0000 |
107 | @@ -1,6 +1,9 @@ |
108 | data/unity8.conf usr/share/upstart/sessions/ |
109 | +data/unity8-dash.conf usr/share/upstart/sessions/ |
110 | usr/bin/unity8 |
111 | +usr/bin/unity8-dash |
112 | usr/share/applications/unity8.desktop |
113 | +usr/share/applications/unity8-dash.desktop |
114 | usr/share/unity8/Greeter |
115 | usr/share/unity8/Hud |
116 | usr/share/unity8/Launcher |
117 | |
118 | === modified file 'plugins/Unity/CMakeLists.txt' |
119 | --- plugins/Unity/CMakeLists.txt 2014-05-06 14:28:48 +0000 |
120 | +++ plugins/Unity/CMakeLists.txt 2014-07-28 15:50:22 +0000 |
121 | @@ -1,3 +1,4 @@ |
122 | add_subdirectory(Indicators) |
123 | add_subdirectory(Launcher) |
124 | add_subdirectory(Session) |
125 | +add_subdirectory(DashCommunicator) |
126 | |
127 | === added directory 'plugins/Unity/DashCommunicator' |
128 | === added file 'plugins/Unity/DashCommunicator/CMakeLists.txt' |
129 | --- plugins/Unity/DashCommunicator/CMakeLists.txt 1970-01-01 00:00:00 +0000 |
130 | +++ plugins/Unity/DashCommunicator/CMakeLists.txt 2014-07-28 15:50:22 +0000 |
131 | @@ -0,0 +1,19 @@ |
132 | +include_directories( |
133 | + ${CMAKE_CURRENT_SOURCE_DIR} |
134 | +) |
135 | + |
136 | +set(QMLDASHCOMMUNICATORPLUGIN_SRC |
137 | + plugin.cpp |
138 | + dbusdashcommunicatorservice.cpp |
139 | + dashcommunicatorservice.cpp |
140 | + dashcommunicator.cpp |
141 | + ) |
142 | + |
143 | +add_library(DashCommunicator-qml MODULE |
144 | + ${QMLDASHCOMMUNICATORPLUGIN_SRC} |
145 | + ) |
146 | + |
147 | +qt5_use_modules(DashCommunicator-qml DBus Qml) |
148 | + |
149 | +# export the qmldir and qmltypes files |
150 | +add_unity8_plugin(Unity.DashCommunicator 0.1 Unity/DashCommunicator TARGETS DashCommunicator-qml) |
151 | |
152 | === added file 'plugins/Unity/DashCommunicator/dashcommunicator.cpp' |
153 | --- plugins/Unity/DashCommunicator/dashcommunicator.cpp 1970-01-01 00:00:00 +0000 |
154 | +++ plugins/Unity/DashCommunicator/dashcommunicator.cpp 2014-07-28 15:50:22 +0000 |
155 | @@ -0,0 +1,43 @@ |
156 | +/* |
157 | + * Copyright (C) 2014 Canonical, Ltd. |
158 | + * |
159 | + * This program is free software: you can redistribute it and/or modify it under |
160 | + * the terms of the GNU Lesser General Public License version 3, as published by |
161 | + * the Free Software Foundation. |
162 | + * |
163 | + * This program is distributed in the hope that it will be useful, but WITHOUT |
164 | + * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, |
165 | + * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
166 | + * Lesser General Public License for more details. |
167 | + * |
168 | + * You should have received a copy of the GNU Lesser General Public License |
169 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
170 | + */ |
171 | + |
172 | +#include "dashcommunicator.h" |
173 | + |
174 | +#include <QObject> |
175 | +#include <QDBusConnection> |
176 | +#include <QDBusInterface> |
177 | +#include <QDebug> |
178 | + |
179 | +DashCommunicator::DashCommunicator(QObject *parent): |
180 | + QObject(parent) |
181 | +{ |
182 | +} |
183 | + |
184 | +DashCommunicator::~DashCommunicator() |
185 | +{ |
186 | +} |
187 | + |
188 | + |
189 | +void DashCommunicator::setCurrentScope(const QString &scopeId, bool animate, bool reset) |
190 | +{ |
191 | + QDBusConnection connection = QDBusConnection::sessionBus(); |
192 | + QDBusInterface dashIface ("com.canonical.UnityDash", |
193 | + "/com/canonical/UnityDash", |
194 | + "", |
195 | + connection); |
196 | + |
197 | + dashIface.call("SetCurrentScope", scopeId, animate, reset); |
198 | +} |
199 | |
200 | === added file 'plugins/Unity/DashCommunicator/dashcommunicator.h' |
201 | --- plugins/Unity/DashCommunicator/dashcommunicator.h 1970-01-01 00:00:00 +0000 |
202 | +++ plugins/Unity/DashCommunicator/dashcommunicator.h 2014-07-28 15:50:22 +0000 |
203 | @@ -0,0 +1,35 @@ |
204 | +/* |
205 | + * Copyright (C) 2014 Canonical, Ltd. |
206 | + * |
207 | + * This program is free software: you can redistribute it and/or modify it under |
208 | + * the terms of the GNU Lesser General Public License version 3, as published by |
209 | + * the Free Software Foundation. |
210 | + * |
211 | + * This program is distributed in the hope that it will be useful, but WITHOUT |
212 | + * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, |
213 | + * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
214 | + * Lesser General Public License for more details. |
215 | + * |
216 | + * You should have received a copy of the GNU Lesser General Public License |
217 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
218 | + */ |
219 | + |
220 | +#ifndef DASHCOMMUNICATOR_H |
221 | +#define DASHCOMMUNICATOR_H |
222 | + |
223 | +#include <QObject> |
224 | + |
225 | +class DashCommunicator: public QObject |
226 | +{ |
227 | + Q_OBJECT |
228 | + Q_CLASSINFO("D-Bus Interface", "com.canonical.Unity.DashCommunicator") |
229 | + |
230 | +public: |
231 | + DashCommunicator(QObject *parent = 0); |
232 | + ~DashCommunicator(); |
233 | + |
234 | +public Q_SLOTS: |
235 | + void setCurrentScope(const QString &scopeId, bool animate, bool reset); |
236 | +}; |
237 | + |
238 | +#endif |
239 | |
240 | === added file 'plugins/Unity/DashCommunicator/dashcommunicatorservice.cpp' |
241 | --- plugins/Unity/DashCommunicator/dashcommunicatorservice.cpp 1970-01-01 00:00:00 +0000 |
242 | +++ plugins/Unity/DashCommunicator/dashcommunicatorservice.cpp 2014-07-28 15:50:22 +0000 |
243 | @@ -0,0 +1,30 @@ |
244 | +/* |
245 | + * Copyright (C) 2014 Canonical, Ltd. |
246 | + * |
247 | + * This program is free software: you can redistribute it and/or modify it under |
248 | + * the terms of the GNU Lesser General Public License version 3, as published by |
249 | + * the Free Software Foundation. |
250 | + * |
251 | + * This program is distributed in the hope that it will be useful, but WITHOUT |
252 | + * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, |
253 | + * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
254 | + * Lesser General Public License for more details. |
255 | + * |
256 | + * You should have received a copy of the GNU Lesser General Public License |
257 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
258 | + */ |
259 | + |
260 | +#include "dashcommunicatorservice.h" |
261 | + |
262 | +DashCommunicatorService::DashCommunicatorService(QObject *parent): |
263 | + QObject(parent), |
264 | + m_dbusService(new DBusDashCommunicatorService(this)) |
265 | +{ |
266 | + connect(m_dbusService, &DBusDashCommunicatorService::setCurrentScope, this, &DashCommunicatorService::setCurrentScope); |
267 | +} |
268 | + |
269 | + |
270 | +DashCommunicatorService::~DashCommunicatorService() |
271 | +{ |
272 | + |
273 | +} |
274 | |
275 | === added file 'plugins/Unity/DashCommunicator/dashcommunicatorservice.h' |
276 | --- plugins/Unity/DashCommunicator/dashcommunicatorservice.h 1970-01-01 00:00:00 +0000 |
277 | +++ plugins/Unity/DashCommunicator/dashcommunicatorservice.h 2014-07-28 15:50:22 +0000 |
278 | @@ -0,0 +1,38 @@ |
279 | +/* |
280 | + * Copyright (C) 2014 Canonical, Ltd. |
281 | + * |
282 | + * This program is free software: you can redistribute it and/or modify it under |
283 | + * the terms of the GNU Lesser General Public License version 3, as published by |
284 | + * the Free Software Foundation. |
285 | + * |
286 | + * This program is distributed in the hope that it will be useful, but WITHOUT |
287 | + * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, |
288 | + * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
289 | + * Lesser General Public License for more details. |
290 | + * |
291 | + * You should have received a copy of the GNU Lesser General Public License |
292 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
293 | + */ |
294 | + |
295 | +#ifndef DASHCOMMUNICATORSERVICE_H |
296 | +#define DASHCOMMUNICATORSERVICE_H |
297 | + |
298 | +#include "dbusdashcommunicatorservice.h" |
299 | + |
300 | +#include <QObject> |
301 | + |
302 | +class DashCommunicatorService: public QObject |
303 | +{ |
304 | + Q_OBJECT |
305 | +public: |
306 | + DashCommunicatorService(QObject *parent = 0); |
307 | + ~DashCommunicatorService(); |
308 | + |
309 | +Q_SIGNALS: |
310 | + void setCurrentScope(const QString &scopeId, bool animate, bool reset); |
311 | + |
312 | +private: |
313 | + DBusDashCommunicatorService *m_dbusService; |
314 | +}; |
315 | + |
316 | +#endif // DBUSUNITYSESSIONSERVICE_H |
317 | |
318 | === added file 'plugins/Unity/DashCommunicator/dbusdashcommunicatorservice.cpp' |
319 | --- plugins/Unity/DashCommunicator/dbusdashcommunicatorservice.cpp 1970-01-01 00:00:00 +0000 |
320 | +++ plugins/Unity/DashCommunicator/dbusdashcommunicatorservice.cpp 2014-07-28 15:50:22 +0000 |
321 | @@ -0,0 +1,39 @@ |
322 | +/* |
323 | + * Copyright (C) 2014 Canonical, Ltd. |
324 | + * |
325 | + * This program is free software: you can redistribute it and/or modify it under |
326 | + * the terms of the GNU Lesser General Public License version 3, as published by |
327 | + * the Free Software Foundation. |
328 | + * |
329 | + * This program is distributed in the hope that it will be useful, but WITHOUT |
330 | + * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, |
331 | + * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
332 | + * Lesser General Public License for more details. |
333 | + * |
334 | + * You should have received a copy of the GNU Lesser General Public License |
335 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
336 | + */ |
337 | + |
338 | +#include "dbusdashcommunicatorservice.h" |
339 | + |
340 | +#include <QDBusConnection> |
341 | +#include <QDBusInterface> |
342 | +#include <QDebug> |
343 | + |
344 | +DBusDashCommunicatorService::DBusDashCommunicatorService(QObject *parent): |
345 | + QObject(parent) |
346 | +{ |
347 | + QDBusConnection connection = QDBusConnection::sessionBus(); |
348 | + |
349 | + connection.registerService("com.canonical.UnityDash"); |
350 | + connection.registerObject("/com/canonical/UnityDash", this, QDBusConnection::ExportScriptableSlots); |
351 | +} |
352 | + |
353 | +DBusDashCommunicatorService::~DBusDashCommunicatorService() |
354 | +{ |
355 | +} |
356 | + |
357 | +void DBusDashCommunicatorService::SetCurrentScope(const QString &scopeId, bool animate, bool reset) |
358 | +{ |
359 | + Q_EMIT setCurrentScope(scopeId, animate, reset); |
360 | +} |
361 | |
362 | === added file 'plugins/Unity/DashCommunicator/dbusdashcommunicatorservice.h' |
363 | --- plugins/Unity/DashCommunicator/dbusdashcommunicatorservice.h 1970-01-01 00:00:00 +0000 |
364 | +++ plugins/Unity/DashCommunicator/dbusdashcommunicatorservice.h 2014-07-28 15:50:22 +0000 |
365 | @@ -0,0 +1,39 @@ |
366 | +/* |
367 | + * Copyright (C) 2014 Canonical, Ltd. |
368 | + * |
369 | + * This program is free software: you can redistribute it and/or modify it under |
370 | + * the terms of the GNU Lesser General Public License version 3, as published by |
371 | + * the Free Software Foundation. |
372 | + * |
373 | + * This program is distributed in the hope that it will be useful, but WITHOUT |
374 | + * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, |
375 | + * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
376 | + * Lesser General Public License for more details. |
377 | + * |
378 | + * You should have received a copy of the GNU Lesser General Public License |
379 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
380 | + */ |
381 | + |
382 | +#ifndef DBUSDASHCOMMUNICATORSERVICE_H |
383 | +#define DBUSDASHCOMMUNICATORSERVICE_H |
384 | + |
385 | +#include <QObject> |
386 | + |
387 | +class DBusDashCommunicatorService: public QObject |
388 | +{ |
389 | + Q_OBJECT |
390 | + Q_CLASSINFO("D-Bus Interface", "com.canonical.Unity.DashCommunicator") |
391 | + |
392 | +public: |
393 | + DBusDashCommunicatorService(QObject *parent = 0); |
394 | + ~DBusDashCommunicatorService(); |
395 | + |
396 | +Q_SIGNALS: |
397 | + void setCurrentScope(const QString &scopeId, bool animate, bool reset); |
398 | + |
399 | +public Q_SLOTS: |
400 | + Q_SCRIPTABLE void SetCurrentScope(const QString &scopeId, bool animate, bool reset); |
401 | + |
402 | +}; |
403 | + |
404 | +#endif // DBUSUNITYSESSIONSERVICE_H |
405 | |
406 | === added file 'plugins/Unity/DashCommunicator/plugin.cpp' |
407 | --- plugins/Unity/DashCommunicator/plugin.cpp 1970-01-01 00:00:00 +0000 |
408 | +++ plugins/Unity/DashCommunicator/plugin.cpp 2014-07-28 15:50:22 +0000 |
409 | @@ -0,0 +1,31 @@ |
410 | +/* |
411 | + * Copyright (C) 2014 Canonical, Ltd. |
412 | + * |
413 | + * This program is free software; you can redistribute it and/or modify |
414 | + * it under the terms of the GNU General Public License as published by |
415 | + * the Free Software Foundation; version 3. |
416 | + * |
417 | + * This program is distributed in the hope that it will be useful, |
418 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
419 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
420 | + * GNU General Public License for more details. |
421 | + * |
422 | + * You should have received a copy of the GNU General Public License |
423 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
424 | + * |
425 | + * Authors: Michael Zanetti <michael.zanetti@canonical.com> |
426 | + */ |
427 | + |
428 | +#include "plugin.h" |
429 | +#include "dashcommunicator.h" |
430 | +#include "dashcommunicatorservice.h" |
431 | + |
432 | +#include <QDBusConnection> |
433 | +#include <QtQml/qqml.h> |
434 | + |
435 | +void DashCommunicatorPlugin::registerTypes(const char *uri) |
436 | +{ |
437 | + Q_ASSERT(uri == QStringLiteral("Unity.DashCommunicator")); |
438 | + qmlRegisterType<DashCommunicatorService>(uri, 0, 1, "DashCommunicatorService"); |
439 | + qmlRegisterType<DashCommunicator>(uri, 0, 1, "DashCommunicator"); |
440 | +} |
441 | |
442 | === added file 'plugins/Unity/DashCommunicator/plugin.h' |
443 | --- plugins/Unity/DashCommunicator/plugin.h 1970-01-01 00:00:00 +0000 |
444 | +++ plugins/Unity/DashCommunicator/plugin.h 2014-07-28 15:50:22 +0000 |
445 | @@ -0,0 +1,34 @@ |
446 | +/* |
447 | + * Copyright (C) 2014 Canonical, Ltd. |
448 | + * |
449 | + * This program is free software; you can redistribute it and/or modify |
450 | + * it under the terms of the GNU General Public License as published by |
451 | + * the Free Software Foundation; version 3. |
452 | + * |
453 | + * This program is distributed in the hope that it will be useful, |
454 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
455 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
456 | + * GNU General Public License for more details. |
457 | + * |
458 | + * You should have received a copy of the GNU General Public License |
459 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
460 | + * |
461 | + * Authors: Michael Zanetti <michael.zanetti@canonical.com> |
462 | + */ |
463 | + |
464 | +#ifndef DASHCOMMUNICATOR_PLUGIN_H |
465 | +#define DASHCOMMUNICATOR_PLUGIN_H |
466 | + |
467 | +#include <QtQml/QQmlEngine> |
468 | +#include <QtQml/QQmlExtensionPlugin> |
469 | + |
470 | +class DashCommunicatorPlugin : public QQmlExtensionPlugin |
471 | +{ |
472 | + Q_OBJECT |
473 | + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface") |
474 | + |
475 | +public: |
476 | + void registerTypes(const char *uri); |
477 | +}; |
478 | + |
479 | +#endif |
480 | |
481 | === added file 'plugins/Unity/DashCommunicator/qmldir' |
482 | --- plugins/Unity/DashCommunicator/qmldir 1970-01-01 00:00:00 +0000 |
483 | +++ plugins/Unity/DashCommunicator/qmldir 2014-07-28 15:50:22 +0000 |
484 | @@ -0,0 +1,3 @@ |
485 | +module Unity.DashCommunicator |
486 | +plugin DashCommunicator-qml |
487 | +typeinfo DashCommunicator.qmltypes |
488 | |
489 | === modified file 'plugins/Unity/Launcher/launchermodel.cpp' |
490 | --- plugins/Unity/Launcher/launchermodel.cpp 2014-07-24 06:11:07 +0000 |
491 | +++ plugins/Unity/Launcher/launchermodel.cpp 2014-07-28 15:50:22 +0000 |
492 | @@ -317,6 +317,11 @@ |
493 | return; |
494 | } |
495 | |
496 | + if (app->appId() == "unity8-dash") { |
497 | + // Not adding the dash app |
498 | + return; |
499 | + } |
500 | + |
501 | bool found = false; |
502 | Q_FOREACH(LauncherItem *item, m_list) { |
503 | if (app->appId() == item->appId()) { |
504 | |
505 | === modified file 'qml/Components/EdgeDemo.qml' |
506 | --- qml/Components/EdgeDemo.qml 2014-06-11 15:36:51 +0000 |
507 | +++ qml/Components/EdgeDemo.qml 2014-07-28 15:50:22 +0000 |
508 | @@ -22,7 +22,6 @@ |
509 | id: demo |
510 | |
511 | property Item greeter |
512 | - property Item dash |
513 | property Item launcher |
514 | property Item indicators |
515 | property Item underlay |
516 | @@ -144,7 +143,7 @@ |
517 | "edge": "top", |
518 | "title": i18n.tr("Top edge"), |
519 | "text": i18n.tr("Try swiping from the top edge to access the indicators"), |
520 | - "anchors.fill": demo.dash, |
521 | + "anchors.fill": demo.underlay, |
522 | }); |
523 | } |
524 | if (d.topEdgeDemo) { |
525 | @@ -193,12 +192,12 @@ |
526 | function startLeftEdgeDemo() { |
527 | demo.panelEnabled = false; |
528 | demo.launcherEnabled = true; |
529 | - if (demo.dash && demo.underlay) { |
530 | + if (demo.underlay) { |
531 | d.leftEdgeDemo = d.overlay.createObject(demo.underlay, { |
532 | "edge": "left", |
533 | "title": i18n.tr("Left edge"), |
534 | "text": i18n.tr("Swipe from the left to reveal the launcher for quick access to apps"), |
535 | - "anchors.fill": demo.dash, |
536 | + "anchors.fill": demo.underlay, |
537 | }); |
538 | } |
539 | if (d.leftEdgeDemo) { |
540 | @@ -221,12 +220,12 @@ |
541 | |
542 | function startFinalEdgeDemo() { |
543 | demo.launcherEnabled = false; |
544 | - if (demo.dash && demo.underlay) { |
545 | + if (demo.underlay) { |
546 | d.finalEdgeDemo = d.overlay.createObject(demo.underlay, { |
547 | "edge": "none", |
548 | "title": i18n.tr("Well done"), |
549 | "text": i18n.tr("You have now mastered the edge gestures and can start using the phone<br><br>Tap on the screen to start"), |
550 | - "anchors.fill": demo.dash, |
551 | + "anchors.fill": demo.underlay, |
552 | "showSkip": false, |
553 | }); |
554 | } |
555 | |
556 | === modified file 'qml/Dash/Dash.qml' |
557 | --- qml/Dash/Dash.qml 2014-07-07 08:20:04 +0000 |
558 | +++ qml/Dash/Dash.qml 2014-07-28 15:50:22 +0000 |
559 | @@ -18,6 +18,7 @@ |
560 | import Ubuntu.Components 0.1 |
561 | import Unity 0.2 |
562 | import Utils 0.1 |
563 | +import Unity.DashCommunicator 0.1 |
564 | import "../Components" |
565 | |
566 | Showable { |
567 | @@ -29,6 +30,13 @@ |
568 | property string showScopeOnLoaded: "clickscope" |
569 | property real contentScale: 1.0 |
570 | |
571 | + DashCommunicatorService { |
572 | + objectName: "dashCommunicatorService" |
573 | + onSetCurrentScope: { |
574 | + dash.setCurrentScope(scopeId, animate, reset) |
575 | + } |
576 | + } |
577 | + |
578 | function setCurrentScope(scopeId, animate, reset) { |
579 | var scopeIndex = filteredScopes.findFirst(Scopes.RoleId, scopeId) |
580 | |
581 | |
582 | === added file 'qml/Dash/DashApplication.qml' |
583 | --- qml/Dash/DashApplication.qml 1970-01-01 00:00:00 +0000 |
584 | +++ qml/Dash/DashApplication.qml 2014-07-28 15:50:22 +0000 |
585 | @@ -0,0 +1,13 @@ |
586 | +import QtQuick 2.2 |
587 | +import Ubuntu.Components 1.0 |
588 | + |
589 | +MainView { |
590 | + width: units.gu(40) |
591 | + height: units.gu(71) |
592 | + |
593 | + useDeprecatedToolbar: false |
594 | + |
595 | + Dash { |
596 | + anchors.fill: parent |
597 | + } |
598 | +} |
599 | |
600 | === modified file 'qml/Dash/GenericScopeView.qml' |
601 | --- qml/Dash/GenericScopeView.qml 2014-07-28 15:50:19 +0000 |
602 | +++ qml/Dash/GenericScopeView.qml 2014-07-28 15:50:22 +0000 |
603 | @@ -46,7 +46,7 @@ |
604 | } |
605 | |
606 | function activateApp(appId) { |
607 | - shell.activateApplication(appId); |
608 | + Qt.openUrlExternally(appId); |
609 | } |
610 | |
611 | function positionAtBeginning() { |
612 | |
613 | === modified file 'qml/Dash/ScopeListView.qml' |
614 | --- qml/Dash/ScopeListView.qml 2014-06-11 15:36:51 +0000 |
615 | +++ qml/Dash/ScopeListView.qml 2014-07-28 15:50:22 +0000 |
616 | @@ -20,9 +20,4 @@ |
617 | ListViewWithPageHeader { |
618 | maximumFlickVelocity: height * 10 |
619 | flickDeceleration: height * 2 |
620 | - |
621 | - Connections { |
622 | - target: greeter |
623 | - onShownChanged: if (greeter.shown) showHeader() |
624 | - } |
625 | } |
626 | |
627 | === added file 'qml/Dash/graphics/phone/screenshots/dash.png' |
628 | === added file 'qml/Dash/graphics/phone/screenshots/unity8-dash@12.png' |
629 | Binary files qml/Dash/graphics/phone/screenshots/unity8-dash@12.png 1970-01-01 00:00:00 +0000 and qml/Dash/graphics/phone/screenshots/unity8-dash@12.png 2014-07-28 15:50:22 +0000 differ |
630 | === modified file 'qml/Launcher/Launcher.qml' |
631 | --- qml/Launcher/Launcher.qml 2014-07-28 15:50:19 +0000 |
632 | +++ qml/Launcher/Launcher.qml 2014-07-28 15:50:22 +0000 |
633 | @@ -29,8 +29,7 @@ |
634 | property int dragAreaWidth: units.gu(1) |
635 | property int minimizeDistance: units.gu(26) |
636 | property real progress: dragArea.dragging && dragArea.touchX > panelWidth ? |
637 | - (width * (dragArea.touchX-panelWidth) / (width - panelWidth)) : |
638 | - (dragArea.dragging ? 0.001 : 0) |
639 | + (width * (dragArea.touchX-panelWidth) / (width - panelWidth)) : 0 |
640 | |
641 | readonly property bool shown: panel.x > -panel.width |
642 | |
643 | @@ -245,7 +244,7 @@ |
644 | if (!dragging) { |
645 | if (distance > panel.width / 2) { |
646 | if (distance > minimizeDistance) { |
647 | - root.dash() |
648 | + root.fadeOut(); |
649 | } else { |
650 | root.switchToNextState("visible") |
651 | } |
652 | |
653 | === modified file 'qml/Shell.qml' |
654 | --- qml/Shell.qml 2014-07-28 15:50:19 +0000 |
655 | +++ qml/Shell.qml 2014-07-28 15:50:22 +0000 |
656 | @@ -25,7 +25,6 @@ |
657 | import LightDM 0.1 as LightDM |
658 | import Powerd 0.1 |
659 | import SessionBroadcast 0.1 |
660 | -import "Dash" |
661 | import "Greeter" |
662 | import "Launcher" |
663 | import "Panel" |
664 | @@ -34,6 +33,7 @@ |
665 | import "Stages" |
666 | import Unity.Notifications 1.0 as NotificationBackend |
667 | import Unity.Session 0.1 |
668 | +import Unity.DashCommunicator 0.1 |
669 | |
670 | Item { |
671 | id: shell |
672 | @@ -48,8 +48,6 @@ |
673 | property url background |
674 | readonly property real panelHeight: panel.panelHeight |
675 | |
676 | - property bool dashShown: dash.shown && dash.available && underlay.visible |
677 | - |
678 | property bool sideStageEnabled: shell.width >= units.gu(100) |
679 | readonly property string focusedApplicationId: ApplicationManager.focusedApplicationId |
680 | |
681 | @@ -59,7 +57,6 @@ |
682 | } else { |
683 | var execFlags = shell.sideStageEnabled ? ApplicationManager.NoFlag : ApplicationManager.ForceMainStage; |
684 | ApplicationManager.startApplication(appId, execFlags); |
685 | - stages.show(); |
686 | } |
687 | } |
688 | |
689 | @@ -86,6 +83,11 @@ |
690 | id: volumeControl |
691 | } |
692 | |
693 | + DashCommunicator { |
694 | + id: dash |
695 | + objectName: "dashCommunicator" |
696 | + } |
697 | + |
698 | WindowKeysFilter { |
699 | // Handle but do not filter out volume keys |
700 | Keys.onVolumeUpPressed: { volumeControl.volumeUp(); event.accepted = false; } |
701 | @@ -121,64 +123,12 @@ |
702 | visible: !fullyCovered |
703 | |
704 | Image { |
705 | - anchors.fill: dash |
706 | + anchors.fill: underlay |
707 | source: shell.width > shell.height ? "Dash/graphics/paper_landscape.png" : "Dash/graphics/paper_portrait.png" |
708 | fillMode: Image.PreserveAspectCrop |
709 | horizontalAlignment: Image.AlignRight |
710 | verticalAlignment: Image.AlignTop |
711 | } |
712 | - |
713 | - Dash { |
714 | - id: dash |
715 | - objectName: "dash" |
716 | - |
717 | - available: !LightDM.Greeter.active |
718 | - hides: [stages, launcher, panel.indicators] |
719 | - shown: disappearingAnimationProgress !== 1.0 && greeterWrapper.showProgress !== 1.0 && |
720 | - !(panel.indicators.fullyOpened && !sideStageEnabled) |
721 | - enabled: disappearingAnimationProgress === 0.0 && greeterWrapper.showProgress === 0.0 && edgeDemo.dashEnabled |
722 | - |
723 | - anchors { |
724 | - fill: parent |
725 | - topMargin: panel.panelHeight |
726 | - } |
727 | - |
728 | - contentScale: 1.0 - 0.2 * disappearingAnimationProgress |
729 | - opacity: 1.0 - disappearingAnimationProgress |
730 | - property real disappearingAnimationProgress: stages.showProgress |
731 | - |
732 | - // FIXME: only necessary because stages.showProgress is not animated |
733 | - Behavior on disappearingAnimationProgress { SmoothedAnimation { velocity: 5 }} |
734 | - } |
735 | - } |
736 | - |
737 | - EdgeDragArea { |
738 | - id: stagesDragArea |
739 | - direction: Direction.Leftwards |
740 | - |
741 | - anchors { top: parent.top; right: parent.right; bottom: parent.bottom } |
742 | - width: shell.edgeSize |
743 | - |
744 | - property real progress: stages.width |
745 | - |
746 | - onTouchXChanged: { |
747 | - if (status == DirectionalDragArea.Recognized) { |
748 | - if (ApplicationManager.empty) { |
749 | - progress = Math.max(stages.width - stagesDragArea.width + touchX, stages.width * .3); |
750 | - } else { |
751 | - progress = stages.width - stagesDragArea.width + touchX; |
752 | - } |
753 | - } |
754 | - } |
755 | - |
756 | - onDraggingChanged: { |
757 | - if (!dragging) { |
758 | - if (!ApplicationManager.empty && progress < stages.width - units.gu(10)) { |
759 | - stages.show(); |
760 | - } |
761 | - stagesDragArea.progress = Qt.binding(function () { return stages.width; }); |
762 | - } |
763 | - } |
764 | } |
765 | |
766 | Item { |
767 | @@ -186,55 +136,7 @@ |
768 | objectName: "stages" |
769 | width: parent.width |
770 | height: parent.height |
771 | - |
772 | - visible: !fullyHidden && !ApplicationManager.empty |
773 | - |
774 | - x: { |
775 | - if (shown) { |
776 | - if (locked || greeter.fakeActiveForApp !== "") { |
777 | - return 0; |
778 | - } |
779 | - return launcher.progress; |
780 | - } else { |
781 | - return stagesDragArea.progress |
782 | - } |
783 | - } |
784 | - Behavior on x { SmoothedAnimation { velocity: 600; duration: UbuntuAnimation.FastDuration } } |
785 | - |
786 | - property bool shown: false |
787 | - onShownChanged: { |
788 | - if (shown) { |
789 | - if (ApplicationManager.count > 0) { |
790 | - ApplicationManager.focusApplication(ApplicationManager.get(0).appId); |
791 | - } |
792 | - } else { |
793 | - if (ApplicationManager.focusedApplicationId) { |
794 | - ApplicationManager.updateScreenshot(ApplicationManager.focusedApplicationId); |
795 | - ApplicationManager.unfocusCurrentApplication(); |
796 | - } |
797 | - } |
798 | - } |
799 | - |
800 | - // Avoid a silent "divide by zero -> NaN" situation during init as shell.width will be |
801 | - // zero. That breaks the property binding and the function won't be reevaluated once |
802 | - // shell.width is set, with the NaN result staying there for good. |
803 | - property real showProgress: shell.width ? MathUtils.clamp(1 - x / shell.width, 0, 1) : 0 |
804 | - |
805 | - property bool fullyShown: x == 0 |
806 | - property bool fullyHidden: x == width |
807 | - |
808 | - property bool locked: applicationsDisplayLoader.item ? applicationsDisplayLoader.item.locked : false |
809 | - |
810 | - // It might technically not be fullyShown but visually it just looks so. |
811 | - property bool roughlyFullyShown: x >= 0 && x <= units.gu(1) |
812 | - |
813 | - function show() { |
814 | - shown = true; |
815 | - } |
816 | - |
817 | - function hide() { |
818 | - shown = false; |
819 | - } |
820 | + visible: !ApplicationManager.empty |
821 | |
822 | Connections { |
823 | target: ApplicationManager |
824 | @@ -243,7 +145,6 @@ |
825 | lockscreen.show(); |
826 | } |
827 | greeter.hide(); |
828 | - stages.show(); |
829 | } |
830 | |
831 | onFocusedApplicationIdChanged: { |
832 | @@ -254,18 +155,9 @@ |
833 | } |
834 | |
835 | onApplicationAdded: { |
836 | - if (greeter.shown) { |
837 | + if (greeter.shown && appId != "unity8-dash") { |
838 | greeter.hide(); |
839 | } |
840 | - if (!stages.shown) { |
841 | - stages.show(); |
842 | - } |
843 | - } |
844 | - |
845 | - onEmptyChanged: { |
846 | - if (ApplicationManager.empty) { |
847 | - stages.hide(); |
848 | - } |
849 | } |
850 | } |
851 | |
852 | @@ -294,14 +186,18 @@ |
853 | Binding { |
854 | target: applicationsDisplayLoader.item |
855 | property: "interactive" |
856 | - value: stages.roughlyFullyShown && !greeter.shown && !lockscreen.shown |
857 | - && panel.indicators.fullyClosed |
858 | + value: !greeter.shown && !lockscreen.shown && panel.indicators.fullyClosed && launcher.progress == 0 |
859 | } |
860 | Binding { |
861 | target: applicationsDisplayLoader.item |
862 | property: "spreadEnabled" |
863 | value: greeter.fakeActiveForApp === "" // to support emergency dialer hack |
864 | } |
865 | + Binding { |
866 | + target: applicationsDisplayLoader.item |
867 | + property: "inverseProgress" |
868 | + value: launcher.progress |
869 | + } |
870 | } |
871 | } |
872 | |
873 | @@ -525,7 +421,7 @@ |
874 | |
875 | var animate = !LightDM.Greeter.active && !stages.shown |
876 | dash.setCurrentScope("clickscope", animate, false) |
877 | - stages.hide() |
878 | + ApplicationManager.requestFocusApplication("unity8-dash") |
879 | } |
880 | |
881 | function showDash() { |
882 | @@ -534,7 +430,7 @@ |
883 | } |
884 | |
885 | if (!stages.locked) { |
886 | - stages.hide(); |
887 | + ApplicationManager.requestFocusApplication("unity8-dash") |
888 | launcher.fadeOut(); |
889 | } else { |
890 | launcher.switchToNextState("visible"); |
891 | @@ -568,7 +464,7 @@ |
892 | ApplicationManager.focusedApplicationId && |
893 | ApplicationManager.findApplication(ApplicationManager.focusedApplicationId).fullscreen |
894 | |
895 | - fullscreenMode: (stages.roughlyFullyShown && topmostApplicationIsFullscreen |
896 | + fullscreenMode: (topmostApplicationIsFullscreen |
897 | && !LightDM.Greeter.active) || greeter.fakeActiveForApp !== "" |
898 | } |
899 | |
900 | @@ -586,7 +482,11 @@ |
901 | |
902 | onShowDashHome: showHome() |
903 | onDash: showDash() |
904 | - onDashSwipeChanged: if (dashSwipe && stages.shown) dash.setCurrentScope("clickscope", false, true) |
905 | + onDashSwipeChanged: { |
906 | + if (dashSwipe && ApplicationManager.focusedApplicationId !== "unity8-dash") { |
907 | + dash.setCurrentScope("clickscope", false, true) |
908 | + } |
909 | + } |
910 | onLauncherApplicationSelected: { |
911 | if (greeter.fakeActiveForApp !== "") { |
912 | lockscreen.show() |
913 | @@ -678,7 +578,6 @@ |
914 | z: alphaDisclaimerLabel.z + 10 |
915 | greeter: greeter |
916 | launcher: launcher |
917 | - dash: dash |
918 | indicators: panel.indicators |
919 | underlay: underlay |
920 | } |
921 | |
922 | === modified file 'qml/Stages/PhoneStage.qml' |
923 | --- qml/Stages/PhoneStage.qml 2014-07-28 15:50:19 +0000 |
924 | +++ qml/Stages/PhoneStage.qml 2014-07-28 15:50:22 +0000 |
925 | @@ -21,7 +21,7 @@ |
926 | import Utils 0.1 |
927 | import "../Components" |
928 | |
929 | -Item { |
930 | +Rectangle { |
931 | id: root |
932 | |
933 | // Controls to be set from outside |
934 | @@ -29,10 +29,13 @@ |
935 | property real maximizedAppTopMargin |
936 | property bool interactive |
937 | property bool spreadEnabled: true // If false, animations and right edge will be disabled |
938 | + property real inverseProgress: 0 // This is the progress for left edge drags, in pixels. |
939 | |
940 | // State information propagated to the outside |
941 | readonly property bool locked: spreadView.phase == 2 |
942 | |
943 | + color: "black" |
944 | + |
945 | function select(appId) { |
946 | spreadView.snapTo(priv.indexOf(appId)); |
947 | } |
948 | @@ -43,6 +46,16 @@ |
949 | spreadView.contentX = -spreadView.shift; |
950 | } |
951 | |
952 | + onInverseProgressChanged: { |
953 | + if (inverseProgress == 0 && priv.oldInverseProgress > 0) { |
954 | + // left edge drag released. Minimum distance is given by design. |
955 | + if (priv.oldInverseProgress > units.gu(22)) { |
956 | + ApplicationManager.focusApplication("unity8-dash"); |
957 | + } |
958 | + } |
959 | + priv.oldInverseProgress = inverseProgress; |
960 | + } |
961 | + |
962 | Connections { |
963 | target: ApplicationManager |
964 | |
965 | @@ -50,7 +63,7 @@ |
966 | if (spreadView.phase > 0) { |
967 | spreadView.snapTo(priv.indexOf(appId)); |
968 | } else { |
969 | - priv.switchToApp(appId); |
970 | + ApplicationManager.focusApplication(appId); |
971 | } |
972 | } |
973 | |
974 | @@ -60,7 +73,7 @@ |
975 | } else { |
976 | spreadView.phase = 0; |
977 | spreadView.contentX = -spreadView.shift; |
978 | - priv.switchToApp(appId); |
979 | + ApplicationManager.focusApplication(appId); |
980 | } |
981 | } |
982 | |
983 | @@ -79,15 +92,11 @@ |
984 | |
985 | property string focusedAppId: ApplicationManager.focusedApplicationId |
986 | property var focusedApplication: ApplicationManager.findApplication(focusedAppId) |
987 | - |
988 | - function switchToApp(appId) { |
989 | - if (priv.focusedAppId) { |
990 | - spreadView.focusChanging = true; |
991 | - ApplicationManager.focusApplication(appId); |
992 | - } else { |
993 | - ApplicationManager.focusApplication(appId); |
994 | - } |
995 | - } |
996 | + property var focusedAppDelegate: null |
997 | + |
998 | + property real oldInverseProgress: 0 |
999 | + |
1000 | + onFocusedAppIdChanged: focusedAppDelegate = spreadRepeater.itemAt(0); |
1001 | |
1002 | function indexOf(appId) { |
1003 | for (var i = 0; i < ApplicationManager.count; i++) { |
1004 | @@ -100,14 +109,6 @@ |
1005 | |
1006 | } |
1007 | |
1008 | - Rectangle { |
1009 | - id: coverFlipBackground |
1010 | - anchors.fill: parent |
1011 | - color: "black" |
1012 | - visible: spreadView.visible |
1013 | - } |
1014 | - |
1015 | - |
1016 | Flickable { |
1017 | id: spreadView |
1018 | objectName: "spreadView" |
1019 | @@ -116,6 +117,8 @@ |
1020 | contentWidth: spreadRow.width - shift |
1021 | contentX: -shift |
1022 | |
1023 | + readonly property bool isActive: shiftedContentX > 0 || spreadDragArea.dragging |
1024 | + |
1025 | // The flickable needs to fill the screen in order to get touch events all over. |
1026 | // However, we don't want to the user to be able to scroll back all the way. For |
1027 | // that, the beginning of the gesture starts with a negative value for contentX |
1028 | @@ -198,6 +201,12 @@ |
1029 | snapAnimation.start(); |
1030 | } |
1031 | |
1032 | + // In case the ApplicationManager already holds an app when starting up we're missing animations |
1033 | + // Make sure we end up in the same state |
1034 | + Component.onCompleted: { |
1035 | + spreadView.contentX = -spreadView.shift |
1036 | + } |
1037 | + |
1038 | SequentialAnimation { |
1039 | id: snapAnimation |
1040 | property int targetContentX: -spreadView.shift |
1041 | @@ -260,14 +269,33 @@ |
1042 | && spreadView.shiftedContentX === 0 && root.interactive && index === 0 |
1043 | swipeToCloseEnabled: spreadView.interactive |
1044 | maximizedAppTopMargin: root.maximizedAppTopMargin |
1045 | - dropShadow: spreadView.shiftedContentX > 0 || spreadDragArea.status == DirectionalDragArea.Undecided |
1046 | - |
1047 | - z: behavioredIndex |
1048 | - x: index == 0 ? 0 : spreadView.width + (index - 1) * spreadView.tileDistance |
1049 | + dropShadow: spreadView.isActive || |
1050 | + priv.focusedAppDelegate.x !== 0 |
1051 | + |
1052 | + readonly property bool isDash: model.appId == "unity8-dash" |
1053 | + |
1054 | + z: isDash && !spreadView.isActive ? -1 : behavioredIndex |
1055 | + |
1056 | + x: { |
1057 | + // focused app is always positioned at 0 except when following left edge drag |
1058 | + if (index == 0) { |
1059 | + if (!isDash && root.inverseProgress > 0) { |
1060 | + return root.inverseProgress; |
1061 | + } |
1062 | + return 0; |
1063 | + } |
1064 | + if (isDash && !spreadView.isActive && !spreadDragArea.dragging) { |
1065 | + return 0; |
1066 | + } |
1067 | + |
1068 | + // Otherwise line up for the spread |
1069 | + return spreadView.width + (index - 1) * spreadView.tileDistance; |
1070 | + } |
1071 | property real behavioredIndex: index |
1072 | Behavior on behavioredIndex { |
1073 | enabled: spreadView.closingIndex >= 0 |
1074 | UbuntuNumberAnimation { |
1075 | + id: appXAnimation |
1076 | onRunningChanged: { |
1077 | if (!running) { |
1078 | spreadView.closingIndex = -1; |
1079 | @@ -277,11 +305,13 @@ |
1080 | } |
1081 | |
1082 | Behavior on x { |
1083 | - enabled: spreadView.focusChanging && index == 0 && root.spreadEnabled |
1084 | + enabled: root.spreadEnabled && |
1085 | + !spreadView.isActive && |
1086 | + !snapAnimation.running |
1087 | UbuntuNumberAnimation { |
1088 | duration: UbuntuAnimation.FastDuration |
1089 | onRunningChanged: { |
1090 | - if (!running) { |
1091 | + if (!running && root.inverseProgress == 0) { |
1092 | spreadView.focusChanging = false; |
1093 | } |
1094 | } |
1095 | @@ -322,6 +352,10 @@ |
1096 | return progress; |
1097 | } |
1098 | |
1099 | + // Hiding tiles when their progress is negative or reached the maximum |
1100 | + visible: (progress >= 0 && progress < 1.7) || |
1101 | + (model.appId == "unity8-dash" && priv.focusedAppDelegate.x !== 0) |
1102 | + |
1103 | EasingCurve { |
1104 | id: snappingCurve |
1105 | type: EasingCurve.Linear |
1106 | |
1107 | === modified file 'qml/Stages/SpreadDelegate.qml' |
1108 | --- qml/Stages/SpreadDelegate.qml 2014-07-28 15:50:19 +0000 |
1109 | +++ qml/Stages/SpreadDelegate.qml 2014-07-28 15:50:22 +0000 |
1110 | @@ -37,6 +37,7 @@ |
1111 | |
1112 | SurfaceContainer { |
1113 | id: surfaceContainer |
1114 | + objectName: "surfaceContainer" |
1115 | anchors.fill: parent |
1116 | surface: model.surface |
1117 | property bool appHasCreatedASurface: false |
1118 | @@ -172,6 +173,11 @@ |
1119 | } |
1120 | |
1121 | onDragEnd: { |
1122 | + if (model.appId == "unity8-dash") { |
1123 | + animation.animate("center") |
1124 | + return; |
1125 | + } |
1126 | + |
1127 | // velocity and distance values specified by design prototype |
1128 | if ((dragVelocity < -units.gu(40) && distance < -units.gu(8)) || distance < -root.height / 2) { |
1129 | animation.animate("up") |
1130 | |
1131 | === modified file 'qml/Stages/TabletStage.qml' |
1132 | --- qml/Stages/TabletStage.qml 2014-07-28 15:50:19 +0000 |
1133 | +++ qml/Stages/TabletStage.qml 2014-07-28 15:50:22 +0000 |
1134 | @@ -21,10 +21,11 @@ |
1135 | import Utils 0.1 |
1136 | import "../Components" |
1137 | |
1138 | -Item { |
1139 | +Rectangle { |
1140 | id: root |
1141 | objectName: "stages" |
1142 | anchors.fill: parent |
1143 | + color: "black" |
1144 | |
1145 | // Controls to be set from outside |
1146 | property bool shown: false |
1147 | @@ -32,10 +33,21 @@ |
1148 | property int dragAreaWidth |
1149 | property real maximizedAppTopMargin |
1150 | property bool interactive |
1151 | + property real inverseProgress: 0 // This is the progress for left edge drags, in pixels. |
1152 | |
1153 | // State information propagated to the outside |
1154 | readonly property bool locked: spreadView.phase == 2 |
1155 | |
1156 | + onInverseProgressChanged: { |
1157 | + if (inverseProgress == 0 && priv.oldInverseProgress > 0) { |
1158 | + // left edge drag released. Minimum distance is given by design. |
1159 | + if (priv.oldInverseProgress > units.gu(22)) { |
1160 | + ApplicationManager.focusApplication("unity8-dash"); |
1161 | + } |
1162 | + } |
1163 | + priv.oldInverseProgress = inverseProgress; |
1164 | + } |
1165 | + |
1166 | QtObject { |
1167 | id: priv |
1168 | |
1169 | @@ -49,6 +61,8 @@ |
1170 | property string appId0 |
1171 | property string appId1 |
1172 | |
1173 | + property int oldInverseProgress: 0 |
1174 | + |
1175 | onFocusedAppIdChanged: { |
1176 | if (priv.focusedAppId.length > 0) { |
1177 | var focusedApp = ApplicationManager.findApplication(focusedAppId); |
1178 | @@ -107,16 +121,26 @@ |
1179 | } |
1180 | } |
1181 | |
1182 | + onApplicationAdded: { |
1183 | + if (spreadView.phase == 2) { |
1184 | + spreadView.snapTo(ApplicationManager.count - 1); |
1185 | + } else { |
1186 | + spreadView.phase = 0; |
1187 | + spreadView.contentX = -spreadView.shift; |
1188 | + ApplicationManager.focusApplication(appId); |
1189 | + } |
1190 | + } |
1191 | + |
1192 | onApplicationRemoved: { |
1193 | if (priv.mainStageAppId == appId) { |
1194 | - priv.mainStageAppId = ""; |
1195 | + ApplicationManager.focusApplication("unity8-dash") |
1196 | } |
1197 | if (priv.sideStageAppId == appId) { |
1198 | priv.sideStageAppId = ""; |
1199 | } |
1200 | if (ApplicationManager.count == 0) { |
1201 | spreadView.phase = 0; |
1202 | - spreadView.contentX = 0; |
1203 | + spreadView.contentX = -spreadView.shift; |
1204 | } |
1205 | } |
1206 | } |
1207 | @@ -124,13 +148,25 @@ |
1208 | Flickable { |
1209 | id: spreadView |
1210 | anchors.fill: parent |
1211 | - contentWidth: spreadRow.width |
1212 | interactive: (spreadDragArea.status == DirectionalDragArea.Recognized || phase > 1) && draggedIndex == -1 |
1213 | + contentWidth: spreadRow.width - shift |
1214 | + contentX: -shift |
1215 | |
1216 | property int tileDistance: units.gu(20) |
1217 | property int sideStageWidth: units.gu(40) |
1218 | property bool sideStageVisible: priv.sideStageAppId |
1219 | |
1220 | + readonly property bool isActive: shiftedContentX > 0 || spreadDragArea.dragging |
1221 | + onIsActiveChanged: print("spreadView isActive changed", isActive) |
1222 | + |
1223 | + // The flickable needs to fill the screen in order to get touch events all over. |
1224 | + // However, we don't want to the user to be able to scroll back all the way. For |
1225 | + // that, the beginning of the gesture starts with a negative value for contentX |
1226 | + // so the flickable wants to pull it into the view already. "shift" tunes the |
1227 | + // distance where to "lock" the content. |
1228 | + readonly property real shift: width / 2 |
1229 | + readonly property real shiftedContentX: contentX + shift |
1230 | + |
1231 | // Phase of the animation: |
1232 | // 0: Starting from right edge, a new app (index 1) comes in from the right |
1233 | // 1: The app has reached the first snap position. |
1234 | @@ -168,6 +204,12 @@ |
1235 | } |
1236 | } |
1237 | |
1238 | + // In case the ApplicationManager already holds an app when starting up we're missing animations |
1239 | + // Make sure we end up in the same state |
1240 | + Component.onCompleted: { |
1241 | + spreadView.contentX = -spreadView.shift |
1242 | + } |
1243 | + |
1244 | property int nextInStack: { |
1245 | switch (state) { |
1246 | case "main": |
1247 | @@ -224,31 +266,31 @@ |
1248 | return "empty"; |
1249 | } |
1250 | |
1251 | - onContentXChanged: { |
1252 | - if (spreadView.phase == 0 && spreadView.contentX > spreadView.width * spreadView.positionMarker2) { |
1253 | + onShiftedContentXChanged: { |
1254 | + if (spreadView.phase == 0 && spreadView.shiftedContentX > spreadView.width * spreadView.positionMarker2) { |
1255 | spreadView.phase = 1; |
1256 | - } else if (spreadView.phase == 1 && spreadView.contentX > spreadView.width * spreadView.positionMarker4) { |
1257 | + } else if (spreadView.phase == 1 && spreadView.shiftedContentX > spreadView.width * spreadView.positionMarker4) { |
1258 | spreadView.phase = 2; |
1259 | - } else if (spreadView.phase == 1 && spreadView.contentX < spreadView.width * spreadView.positionMarker2) { |
1260 | + } else if (spreadView.phase == 1 && spreadView.shiftedContentX < spreadView.width * spreadView.positionMarker2) { |
1261 | spreadView.phase = 0; |
1262 | } |
1263 | } |
1264 | |
1265 | function snap() { |
1266 | - if (contentX < phase0Width) { |
1267 | - snapAnimation.targetContentX = 0; |
1268 | + if (shiftedContentX < phase0Width) { |
1269 | + snapAnimation.targetContentX = -shift; |
1270 | snapAnimation.start(); |
1271 | - } else if (contentX < phase1Width) { |
1272 | + } else if (shiftedContentX < phase1Width) { |
1273 | snapTo(1); |
1274 | } else { |
1275 | // Add 1 pixel to make sure we definitely hit positionMarker4 even with rounding errors of the animation. |
1276 | - snapAnimation.targetContentX = spreadView.width * spreadView.positionMarker4 + 1; |
1277 | + snapAnimation.targetContentX = spreadView.width * spreadView.positionMarker4 + 1 - shift; |
1278 | snapAnimation.start(); |
1279 | } |
1280 | } |
1281 | function snapTo(index) { |
1282 | spreadView.selectedIndex = index; |
1283 | - snapAnimation.targetContentX = 0; |
1284 | + snapAnimation.targetContentX = -shift; |
1285 | snapAnimation.start(); |
1286 | } |
1287 | |
1288 | @@ -309,7 +351,7 @@ |
1289 | |
1290 | SequentialAnimation { |
1291 | id: snapAnimation |
1292 | - property int targetContentX: 0 |
1293 | + property int targetContentX: -spreadView.shift |
1294 | |
1295 | UbuntuNumberAnimation { |
1296 | target: spreadView |
1297 | @@ -325,15 +367,14 @@ |
1298 | spreadView.selectedIndex = -1; |
1299 | ApplicationManager.focusApplication(ApplicationManager.get(newIndex).appId); |
1300 | spreadView.phase = 0; |
1301 | - spreadView.contentX = 0; |
1302 | + spreadView.contentX = -spreadView.shift; |
1303 | } |
1304 | } |
1305 | } |
1306 | } |
1307 | |
1308 | - Rectangle { |
1309 | + Item { |
1310 | id: spreadRow |
1311 | - color: "black" |
1312 | x: spreadView.contentX |
1313 | height: root.height |
1314 | width: spreadView.width + Math.max(spreadView.width, ApplicationManager.count * spreadView.tileDistance) |
1315 | @@ -380,7 +421,7 @@ |
1316 | MouseArea { |
1317 | id: sideStageDragHandleMouseArea |
1318 | anchors.fill: parent |
1319 | - enabled: spreadView.contentX == 0 |
1320 | + enabled: spreadView.shiftedContentX == 0 |
1321 | property int startX |
1322 | property var gesturePoints: new Array() |
1323 | |
1324 | @@ -413,7 +454,7 @@ |
1325 | |
1326 | onRunningChanged: { |
1327 | if (!running) { |
1328 | - sideStageDragHandle.dragging = false;; |
1329 | + sideStageDragHandle.dragging = false; |
1330 | } |
1331 | } |
1332 | } |
1333 | @@ -427,17 +468,26 @@ |
1334 | id: spreadTile |
1335 | height: spreadView.height |
1336 | width: model.stage == ApplicationInfoInterface.MainStage ? spreadView.width : spreadView.sideStageWidth |
1337 | - x: spreadView.width |
1338 | - z: spreadView.indexToZIndex(index) |
1339 | active: model.appId == priv.mainStageAppId || model.appId == priv.sideStageAppId |
1340 | - zIndex: z |
1341 | + zIndex: spreadView.indexToZIndex(index) |
1342 | selected: spreadView.selectedIndex == index |
1343 | otherSelected: spreadView.selectedIndex >= 0 && !selected |
1344 | isInSideStage: priv.sideStageAppId == model.appId |
1345 | interactive: !spreadView.interactive && spreadView.phase === 0 && root.interactive |
1346 | swipeToCloseEnabled: spreadView.interactive |
1347 | maximizedAppTopMargin: root.maximizedAppTopMargin |
1348 | - dropShadow: spreadView.contentX > 0 || spreadDragArea.status == DirectionalDragArea.Undecided |
1349 | + dragOffset: !isDash && model.appId == priv.mainStageAppId && root.inverseProgress > 0 ? root.inverseProgress : 0 |
1350 | + |
1351 | + readonly property bool isDash: model.appId == "unity8-dash" |
1352 | + |
1353 | + // FIXME: A regular binding doesn't update any more after closing an app. |
1354 | + // Using a Binding for now. |
1355 | + Binding { |
1356 | + target: spreadTile |
1357 | + property: "z" |
1358 | + value: (!spreadView.isActive && isDash && !active) ? -1 : spreadTile.zIndex |
1359 | + } |
1360 | + x: spreadView.width |
1361 | |
1362 | property real behavioredZIndex: zIndex |
1363 | Behavior on behavioredZIndex { |
1364 | @@ -458,7 +508,7 @@ |
1365 | } |
1366 | |
1367 | progress: { |
1368 | - var tileProgress = (spreadView.contentX - behavioredZIndex * spreadView.tileDistance) / spreadView.width; |
1369 | + var tileProgress = (spreadView.shiftedContentX - behavioredZIndex * spreadView.tileDistance) / spreadView.width; |
1370 | // Some tiles (nextInStack, active) need to move directly from the beginning, normalize progress to immediately start at 0 |
1371 | if ((index == spreadView.nextInStack && spreadView.phase < 2) || (active && spreadView.phase < 1)) { |
1372 | tileProgress += behavioredZIndex * spreadView.tileDistance / spreadView.width; |
1373 | @@ -481,11 +531,7 @@ |
1374 | |
1375 | onClicked: { |
1376 | if (spreadView.phase == 2) { |
1377 | - if (ApplicationManager.focusedApplicationId == ApplicationManager.get(index).appId) { |
1378 | - spreadView.snapTo(index); |
1379 | - } else { |
1380 | - ApplicationManager.requestFocusApplication(ApplicationManager.get(index).appId); |
1381 | - } |
1382 | + spreadView.snapTo(index); |
1383 | } |
1384 | } |
1385 | |
1386 | @@ -518,12 +564,12 @@ |
1387 | onTouchXChanged: { |
1388 | if (!dragging) { |
1389 | spreadView.phase = 0; |
1390 | - spreadView.contentX = 0; |
1391 | + spreadView.contentX = -spreadView.shift; |
1392 | } |
1393 | |
1394 | - if (attachedToView) { |
1395 | - spreadView.contentX = -touchX + spreadDragArea.width; |
1396 | - if (spreadView.contentX > spreadView.phase0Width + spreadView.phase1Width / 2) { |
1397 | + if (dragging && attachedToView) { |
1398 | + spreadView.contentX = -touchX + spreadDragArea.width - spreadView.shift; |
1399 | + if (spreadView.shiftedContentX > spreadView.phase0Width + spreadView.phase1Width / 2) { |
1400 | attachedToView = false; |
1401 | spreadView.snap(); |
1402 | } |
1403 | @@ -548,14 +594,14 @@ |
1404 | var oneWayFlick = priv.evaluateOneWayFlick(gesturePoints); |
1405 | gesturePoints = []; |
1406 | |
1407 | - if (oneWayFlick && spreadView.contentX < spreadView.positionMarker1 * spreadView.width) { |
1408 | + if (oneWayFlick && spreadView.shiftedContentX < spreadView.positionMarker1 * spreadView.width) { |
1409 | // If it was a short one-way movement, do the Alt+Tab switch |
1410 | // no matter if we didn't cross positionMarker1 yet. |
1411 | spreadView.snapTo(spreadView.nextInStack); |
1412 | } else if (!dragging && attachedToView) { |
1413 | - if (spreadView.contentX < spreadView.width * spreadView.positionMarker1) { |
1414 | + if (spreadView.shiftedContentX < spreadView.width * spreadView.positionMarker1) { |
1415 | spreadView.snap(); |
1416 | - } else if (spreadView.contentX < spreadView.width * spreadView.positionMarker2) { |
1417 | + } else if (spreadView.shiftedContentX < spreadView.width * spreadView.positionMarker2) { |
1418 | spreadView.snapTo(spreadView.nextInStack); |
1419 | } else { |
1420 | // otherwise snap to the closest snap position we can find |
1421 | |
1422 | === modified file 'qml/Stages/TransformedSpreadDelegate.qml' |
1423 | --- qml/Stages/TransformedSpreadDelegate.qml 2014-07-28 15:50:19 +0000 |
1424 | +++ qml/Stages/TransformedSpreadDelegate.qml 2014-07-28 15:50:22 +0000 |
1425 | @@ -46,9 +46,6 @@ |
1426 | property real startDistance: units.gu(5) |
1427 | property real endDistance: units.gu(.5) |
1428 | |
1429 | - // Hiding tiles when their progress is negative or reached the maximum |
1430 | - visible: progress >= 0 && progress < 1.7 |
1431 | - |
1432 | onSelectedChanged: { |
1433 | if (selected) { |
1434 | priv.snapshot(); |
1435 | @@ -132,6 +129,10 @@ |
1436 | // the selected tile, which is animated from the snapshotted position to be fullscreen. |
1437 | |
1438 | readonly property real xTranslate: { |
1439 | + if (!spreadView.isActive) { |
1440 | + return 0; |
1441 | + } |
1442 | + |
1443 | if (otherSelected) { |
1444 | if (spreadView.phase < 2 && index == 0) { |
1445 | return linearAnimation(selectedProgress, 0, selectedXTranslate, |
1446 | @@ -183,7 +184,7 @@ |
1447 | } |
1448 | |
1449 | readonly property real angle: { |
1450 | - if (spreadView.focusChanging) { |
1451 | + if (!spreadView.isActive) { |
1452 | return 0; |
1453 | } |
1454 | |
1455 | @@ -216,7 +217,7 @@ |
1456 | } |
1457 | |
1458 | readonly property real scale: { |
1459 | - if (spreadView.focusChanging) { |
1460 | + if (!spreadView.isActive) { |
1461 | return 1; |
1462 | } |
1463 | if (priv.otherSelected) { |
1464 | |
1465 | === modified file 'qml/Stages/TransformedTabletSpreadDelegate.qml' |
1466 | --- qml/Stages/TransformedTabletSpreadDelegate.qml 2014-07-28 15:50:19 +0000 |
1467 | +++ qml/Stages/TransformedTabletSpreadDelegate.qml 2014-07-28 15:50:22 +0000 |
1468 | @@ -47,6 +47,11 @@ |
1469 | |
1470 | property bool isInSideStage: false |
1471 | |
1472 | + property int dragOffset: 0 |
1473 | + |
1474 | + dropShadow: spreadView.isActive || |
1475 | + (active && model.stage == ApplicationInfoInterface.MainStage && priv.xTranslate != 0) |
1476 | + |
1477 | onSelectedChanged: { |
1478 | if (selected) { |
1479 | priv.snapshot(); |
1480 | @@ -129,6 +134,16 @@ |
1481 | return helperEasingCurve.value * (endValue - startValue) + startValue; |
1482 | } |
1483 | |
1484 | + Behavior on xTranslate { |
1485 | + enabled: !spreadView.isActive && |
1486 | + !snapAnimation.running && |
1487 | + model.appId !== "unity8-dash" && |
1488 | + !spreadView.sideStageDragging |
1489 | + UbuntuNumberAnimation { |
1490 | + duration: UbuntuAnimation.FastDuration |
1491 | + } |
1492 | + } |
1493 | + |
1494 | property real xTranslate: { |
1495 | var newTranslate = 0; |
1496 | |
1497 | @@ -155,7 +170,12 @@ |
1498 | if (spreadView.phase == 0 && shouldMoveAway) { |
1499 | newTranslate += linearAnimation(0, spreadView.positionMarker2, 0, -units.gu(4), root.animatedProgress); |
1500 | } |
1501 | - } |
1502 | + newTranslate += root.dragOffset; |
1503 | + } |
1504 | + if (!spreadView.isActive && model.appId == "unity8-dash" && !root.active) { |
1505 | + newTranslate -= root.width; |
1506 | + } |
1507 | + |
1508 | if (nextInStack && spreadView.phase == 0) { |
1509 | if (model.stage == ApplicationInfoInterface.MainStage) { |
1510 | if (spreadView.sideStageVisible && root.progress > 0) { |
1511 | @@ -205,6 +225,10 @@ |
1512 | } |
1513 | |
1514 | property real scale: { |
1515 | + if (!spreadView.isActive) { |
1516 | + return 1; |
1517 | + } |
1518 | + |
1519 | if (otherSelected) { |
1520 | return selectedScale; |
1521 | } |
1522 | @@ -249,6 +273,10 @@ |
1523 | } |
1524 | |
1525 | property real angle: { |
1526 | + if (!spreadView.isActive) { |
1527 | + return 0; |
1528 | + } |
1529 | + |
1530 | if (otherSelected) { |
1531 | return selectedAngle; |
1532 | } |
1533 | |
1534 | === modified file 'src/CMakeLists.txt' |
1535 | --- src/CMakeLists.txt 2014-07-28 15:50:19 +0000 |
1536 | +++ src/CMakeLists.txt 2014-07-28 15:50:22 +0000 |
1537 | @@ -35,3 +35,4 @@ |
1538 | ) |
1539 | |
1540 | add_subdirectory(Panel) |
1541 | +add_subdirectory(Dash) |
1542 | |
1543 | === added directory 'src/Dash' |
1544 | === added file 'src/Dash/CMakeLists.txt' |
1545 | --- src/Dash/CMakeLists.txt 1970-01-01 00:00:00 +0000 |
1546 | +++ src/Dash/CMakeLists.txt 2014-07-28 15:50:22 +0000 |
1547 | @@ -0,0 +1,12 @@ |
1548 | +set(DASH_SRCS |
1549 | + main.cpp |
1550 | +) |
1551 | + |
1552 | +add_executable(unity8-dash ${DASH_SRCS}) |
1553 | + |
1554 | +qt5_use_modules(unity8-dash Gui Qml Quick Test) |
1555 | + |
1556 | +# install binaries |
1557 | +install(TARGETS ${DASH_APP} |
1558 | + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} |
1559 | +) |
1560 | |
1561 | === added file 'src/Dash/main.cpp' |
1562 | --- src/Dash/main.cpp 1970-01-01 00:00:00 +0000 |
1563 | +++ src/Dash/main.cpp 2014-07-28 15:50:22 +0000 |
1564 | @@ -0,0 +1,49 @@ |
1565 | +/* |
1566 | + * Copyright (C) 2014 Canonical, Ltd. |
1567 | + * |
1568 | + * Authors: |
1569 | + * Michael Zanetti <michael.zanetti@canonical.com> |
1570 | + * |
1571 | + * This program is free software; you can redistribute it and/or modify |
1572 | + * it under the terms of the GNU General Public License as published by |
1573 | + * the Free Software Foundation; version 3. |
1574 | + * |
1575 | + * This program is distributed in the hope that it will be useful, |
1576 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1577 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1578 | + * GNU General Public License for more details. |
1579 | + * |
1580 | + * You should have received a copy of the GNU General Public License |
1581 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1582 | + */ |
1583 | + |
1584 | +#include <QtQuick/QQuickView> |
1585 | +#include <QtGui/QGuiApplication> |
1586 | +#include <QtQml/QQmlEngine> |
1587 | +#include <QtQml/QQmlContext> |
1588 | +#include <QDebug> |
1589 | + |
1590 | +#include <paths.h> |
1591 | + |
1592 | +int main(int argc, const char *argv[]) |
1593 | +{ |
1594 | + QGuiApplication *application = new QGuiApplication(argc, (char**)argv); |
1595 | + |
1596 | + QQuickView* view = new QQuickView(); |
1597 | + view->setResizeMode(QQuickView::SizeRootObjectToView); |
1598 | + view->setTitle("Unity Dash"); |
1599 | + |
1600 | + QUrl source(::qmlDirectory()+"Dash/DashApplication.qml"); |
1601 | + prependImportPaths(view->engine(), ::overrideImportPaths()); |
1602 | + appendImportPaths(view->engine(), ::fallbackImportPaths()); |
1603 | + |
1604 | + view->setSource(source); |
1605 | + view->show(); |
1606 | + |
1607 | + int result = application->exec(); |
1608 | + |
1609 | + delete view; |
1610 | + delete application; |
1611 | + |
1612 | + return result; |
1613 | +} |
1614 | |
1615 | === modified file 'tests/mocks/Unity/Application/ApplicationInfo.cpp' |
1616 | --- tests/mocks/Unity/Application/ApplicationInfo.cpp 2014-07-28 15:50:19 +0000 |
1617 | +++ tests/mocks/Unity/Application/ApplicationInfo.cpp 2014-07-28 15:50:22 +0000 |
1618 | @@ -31,8 +31,6 @@ |
1619 | , m_state(Starting) |
1620 | , m_focused(false) |
1621 | , m_fullscreen(false) |
1622 | - , m_windowItem(0) |
1623 | - , m_windowComponent(0) |
1624 | , m_parentItem(0) |
1625 | , m_surface(0) |
1626 | { |
1627 | @@ -45,8 +43,6 @@ |
1628 | , m_state(Starting) |
1629 | , m_focused(false) |
1630 | , m_fullscreen(false) |
1631 | - , m_windowItem(0) |
1632 | - , m_windowComponent(0) |
1633 | , m_parentItem(0) |
1634 | , m_surface(0) |
1635 | { |
1636 | @@ -61,12 +57,6 @@ |
1637 | } |
1638 | } |
1639 | |
1640 | -void ApplicationInfo::onWindowComponentStatusChanged(QQmlComponent::Status status) |
1641 | -{ |
1642 | - if (status == QQmlComponent::Ready && !m_windowItem) |
1643 | - doCreateWindowItem(); |
1644 | -} |
1645 | - |
1646 | void ApplicationInfo::onStateChanged(State state) |
1647 | { |
1648 | if (state == ApplicationInfo::Running) { |
1649 | @@ -108,55 +98,3 @@ |
1650 | Q_EMIT surfaceChanged(m_surface); |
1651 | SurfaceManager::singleton()->registerSurface(m_surface); |
1652 | } |
1653 | - |
1654 | -void ApplicationInfo::createWindowComponent() |
1655 | -{ |
1656 | - // The assumptions I make here really should hold. |
1657 | - QQuickView *quickView = |
1658 | - qobject_cast<QQuickView*>(QGuiApplication::topLevelWindows()[0]); |
1659 | - |
1660 | - QQmlEngine *engine = quickView->engine(); |
1661 | - |
1662 | - m_windowComponent = new QQmlComponent(engine, this); |
1663 | - m_windowComponent->setData(m_windowQml.toLatin1(), QUrl()); |
1664 | -} |
1665 | - |
1666 | -void ApplicationInfo::doCreateWindowItem() |
1667 | -{ |
1668 | - m_windowItem = qobject_cast<QQuickItem *>(m_windowComponent->create()); |
1669 | - m_windowItem->setParentItem(m_parentItem); |
1670 | -} |
1671 | - |
1672 | -void ApplicationInfo::createWindowItem() |
1673 | -{ |
1674 | - if (!m_windowComponent) |
1675 | - createWindowComponent(); |
1676 | - |
1677 | - // only create the windowItem once the component is ready |
1678 | - if (!m_windowComponent->isReady()) { |
1679 | - connect(m_windowComponent, &QQmlComponent::statusChanged, |
1680 | - this, &ApplicationInfo::onWindowComponentStatusChanged); |
1681 | - } else { |
1682 | - doCreateWindowItem(); |
1683 | - } |
1684 | -} |
1685 | - |
1686 | -void ApplicationInfo::showWindow(QQuickItem *parent) |
1687 | -{ |
1688 | - m_parentItem = parent; |
1689 | - |
1690 | - if (!m_windowItem) |
1691 | - createWindowItem(); |
1692 | - |
1693 | - if (m_windowItem) { |
1694 | - m_windowItem->setVisible(true); |
1695 | - } |
1696 | -} |
1697 | - |
1698 | -void ApplicationInfo::hideWindow() |
1699 | -{ |
1700 | - if (!m_windowItem) |
1701 | - return; |
1702 | - |
1703 | - m_windowItem->setVisible(false); |
1704 | -} |
1705 | |
1706 | === modified file 'tests/mocks/Unity/Application/ApplicationInfo.h' |
1707 | --- tests/mocks/Unity/Application/ApplicationInfo.h 2014-07-28 15:50:19 +0000 |
1708 | +++ tests/mocks/Unity/Application/ApplicationInfo.h 2014-07-28 15:50:22 +0000 |
1709 | @@ -88,22 +88,12 @@ |
1710 | Q_SIGNALS: |
1711 | void surfaceChanged(MirSurfaceItem*); |
1712 | |
1713 | -public: |
1714 | - void showWindow(QQuickItem *parent); |
1715 | - void hideWindow(); |
1716 | - |
1717 | private Q_SLOTS: |
1718 | - void onWindowComponentStatusChanged(QQmlComponent::Status status); |
1719 | void onStateChanged(State state); |
1720 | |
1721 | void createSurface(); |
1722 | |
1723 | private: |
1724 | - void createWindowItem(); |
1725 | - void doCreateWindowItem(); |
1726 | - void createWindowComponent(); |
1727 | - QQuickItem *m_windowItem; |
1728 | - QQmlComponent *m_windowComponent; |
1729 | QQuickItem *m_parentItem; |
1730 | MirSurfaceItem* m_surface; |
1731 | }; |
1732 | |
1733 | === modified file 'tests/mocks/Unity/Application/ApplicationManager.cpp' |
1734 | --- tests/mocks/Unity/Application/ApplicationManager.cpp 2014-07-28 15:50:19 +0000 |
1735 | +++ tests/mocks/Unity/Application/ApplicationManager.cpp 2014-07-28 15:50:22 +0000 |
1736 | @@ -48,16 +48,14 @@ |
1737 | ApplicationManager::ApplicationManager(QObject *parent) |
1738 | : ApplicationManagerInterface(parent) |
1739 | , m_suspended(false) |
1740 | - , m_mainStageComponent(0) |
1741 | - , m_mainStage(0) |
1742 | - , m_sideStageComponent(0) |
1743 | - , m_sideStage(0) |
1744 | - , m_rightMargin(0) |
1745 | { |
1746 | m_roleNames.insert(RoleSurface, "surface"); |
1747 | m_roleNames.insert(RoleFullscreen, "fullscreen"); |
1748 | |
1749 | buildListOfAvailableApplications(); |
1750 | + |
1751 | + startApplication("unity8-dash"); |
1752 | + focusApplication("unity8-dash"); |
1753 | } |
1754 | |
1755 | ApplicationManager::~ApplicationManager() |
1756 | @@ -136,7 +134,6 @@ |
1757 | Q_EMIT applicationAdded(application->appId()); |
1758 | Q_EMIT countChanged(); |
1759 | if (count() == 1) Q_EMIT emptyChanged(isEmpty()); // was empty but not anymore |
1760 | - Q_EMIT focusRequested(application->appId()); |
1761 | |
1762 | connect(application, &ApplicationInfo::surfaceChanged, this, [application, this]() { |
1763 | QModelIndex appIndex = findIndex(application); |
1764 | @@ -222,6 +219,10 @@ |
1765 | |
1766 | bool ApplicationManager::stopApplication(const QString &appId) |
1767 | { |
1768 | + if (appId == "unity8-dash") { |
1769 | + return false; |
1770 | + } |
1771 | + |
1772 | ApplicationInfo *application = findApplication(appId); |
1773 | if (application == nullptr) |
1774 | return false; |
1775 | @@ -294,39 +295,25 @@ |
1776 | for (ApplicationInfo *app : m_runningApplications) { |
1777 | if (app->focused() && app->stage() == ApplicationInfo::MainStage) { |
1778 | app->setFocused(false); |
1779 | - app->hideWindow(); |
1780 | app->setState(ApplicationInfo::Suspended); |
1781 | } |
1782 | } |
1783 | |
1784 | // focus this app |
1785 | application->setFocused(true); |
1786 | - if (!m_mainStage) |
1787 | - createMainStage(); |
1788 | application->setState(ApplicationInfo::Running); |
1789 | - application->showWindow(m_mainStage); |
1790 | - m_mainStage->setZ(-1000); |
1791 | - if (m_sideStage) |
1792 | - m_sideStage->setZ(-2000); |
1793 | } else if (application->stage() == ApplicationInfo::SideStage) { |
1794 | // unfocus currently focused sidestage app |
1795 | for (ApplicationInfo *app : m_runningApplications) { |
1796 | if (app->focused() && app->stage() == ApplicationInfo::SideStage) { |
1797 | app->setFocused(false); |
1798 | - app->hideWindow(); |
1799 | app->setState(ApplicationInfo::Suspended); |
1800 | } |
1801 | } |
1802 | |
1803 | // focus this app |
1804 | application->setFocused(true); |
1805 | - if (!m_sideStage) |
1806 | - createSideStage(); |
1807 | application->setState(ApplicationInfo::Running); |
1808 | - application->showWindow(m_sideStage); |
1809 | - m_sideStage->setZ(-1000); |
1810 | - if (m_mainStage) |
1811 | - m_mainStage->setZ(-2000); |
1812 | } |
1813 | |
1814 | // move app to top of stack |
1815 | @@ -348,7 +335,6 @@ |
1816 | { |
1817 | for (ApplicationInfo *app : m_runningApplications) { |
1818 | if (app->focused()) { |
1819 | - app->hideWindow(); |
1820 | app->setFocused(false); |
1821 | } |
1822 | } |
1823 | @@ -357,42 +343,6 @@ |
1824 | |
1825 | void ApplicationManager::generateQmlStrings(ApplicationInfo *application) |
1826 | { |
1827 | - // TODO: Is there a better way of solving this fullscreen vs. regular |
1828 | - // application height? |
1829 | - QString topMargin; |
1830 | - if (application->fullscreen()) { |
1831 | - topMargin.append("0"); |
1832 | - } else { |
1833 | - // Taken from Panel.panelHeight |
1834 | - topMargin.append("units.gu(3) + units.dp(2)"); |
1835 | - } |
1836 | - |
1837 | - QString windowQml = QString( |
1838 | - "import QtQuick 2.0\n" |
1839 | - "Image {\n" |
1840 | - " anchors.fill: parent\n" |
1841 | - " anchors.topMargin: %1\n" |
1842 | - " anchors.rightMargin: %2\n" |
1843 | - " source: \"file://%3/Dash/graphics/phone/screenshots/%4.png\"\n" |
1844 | - " smooth: true\n" |
1845 | - " fillMode: Image.PreserveAspectCrop\n" |
1846 | - "}").arg(topMargin) |
1847 | - .arg(m_rightMargin) |
1848 | - .arg(qmlDirectory()) |
1849 | - .arg(application->icon().toString()); |
1850 | - application->setWindowQml(windowQml); |
1851 | - |
1852 | - QString imageQml = QString( |
1853 | - "import QtQuick 2.0\n" |
1854 | - "Image {\n" |
1855 | - " anchors.fill: parent\n" |
1856 | - " source: \"file://%1/Dash/graphics/phone/screenshots/%2.png\"\n" |
1857 | - " smooth: true\n" |
1858 | - " fillMode: Image.PreserveAspectCrop\n" |
1859 | - "}").arg(qmlDirectory()) |
1860 | - .arg(application->icon().toString()); |
1861 | - application->setImageQml(imageQml); |
1862 | - |
1863 | application->setScreenshot(QString("file://%1/Dash/graphics/phone/screenshots/%2@12.png").arg(qmlDirectory()) |
1864 | .arg(application->icon().toString())); |
1865 | } |
1866 | @@ -402,6 +352,14 @@ |
1867 | ApplicationInfo *application; |
1868 | |
1869 | application = new ApplicationInfo(this); |
1870 | + application->setAppId("unity8-dash"); |
1871 | + application->setName("Unity 8 Mock Dash"); |
1872 | + application->setIcon(QUrl("unity8-dash")); |
1873 | + application->setStage(ApplicationInfo::MainStage); |
1874 | + generateQmlStrings(application); |
1875 | + m_availableApplications.append(application); |
1876 | + |
1877 | + application = new ApplicationInfo(this); |
1878 | application->setAppId("dialer-app"); |
1879 | application->setName("Dialer"); |
1880 | application->setIcon(QUrl("dialer")); |
1881 | @@ -521,78 +479,6 @@ |
1882 | m_availableApplications.append(application); |
1883 | } |
1884 | |
1885 | -void ApplicationManager::createMainStageComponent() |
1886 | -{ |
1887 | - // The assumptions I make here really should hold. |
1888 | - QQuickView *quickView = |
1889 | - qobject_cast<QQuickView*>(QGuiApplication::topLevelWindows()[0]); |
1890 | - |
1891 | - QQmlEngine *engine = quickView->engine(); |
1892 | - |
1893 | - m_mainStageComponent = new QQmlComponent(engine, this); |
1894 | - QString mainStageQml = |
1895 | - "import QtQuick 2.0\n" |
1896 | - "Rectangle {\n" |
1897 | - " anchors.fill: parent\n" |
1898 | - " color: 'black'\n" |
1899 | - " z: -2000\n" |
1900 | - "}\n"; |
1901 | - m_mainStageComponent->setData(mainStageQml.toLatin1(), QUrl()); |
1902 | -} |
1903 | - |
1904 | -void ApplicationManager::createMainStage() |
1905 | -{ |
1906 | - if (!m_mainStageComponent) |
1907 | - createMainStageComponent(); |
1908 | - |
1909 | - // The assumptions I make here really should hold. |
1910 | - QQuickView *quickView = |
1911 | - qobject_cast<QQuickView*>(QGuiApplication::topLevelWindows()[0]); |
1912 | - |
1913 | - QQuickItem *shell = quickView->rootObject(); |
1914 | - |
1915 | - m_mainStage = qobject_cast<QQuickItem *>(m_mainStageComponent->create()); |
1916 | - m_mainStage->setParentItem(shell); |
1917 | -} |
1918 | - |
1919 | -void ApplicationManager::createSideStageComponent() |
1920 | -{ |
1921 | - // The assumptions I make here really should hold. |
1922 | - QQuickView *quickView = |
1923 | - qobject_cast<QQuickView*>(QGuiApplication::topLevelWindows()[0]); |
1924 | - |
1925 | - QQmlEngine *engine = quickView->engine(); |
1926 | - |
1927 | - m_sideStageComponent = new QQmlComponent(engine, this); |
1928 | - QString sideStageQml = |
1929 | - "import QtQuick 2.0\n" |
1930 | - "import Ubuntu.Components 0.1\n" |
1931 | - "Item {\n" |
1932 | - " width: units.gu(40)\n" // from SideStage in Shell.qml |
1933 | - " anchors.top: parent.top\n" |
1934 | - " anchors.bottom: parent.bottom\n" |
1935 | - " anchors.right: parent.right\n" |
1936 | - " z: -1000\n" |
1937 | - "}\n"; |
1938 | - m_sideStageComponent->setData(sideStageQml.toLatin1(), QUrl()); |
1939 | -} |
1940 | - |
1941 | -void ApplicationManager::createSideStage() |
1942 | -{ |
1943 | - if (!m_sideStageComponent) |
1944 | - createSideStageComponent(); |
1945 | - |
1946 | - // The assumptions I make here really should hold. |
1947 | - QQuickView *quickView = |
1948 | - qobject_cast<QQuickView*>(QGuiApplication::topLevelWindows()[0]); |
1949 | - |
1950 | - QQuickItem *shell = quickView->rootObject(); |
1951 | - |
1952 | - m_sideStage = qobject_cast<QQuickItem *>(m_sideStageComponent->create()); |
1953 | - m_sideStage->setParentItem(shell); |
1954 | - m_sideStage->setFlag(QQuickItem::ItemHasContents, false); |
1955 | -} |
1956 | - |
1957 | QStringList ApplicationManager::availableApplications() |
1958 | { |
1959 | QStringList appIds; |
1960 | @@ -602,19 +488,6 @@ |
1961 | return appIds; |
1962 | } |
1963 | |
1964 | -int ApplicationManager::rightMargin() const |
1965 | -{ |
1966 | - return m_rightMargin; |
1967 | -} |
1968 | - |
1969 | -void ApplicationManager::setRightMargin(int rightMargin) |
1970 | -{ |
1971 | - m_rightMargin = rightMargin; |
1972 | - Q_FOREACH(ApplicationInfo *app, m_availableApplications) { |
1973 | - generateQmlStrings(app); |
1974 | - } |
1975 | -} |
1976 | - |
1977 | bool ApplicationManager::isEmpty() const |
1978 | { |
1979 | return m_runningApplications.isEmpty(); |
1980 | |
1981 | === modified file 'tests/mocks/Unity/Application/ApplicationManager.h' |
1982 | --- tests/mocks/Unity/Application/ApplicationManager.h 2014-07-28 15:50:19 +0000 |
1983 | +++ tests/mocks/Unity/Application/ApplicationManager.h 2014-07-28 15:50:22 +0000 |
1984 | @@ -44,10 +44,6 @@ |
1985 | |
1986 | Q_PROPERTY(bool fake READ fake CONSTANT) |
1987 | |
1988 | - // Only for testing |
1989 | - // This can be used to place some controls to right, like make tryPhoneStage for example |
1990 | - Q_PROPERTY(int rightMargin READ rightMargin WRITE setRightMargin) |
1991 | - |
1992 | public: |
1993 | ApplicationManager(QObject *parent = NULL); |
1994 | virtual ~ApplicationManager(); |
1995 | @@ -108,8 +104,6 @@ |
1996 | |
1997 | // Only for testing |
1998 | Q_INVOKABLE QStringList availableApplications(); |
1999 | - int rightMargin() const; |
2000 | - void setRightMargin(int rightMargin); |
2001 | |
2002 | QModelIndex findIndex(ApplicationInfo* application); |
2003 | |
2004 | @@ -126,19 +120,9 @@ |
2005 | void showApplicationWindow(ApplicationInfo *application); |
2006 | void buildListOfAvailableApplications(); |
2007 | void generateQmlStrings(ApplicationInfo *application); |
2008 | - void createMainStageComponent(); |
2009 | - void createMainStage(); |
2010 | - void createSideStageComponent(); |
2011 | - void createSideStage(); |
2012 | bool m_suspended; |
2013 | QList<ApplicationInfo*> m_runningApplications; |
2014 | QList<ApplicationInfo*> m_availableApplications; |
2015 | - QQmlComponent *m_mainStageComponent; |
2016 | - QQuickItem *m_mainStage; |
2017 | - QQmlComponent *m_sideStageComponent; |
2018 | - QQuickItem *m_sideStage; |
2019 | - |
2020 | - int m_rightMargin; |
2021 | |
2022 | static ApplicationManager *the_application_manager; |
2023 | }; |
2024 | |
2025 | === modified file 'tests/mocks/Unity/Application/ApplicationScreenshotProvider.cpp' |
2026 | --- tests/mocks/Unity/Application/ApplicationScreenshotProvider.cpp 2014-04-02 15:33:33 +0000 |
2027 | +++ tests/mocks/Unity/Application/ApplicationScreenshotProvider.cpp 2014-07-28 15:50:22 +0000 |
2028 | @@ -64,7 +64,7 @@ |
2029 | Q_FOREACH (QWindow *win, unity->allWindows()) { |
2030 | QQuickWindow *quickWin = qobject_cast<QQuickWindow*>(win); |
2031 | if (quickWin) { |
2032 | - image = image.scaledToWidth(quickWin->width() - m_appManager->rightMargin()); |
2033 | + image = image.scaledToWidth(quickWin->width()); |
2034 | break; |
2035 | } |
2036 | } |
2037 | |
2038 | === modified file 'tests/mocks/Unity/CMakeLists.txt' |
2039 | --- tests/mocks/Unity/CMakeLists.txt 2014-07-08 09:23:14 +0000 |
2040 | +++ tests/mocks/Unity/CMakeLists.txt 2014-07-28 15:50:22 +0000 |
2041 | @@ -2,6 +2,7 @@ |
2042 | add_subdirectory(Indicators) |
2043 | add_subdirectory(Launcher) |
2044 | add_subdirectory(Notifications) |
2045 | +add_subdirectory(DashCommunicator) |
2046 | |
2047 | pkg_search_module(DEE dee-1.0 REQUIRED) |
2048 | pkg_search_module(GOBJECT gobject-2.0 REQUIRED) |
2049 | |
2050 | === added directory 'tests/mocks/Unity/DashCommunicator' |
2051 | === added file 'tests/mocks/Unity/DashCommunicator/CMakeLists.txt' |
2052 | --- tests/mocks/Unity/DashCommunicator/CMakeLists.txt 1970-01-01 00:00:00 +0000 |
2053 | +++ tests/mocks/Unity/DashCommunicator/CMakeLists.txt 2014-07-28 15:50:22 +0000 |
2054 | @@ -0,0 +1,18 @@ |
2055 | +include_directories( |
2056 | + ${CMAKE_CURRENT_SOURCE_DIR} |
2057 | +) |
2058 | + |
2059 | +set(QMLDASHCOMMUNICATORPLUGIN_SRC |
2060 | + plugin.cpp |
2061 | + dashcommunicatorservice.cpp |
2062 | + dashcommunicator.cpp |
2063 | + ) |
2064 | + |
2065 | +add_library(MockDashCommunicator-qml MODULE |
2066 | + ${QMLDASHCOMMUNICATORPLUGIN_SRC} |
2067 | + ) |
2068 | + |
2069 | +qt5_use_modules(MockDashCommunicator-qml DBus Qml) |
2070 | + |
2071 | +# export the qmldir and qmltypes files |
2072 | +add_unity8_mock(Unity.DashCommunicator 0.1 Unity/DashCommunicator TARGETS MockDashCommunicator-qml) |
2073 | |
2074 | === added file 'tests/mocks/Unity/DashCommunicator/dashcommunicator.cpp' |
2075 | --- tests/mocks/Unity/DashCommunicator/dashcommunicator.cpp 1970-01-01 00:00:00 +0000 |
2076 | +++ tests/mocks/Unity/DashCommunicator/dashcommunicator.cpp 2014-07-28 15:50:22 +0000 |
2077 | @@ -0,0 +1,37 @@ |
2078 | +/* |
2079 | + * Copyright (C) 2014 Canonical, Ltd. |
2080 | + * |
2081 | + * This program is free software: you can redistribute it and/or modify it under |
2082 | + * the terms of the GNU Lesser General Public License version 3, as published by |
2083 | + * the Free Software Foundation. |
2084 | + * |
2085 | + * This program is distributed in the hope that it will be useful, but WITHOUT |
2086 | + * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, |
2087 | + * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
2088 | + * Lesser General Public License for more details. |
2089 | + * |
2090 | + * You should have received a copy of the GNU Lesser General Public License |
2091 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2092 | + */ |
2093 | + |
2094 | +#include "dashcommunicator.h" |
2095 | + |
2096 | +#include <QObject> |
2097 | +#include <QDBusConnection> |
2098 | +#include <QDBusInterface> |
2099 | +#include <QDebug> |
2100 | + |
2101 | +DashCommunicator::DashCommunicator(QObject *parent): |
2102 | + QObject(parent) |
2103 | +{ |
2104 | +} |
2105 | + |
2106 | +DashCommunicator::~DashCommunicator() |
2107 | +{ |
2108 | +} |
2109 | + |
2110 | + |
2111 | +void DashCommunicator::setCurrentScope(const QString &scopeId, bool animate, bool reset) |
2112 | +{ |
2113 | + Q_EMIT setCurrentScopeCalled(scopeId, animate, reset); |
2114 | +} |
2115 | |
2116 | === added file 'tests/mocks/Unity/DashCommunicator/dashcommunicator.h' |
2117 | --- tests/mocks/Unity/DashCommunicator/dashcommunicator.h 1970-01-01 00:00:00 +0000 |
2118 | +++ tests/mocks/Unity/DashCommunicator/dashcommunicator.h 2014-07-28 15:50:22 +0000 |
2119 | @@ -0,0 +1,39 @@ |
2120 | +/* |
2121 | + * Copyright (C) 2014 Canonical, Ltd. |
2122 | + * |
2123 | + * This program is free software: you can redistribute it and/or modify it under |
2124 | + * the terms of the GNU Lesser General Public License version 3, as published by |
2125 | + * the Free Software Foundation. |
2126 | + * |
2127 | + * This program is distributed in the hope that it will be useful, but WITHOUT |
2128 | + * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, |
2129 | + * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
2130 | + * Lesser General Public License for more details. |
2131 | + * |
2132 | + * You should have received a copy of the GNU Lesser General Public License |
2133 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2134 | + */ |
2135 | + |
2136 | +#ifndef DASHCOMMUNICATOR_H |
2137 | +#define DASHCOMMUNICATOR_H |
2138 | + |
2139 | +#include <QObject> |
2140 | + |
2141 | +class DashCommunicator: public QObject |
2142 | +{ |
2143 | + Q_OBJECT |
2144 | + Q_CLASSINFO("D-Bus Interface", "com.canonical.Unity.DashCommunicator") |
2145 | + |
2146 | +public: |
2147 | + DashCommunicator(QObject *parent = 0); |
2148 | + ~DashCommunicator(); |
2149 | + |
2150 | +public Q_SLOTS: |
2151 | + void setCurrentScope(const QString &scopeId, bool animate, bool reset); |
2152 | + |
2153 | +Q_SIGNALS: |
2154 | + // This mock just emits calls back to the QML api for the plugin to verify calls |
2155 | + void setCurrentScopeCalled(const QString &scopeId, bool animate, bool reset); |
2156 | +}; |
2157 | + |
2158 | +#endif |
2159 | |
2160 | === added file 'tests/mocks/Unity/DashCommunicator/dashcommunicatorservice.cpp' |
2161 | --- tests/mocks/Unity/DashCommunicator/dashcommunicatorservice.cpp 1970-01-01 00:00:00 +0000 |
2162 | +++ tests/mocks/Unity/DashCommunicator/dashcommunicatorservice.cpp 2014-07-28 15:50:22 +0000 |
2163 | @@ -0,0 +1,33 @@ |
2164 | +/* |
2165 | + * Copyright (C) 2014 Canonical, Ltd. |
2166 | + * |
2167 | + * This program is free software: you can redistribute it and/or modify it under |
2168 | + * the terms of the GNU Lesser General Public License version 3, as published by |
2169 | + * the Free Software Foundation. |
2170 | + * |
2171 | + * This program is distributed in the hope that it will be useful, but WITHOUT |
2172 | + * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, |
2173 | + * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
2174 | + * Lesser General Public License for more details. |
2175 | + * |
2176 | + * You should have received a copy of the GNU Lesser General Public License |
2177 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2178 | + */ |
2179 | + |
2180 | +#include "dashcommunicatorservice.h" |
2181 | + |
2182 | +DashCommunicatorService::DashCommunicatorService(QObject *parent): |
2183 | + QObject(parent) |
2184 | +{ |
2185 | +} |
2186 | + |
2187 | + |
2188 | +DashCommunicatorService::~DashCommunicatorService() |
2189 | +{ |
2190 | + |
2191 | +} |
2192 | + |
2193 | +void DashCommunicatorService::mockSetCurrentScope(const QString &scopeId, bool animate, bool reset) |
2194 | +{ |
2195 | + Q_EMIT setCurrentScope(scopeId, animate, reset); |
2196 | +} |
2197 | |
2198 | === added file 'tests/mocks/Unity/DashCommunicator/dashcommunicatorservice.h' |
2199 | --- tests/mocks/Unity/DashCommunicator/dashcommunicatorservice.h 1970-01-01 00:00:00 +0000 |
2200 | +++ tests/mocks/Unity/DashCommunicator/dashcommunicatorservice.h 2014-07-28 15:50:22 +0000 |
2201 | @@ -0,0 +1,36 @@ |
2202 | +/* |
2203 | + * Copyright (C) 2014 Canonical, Ltd. |
2204 | + * |
2205 | + * This program is free software: you can redistribute it and/or modify it under |
2206 | + * the terms of the GNU Lesser General Public License version 3, as published by |
2207 | + * the Free Software Foundation. |
2208 | + * |
2209 | + * This program is distributed in the hope that it will be useful, but WITHOUT |
2210 | + * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, |
2211 | + * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
2212 | + * Lesser General Public License for more details. |
2213 | + * |
2214 | + * You should have received a copy of the GNU Lesser General Public License |
2215 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2216 | + */ |
2217 | + |
2218 | +#ifndef DASHCOMMUNICATORSERVICE_H |
2219 | +#define DASHCOMMUNICATORSERVICE_H |
2220 | + |
2221 | +#include <QObject> |
2222 | + |
2223 | +class DashCommunicatorService: public QObject |
2224 | +{ |
2225 | + Q_OBJECT |
2226 | +public: |
2227 | + DashCommunicatorService(QObject *parent = 0); |
2228 | + ~DashCommunicatorService(); |
2229 | + |
2230 | +Q_SIGNALS: |
2231 | + void setCurrentScope(const QString &scopeId, bool animate, bool reset); |
2232 | + |
2233 | +public Q_SLOTS: |
2234 | + void mockSetCurrentScope(const QString &scopeId, bool animate, bool reset); |
2235 | +}; |
2236 | + |
2237 | +#endif // DBUSUNITYSESSIONSERVICE_H |
2238 | |
2239 | === added file 'tests/mocks/Unity/DashCommunicator/plugin.cpp' |
2240 | --- tests/mocks/Unity/DashCommunicator/plugin.cpp 1970-01-01 00:00:00 +0000 |
2241 | +++ tests/mocks/Unity/DashCommunicator/plugin.cpp 2014-07-28 15:50:22 +0000 |
2242 | @@ -0,0 +1,31 @@ |
2243 | +/* |
2244 | + * Copyright (C) 2014 Canonical, Ltd. |
2245 | + * |
2246 | + * This program is free software; you can redistribute it and/or modify |
2247 | + * it under the terms of the GNU General Public License as published by |
2248 | + * the Free Software Foundation; version 3. |
2249 | + * |
2250 | + * This program is distributed in the hope that it will be useful, |
2251 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2252 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2253 | + * GNU General Public License for more details. |
2254 | + * |
2255 | + * You should have received a copy of the GNU General Public License |
2256 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2257 | + * |
2258 | + * Authors: Michael Zanetti <michael.zanetti@canonical.com> |
2259 | + */ |
2260 | + |
2261 | +#include "plugin.h" |
2262 | +#include "dashcommunicator.h" |
2263 | +#include "dashcommunicatorservice.h" |
2264 | + |
2265 | +#include <QDBusConnection> |
2266 | +#include <QtQml/qqml.h> |
2267 | + |
2268 | +void DashCommunicatorPlugin::registerTypes(const char *uri) |
2269 | +{ |
2270 | + Q_ASSERT(uri == QStringLiteral("Unity.DashCommunicator")); |
2271 | + qmlRegisterType<DashCommunicatorService>(uri, 0, 1, "DashCommunicatorService"); |
2272 | + qmlRegisterType<DashCommunicator>(uri, 0, 1, "DashCommunicator"); |
2273 | +} |
2274 | |
2275 | === added file 'tests/mocks/Unity/DashCommunicator/plugin.h' |
2276 | --- tests/mocks/Unity/DashCommunicator/plugin.h 1970-01-01 00:00:00 +0000 |
2277 | +++ tests/mocks/Unity/DashCommunicator/plugin.h 2014-07-28 15:50:22 +0000 |
2278 | @@ -0,0 +1,34 @@ |
2279 | +/* |
2280 | + * Copyright (C) 2014 Canonical, Ltd. |
2281 | + * |
2282 | + * This program is free software; you can redistribute it and/or modify |
2283 | + * it under the terms of the GNU General Public License as published by |
2284 | + * the Free Software Foundation; version 3. |
2285 | + * |
2286 | + * This program is distributed in the hope that it will be useful, |
2287 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2288 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2289 | + * GNU General Public License for more details. |
2290 | + * |
2291 | + * You should have received a copy of the GNU General Public License |
2292 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2293 | + * |
2294 | + * Authors: Michael Zanetti <michael.zanetti@canonical.com> |
2295 | + */ |
2296 | + |
2297 | +#ifndef DASHCOMMUNICATOR_PLUGIN_H |
2298 | +#define DASHCOMMUNICATOR_PLUGIN_H |
2299 | + |
2300 | +#include <QtQml/QQmlEngine> |
2301 | +#include <QtQml/QQmlExtensionPlugin> |
2302 | + |
2303 | +class DashCommunicatorPlugin : public QQmlExtensionPlugin |
2304 | +{ |
2305 | + Q_OBJECT |
2306 | + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface") |
2307 | + |
2308 | +public: |
2309 | + void registerTypes(const char *uri); |
2310 | +}; |
2311 | + |
2312 | +#endif |
2313 | |
2314 | === added file 'tests/mocks/Unity/DashCommunicator/qmldir' |
2315 | --- tests/mocks/Unity/DashCommunicator/qmldir 1970-01-01 00:00:00 +0000 |
2316 | +++ tests/mocks/Unity/DashCommunicator/qmldir 2014-07-28 15:50:22 +0000 |
2317 | @@ -0,0 +1,3 @@ |
2318 | +module Unity.DashCommunicator |
2319 | +plugin MockDashCommunicator-qml |
2320 | +typeinfo DashCommunicator.qmltypes |
2321 | |
2322 | === modified file 'tests/qmltests/Dash/tst_Dash.qml' |
2323 | --- tests/qmltests/Dash/tst_Dash.qml 2014-07-11 11:45:45 +0000 |
2324 | +++ tests/qmltests/Dash/tst_Dash.qml 2014-07-28 15:50:22 +0000 |
2325 | @@ -59,6 +59,7 @@ |
2326 | verify(dashContentList != undefined); |
2327 | tryCompare(dashContentList, "count", 0); |
2328 | scopes.load(); |
2329 | + tryCompare(dashContentList, "currentIndex", 0); |
2330 | } |
2331 | |
2332 | function get_scope_data() { |
2333 | @@ -91,5 +92,23 @@ |
2334 | verify(dashContentList != undefined); |
2335 | tryCompare(dashContentList, "currentIndex", data.visualIndex); |
2336 | } |
2337 | + |
2338 | + function test_setCurrentScope() { |
2339 | + var dashContentList = findChild(dash, "dashContentList"); |
2340 | + var startX = dash.width - units.gu(1); |
2341 | + var startY = dash.height / 2; |
2342 | + var stopX = units.gu(1) |
2343 | + var stopY = startY; |
2344 | + var retry = 0; |
2345 | + while (dashContentList.currentIndex != 2 && retry <= 5) { |
2346 | + mouseFlick(dash, startX, startY, stopX, stopY) |
2347 | + waitForRendering(dashContentList) |
2348 | + retry++; |
2349 | + } |
2350 | + compare(dashContentList.currentIndex, 2); |
2351 | + var dashCommunicatorService = findInvisibleChild(dash, "dashCommunicatorService"); |
2352 | + dashCommunicatorService.mockSetCurrentScope("clickscope", true, true); |
2353 | + tryCompare(dashContentList, "currentIndex", 1) |
2354 | + } |
2355 | } |
2356 | } |
2357 | |
2358 | === modified file 'tests/qmltests/Stages/tst_PhoneStage.qml' |
2359 | --- tests/qmltests/Stages/tst_PhoneStage.qml 2014-07-28 15:50:19 +0000 |
2360 | +++ tests/qmltests/Stages/tst_PhoneStage.qml 2014-07-28 15:50:22 +0000 |
2361 | @@ -231,9 +231,10 @@ |
2362 | } |
2363 | |
2364 | function cleanup() { |
2365 | - while (ApplicationManager.count > 0) { |
2366 | + while (ApplicationManager.count > 1) { |
2367 | var oldCount = ApplicationManager.count; |
2368 | - ApplicationManager.stopApplication(ApplicationManager.get(0).appId) |
2369 | + var closingIndex = ApplicationManager.focusedApplicationId == "unity8-dash" ? 1 : 0 |
2370 | + ApplicationManager.stopApplication(ApplicationManager.get(closingIndex).appId) |
2371 | tryCompare(ApplicationManager, "count", oldCount - 1) |
2372 | } |
2373 | } |
2374 | |
2375 | === modified file 'tests/qmltests/tst_Shell.qml' |
2376 | --- tests/qmltests/tst_Shell.qml 2014-07-28 15:50:19 +0000 |
2377 | +++ tests/qmltests/tst_Shell.qml 2014-07-28 15:50:22 +0000 |
2378 | @@ -56,49 +56,20 @@ |
2379 | signalName: "sessionStarted" |
2380 | } |
2381 | |
2382 | + SignalSpy { |
2383 | + id: dashCommunicatorSpy |
2384 | + signalName: "setCurrentScopeCalled" |
2385 | + } |
2386 | + |
2387 | UT.UnityTestCase { |
2388 | name: "Shell" |
2389 | when: windowShown |
2390 | |
2391 | function initTestCase() { |
2392 | - var ok = false; |
2393 | - var attempts = 0; |
2394 | - var maxAttempts = 1000; |
2395 | - |
2396 | - // Qt loads a qml scene asynchronously. So early on, some findChild() calls made in |
2397 | - // tests may fail because the desired child item wasn't loaded yet. |
2398 | - // Thus here we try to ensure the scene has been fully loaded before proceeding with the tests. |
2399 | - // As I couldn't find an API in QQuickView & friends to tell me that the scene is 100% loaded |
2400 | - // (all items instantiated, etc), I resort to checking the existence of some key items until |
2401 | - // repeatedly until they're all there. |
2402 | - do { |
2403 | - var dashContentList = findChild(shell, "dashContentList"); |
2404 | - waitForRendering(dashContentList); |
2405 | - var homeLoader = findChild(dashContentList, "clickscope loader"); |
2406 | - ok = homeLoader !== null |
2407 | - && homeLoader.item !== undefined; |
2408 | - |
2409 | - var greeter = findChild(shell, "greeter"); |
2410 | - ok &= greeter !== null; |
2411 | - |
2412 | - var launcherPanel = findChild(shell, "launcherPanel"); |
2413 | - ok &= launcherPanel !== null; |
2414 | - |
2415 | - attempts++; |
2416 | - if (!ok) { |
2417 | - console.log("Attempt " + attempts + " failed. Waiting a bit before trying again."); |
2418 | - // wait a bit before retrying |
2419 | - wait(100); |
2420 | - } else { |
2421 | - console.log("All seem fine after " + attempts + " attempts."); |
2422 | - } |
2423 | - } while (!ok && attempts <= maxAttempts); |
2424 | - |
2425 | - verify(ok); |
2426 | - |
2427 | swipeAwayGreeter(); |
2428 | |
2429 | sessionSpy.target = findChild(shell, "greeter") |
2430 | + dashCommunicatorSpy.target = findInvisibleChild(shell, "dashCommunicator"); |
2431 | } |
2432 | |
2433 | function cleanup() { |
2434 | @@ -111,56 +82,16 @@ |
2435 | // kill all (fake) running apps |
2436 | killApps(ApplicationManager); |
2437 | |
2438 | - var dashContent = findChild(shell, "dashContent"); |
2439 | - dashContent.closePreview(); |
2440 | - |
2441 | - var dashHome = findChild(shell, "clickscope loader"); |
2442 | - swipeUntilScopeViewIsReached(dashHome); |
2443 | - |
2444 | + waitForUIToSettle(); |
2445 | hideIndicators(); |
2446 | } |
2447 | |
2448 | - function killApps(apps) { |
2449 | - if (!apps) return; |
2450 | - while (apps.count > 0) { |
2451 | - ApplicationManager.stopApplication(apps.get(0).appId); |
2452 | + function killApps() { |
2453 | + while (ApplicationManager.count > 1) { |
2454 | + var appIndex = ApplicationManager.get(0).appId == "unity8-dash" ? 1 : 0 |
2455 | + ApplicationManager.stopApplication(ApplicationManager.get(appIndex).appId); |
2456 | } |
2457 | - compare(ApplicationManager.count, 0) |
2458 | - } |
2459 | - |
2460 | - /* |
2461 | - Test the effect of a right-edge drag on the dash in 3 situations: |
2462 | - 1 - when no application has been launched yet |
2463 | - 2 - when there's a minimized application |
2464 | - 3 - after the last running application has been closed/stopped |
2465 | - |
2466 | - The behavior of Dash on 3 should be the same as on 1. |
2467 | - */ |
2468 | - function test_rightEdgeDrag() { |
2469 | - checkRightEdgeDragWithNoRunningApps(); |
2470 | - |
2471 | - dragLauncherIntoView(); |
2472 | - |
2473 | - // Launch an app from the launcher |
2474 | - tapOnAppIconInLauncher(); |
2475 | - waitUntilApplicationWindowIsFullyVisible(); |
2476 | - |
2477 | - // Minimize the application we just launched |
2478 | - swipeFromLeftEdge(units.gu(27)); |
2479 | - |
2480 | - waitForUIToSettle(); |
2481 | - |
2482 | - checkRightEdgeDragWithMinimizedApp(); |
2483 | - |
2484 | - // Minimize that application once again |
2485 | - swipeFromLeftEdge(units.gu(27)); |
2486 | - |
2487 | - // Right edge behavior should now be the same as before that app, |
2488 | - // was launched. Manually cleanup beforehand to get to initial |
2489 | - // state. |
2490 | - cleanup(); |
2491 | - waitForUIToSettle(); |
2492 | - checkRightEdgeDragWithNoRunningApps(); |
2493 | + compare(ApplicationManager.count, 1) |
2494 | } |
2495 | |
2496 | function test_leftEdgeDrag_data() { |
2497 | @@ -183,7 +114,7 @@ |
2498 | |
2499 | swipeFromLeftEdge(data.swipeLength); |
2500 | if (data.appHides) |
2501 | - waitUntilApplicationWindowIsFullyHidden(); |
2502 | + waitUntilDashIsFocused(); |
2503 | else |
2504 | waitUntilApplicationWindowIsFullyVisible(); |
2505 | } |
2506 | @@ -240,99 +171,17 @@ |
2507 | } |
2508 | |
2509 | /* |
2510 | - Perform a right-edge drag when the Dash is being show and there are |
2511 | - no running/minimized apps to be restored. |
2512 | - |
2513 | - The expected behavior is that an animation should be played to hint the |
2514 | - user that his right-edge drag gesture has been successfully recognized |
2515 | - but there is no application to be brought to foreground. |
2516 | - */ |
2517 | - function checkRightEdgeDragWithNoRunningApps() { |
2518 | - var touchX = shell.width - (shell.edgeSize / 2); |
2519 | - var touchY = shell.height / 2; |
2520 | - |
2521 | - var dash = findChild(shell, "dash"); |
2522 | - // check that dash has normal scale and opacity |
2523 | - tryCompare(dash, "contentScale", 1.0); |
2524 | - tryCompare(dash, "opacity", 1.0); |
2525 | - |
2526 | - touchFlick(shell, touchX, touchY, shell.width * 0.1, touchY, |
2527 | - true /* beginTouch */, false /* endTouch */, units.gu(10), 50); |
2528 | - |
2529 | - // check that Dash has been scaled down and had its opacity reduced |
2530 | - tryCompareFunction(function() { return dash.contentScale <= 0.9; }, true); |
2531 | - tryCompareFunction(function() { return dash.opacity <= 0.5; }, true); |
2532 | - |
2533 | - touchRelease(shell, shell.width * 0.1, touchY); |
2534 | - |
2535 | - // and now everything should have gone back to normal |
2536 | - tryCompare(dash, "contentScale", 1.0); |
2537 | - tryCompare(dash, "opacity", 1.0); |
2538 | - } |
2539 | - |
2540 | - /* |
2541 | - Perform a right-edge drag when the Dash is being show and there is |
2542 | - a running/minimized app to be restored. |
2543 | - |
2544 | - The expected behavior is that the dash should fade away and ultimately be |
2545 | - made invisible once the gesture is finished as the restored app will now |
2546 | - be on foreground. |
2547 | - */ |
2548 | - function checkRightEdgeDragWithMinimizedApp() { |
2549 | - var touchX = shell.width - (shell.edgeSize / 2); |
2550 | - var touchY = shell.height / 2; |
2551 | - |
2552 | - var dash = findChild(shell, "dash"); |
2553 | - // check that dash has normal scale and opacity |
2554 | - tryCompare(dash, "contentScale", 1.0); |
2555 | - tryCompare(dash, "opacity", 1.0); |
2556 | - |
2557 | - touchFlick(shell, touchX, touchY, shell.width * 0.1, touchY, |
2558 | - true /* beginTouch */, false /* endTouch */, units.gu(10), 50); |
2559 | - |
2560 | - // check that Dash has been scaled down and had its opacity reduced |
2561 | - tryCompareFunction(function() { return dash.contentScale <= 0.9; }, true); |
2562 | - tryCompareFunction(function() { return dash.opacity <= 0.5; }, true); |
2563 | - |
2564 | - touchRelease(shell, shell.width * 0.1, touchY); |
2565 | - |
2566 | - // dash should have gone away, now that the app is on foreground |
2567 | - tryCompare(dash, "visible", false); |
2568 | - } |
2569 | - |
2570 | - /* |
2571 | Regression test for bug https://bugs.launchpad.net/touch-preview-images/+bug/1193419 |
2572 | |
2573 | - When the user minimizes an application (left-edge swipe) he should always end up in the "Running Apps" |
2574 | - category of the "Applications" scope view. |
2575 | + When the user minimizes an application (left-edge swipe) he should always end up in the |
2576 | + "Applications" scope view. |
2577 | |
2578 | Steps: |
2579 | - - go to apps lens |
2580 | - - scroll to the bottom |
2581 | - - reveal launcher and launch an app |
2582 | + - reveal launcher and launch an app that covers the dash |
2583 | - perform long left edge swipe to go minimize the app and go back to the dash. |
2584 | - |
2585 | - Expected Results |
2586 | - - apps lens shown |
2587 | + - verify the setCurrentScope() D-Bus call to the dash has been called for the correct scope id. |
2588 | */ |
2589 | function test_minimizingAppTakesToDashApps() { |
2590 | - var dashApps = findChild(shell, "clickscope"); |
2591 | - swipeUntilScopeViewIsReached(dashApps); |
2592 | - |
2593 | - // swipe finger up until the running/recent apps section (which we assume |
2594 | - // it's the first one) is as far from view as possible. |
2595 | - // We also assume that DashApps is tall enough that it's scrollable |
2596 | - var appsCategoryListView = findChild(dashApps, "categoryListView"); |
2597 | - while (!appsCategoryListView.atYEnd) { |
2598 | - swipeUpFromCenter(); |
2599 | - tryCompare(appsCategoryListView, "moving", false); |
2600 | - } |
2601 | - |
2602 | - // Switch away from the Applications scope. |
2603 | - swipeRightFromCenter(); |
2604 | - waitUntilItemStopsMoving(dashApps); |
2605 | - verify(!itemIsOnScreen(dashApps)); |
2606 | - |
2607 | dragLauncherIntoView(); |
2608 | |
2609 | // Launch an app from the launcher |
2610 | @@ -340,19 +189,16 @@ |
2611 | |
2612 | waitUntilApplicationWindowIsFullyVisible(); |
2613 | |
2614 | - // Dragging launcher into view with a little bit of gap (units.gu(1)) should switch to Apps scope |
2615 | - dragLauncherIntoView(); |
2616 | - verify(itemIsOnScreen(dashApps)); |
2617 | + verify(ApplicationManager.focusedApplicationId !== "unity8-dash") |
2618 | |
2619 | + dashCommunicatorSpy.clear(); |
2620 | // Minimize the application we just launched |
2621 | swipeFromLeftEdge(units.gu(27)); |
2622 | |
2623 | - // Wait for the whole UI to settle down |
2624 | - waitUntilApplicationWindowIsFullyHidden(); |
2625 | - waitUntilItemStopsMoving(dashApps); |
2626 | - tryCompare(appsCategoryListView, "moving", false); |
2627 | + tryCompare(ApplicationManager, "focusedApplicationId", "unity8-dash"); |
2628 | |
2629 | - verify(itemIsOnScreen(dashApps)); |
2630 | + compare(dashCommunicatorSpy.count, 1); |
2631 | + compare(dashCommunicatorSpy.signalArguments[0][0], "clickscope"); |
2632 | } |
2633 | |
2634 | function test_showInputMethod() { |
2635 | @@ -409,9 +255,14 @@ |
2636 | |
2637 | // Wait for the whole UI to settle down |
2638 | function waitForUIToSettle() { |
2639 | - waitUntilApplicationWindowIsFullyHidden(); |
2640 | - var dashContentList = findChild(shell, "dashContentList"); |
2641 | - tryCompare(dashContentList, "moving", false); |
2642 | + var launcher = findChild(shell, "launcherPanel") |
2643 | + tryCompareFunction(function() {return launcher.x === 0 || launcher.x === -launcher.width;}, true); |
2644 | + if (launcher.x === 0) { |
2645 | + mouseClick(shell, shell.width / 2, shell.height / 2) |
2646 | + } |
2647 | + tryCompare(launcher, "x", -launcher.width) |
2648 | + |
2649 | + waitForRendering(shell) |
2650 | } |
2651 | |
2652 | function dragToCloseIndicatorsPanel() { |
2653 | @@ -468,24 +319,13 @@ |
2654 | } |
2655 | |
2656 | function waitUntilApplicationWindowIsFullyVisible() { |
2657 | - var underlay = findChild(shell, "underlay"); |
2658 | - tryCompare(underlay, "visible", false); |
2659 | - } |
2660 | - |
2661 | - function waitUntilApplicationWindowIsFullyHidden() { |
2662 | - var stages = findChild(shell, "stages"); |
2663 | - tryCompare(stages, "fullyHidden", true); |
2664 | - } |
2665 | - |
2666 | - function swipeUntilScopeViewIsReached(scopeView) { |
2667 | - while (!itemIsOnScreen(scopeView)) { |
2668 | - if (itemIsToLeftOfScreen(scopeView)) { |
2669 | - swipeRightFromCenter(); |
2670 | - } else { |
2671 | - swipeLeftFromCenter(); |
2672 | - } |
2673 | - waitUntilItemStopsMoving(scopeView); |
2674 | - } |
2675 | + var appDelegate = findChild(shell, "appDelegate0") |
2676 | + var surfaceContainer = findChild(appDelegate, "surfaceContainer"); |
2677 | + tryCompareFunction(function() { return surfaceContainer.surface !== null; }, true); |
2678 | + } |
2679 | + |
2680 | + function waitUntilDashIsFocused() { |
2681 | + tryCompare(ApplicationManager, "focusedApplicationId", "unity8-dash"); |
2682 | } |
2683 | |
2684 | function swipeFromLeftEdge(swipeLength) { |
2685 | @@ -494,24 +334,6 @@ |
2686 | touchFlick(shell, touchStartX, touchStartY, swipeLength, touchStartY); |
2687 | } |
2688 | |
2689 | - function swipeLeftFromCenter() { |
2690 | - var touchStartX = shell.width * 3 / 4; |
2691 | - var touchStartY = shell.height / 2; |
2692 | - touchFlick(shell, touchStartX, touchStartY, 0, touchStartY); |
2693 | - } |
2694 | - |
2695 | - function swipeRightFromCenter() { |
2696 | - var touchStartX = shell.width * 3 / 4; |
2697 | - var touchStartY = shell.height / 2; |
2698 | - touchFlick(shell, touchStartX, touchStartY, shell.width, touchStartY); |
2699 | - } |
2700 | - |
2701 | - function swipeUpFromCenter() { |
2702 | - var touchStartX = shell.width / 2; |
2703 | - var touchStartY = shell.height / 2; |
2704 | - touchFlick(shell, touchStartX, touchStartY, touchStartX, 0); |
2705 | - } |
2706 | - |
2707 | function itemIsOnScreen(item) { |
2708 | var itemRectInShell = item.mapToItem(shell, 0, 0, item.width, item.height); |
2709 | |
2710 | @@ -521,64 +343,6 @@ |
2711 | && itemRectInShell.y + itemRectInShell.height <= shell.height; |
2712 | } |
2713 | |
2714 | - function itemIsToLeftOfScreen(item) { |
2715 | - var itemRectInShell = item.mapToItem(shell, 0, 0, item.width, item.height); |
2716 | - return itemRectInShell.x < 0; |
2717 | - } |
2718 | - |
2719 | - function waitUntilItemStopsMoving(item) { |
2720 | - var itemRectInShell = item.mapToItem(shell, 0, 0, item.width, item.height); |
2721 | - var previousX = itemRectInShell.x; |
2722 | - var previousY = itemRectInShell.y; |
2723 | - var isStill = false; |
2724 | - |
2725 | - do { |
2726 | - wait(100); |
2727 | - itemRectInShell = item.mapToItem(shell, 0, 0, item.width, item.height); |
2728 | - if (itemRectInShell.x == previousX && itemRectInShell.y == previousY) { |
2729 | - isStill = true; |
2730 | - } else { |
2731 | - previousX = itemRectInShell.x; |
2732 | - previousY = itemRectInShell.y; |
2733 | - } |
2734 | - } while (!isStill); |
2735 | - } |
2736 | - |
2737 | - function test_DashShown_data() { |
2738 | - return [ |
2739 | - {tag: "in focus", greeter: false, app: false, launcher: false, indicators: false, expectedShown: true}, |
2740 | - {tag: "under greeter", greeter: true, app: false, launcher: false, indicators: false, expectedShown: false}, |
2741 | - {tag: "under app", greeter: false, app: true, launcher: false, indicators: false, expectedShown: false}, |
2742 | - {tag: "under launcher", greeter: false, app: false, launcher: true, indicators: false, expectedShown: true}, |
2743 | - {tag: "under indicators", greeter: false, app: false, launcher: false, indicators: true, expectedShown: false}, |
2744 | - ] |
2745 | - } |
2746 | - |
2747 | - function test_DashShown(data) { |
2748 | - if (data.greeter) { |
2749 | - // Swipe the greeter in |
2750 | - var greeter = findChild(shell, "greeter"); |
2751 | - Powerd.displayPowerStateChange(Powerd.Off, 0); |
2752 | - tryCompare(greeter, "showProgress", 1); |
2753 | - } |
2754 | - |
2755 | - if (data.app) { |
2756 | - dragLauncherIntoView(); |
2757 | - tapOnAppIconInLauncher(); |
2758 | - } |
2759 | - |
2760 | - if (data.launcher) { |
2761 | - dragLauncherIntoView(); |
2762 | - } |
2763 | - |
2764 | - if (data.indicators) { |
2765 | - showIndicators(); |
2766 | - } |
2767 | - |
2768 | - var dash = findChild(shell, "dash"); |
2769 | - tryCompare(dash, "shown", data.expectedShown); |
2770 | - } |
2771 | - |
2772 | function test_focusRequestedHidesGreeter() { |
2773 | var greeter = findChild(shell, "greeter"); |
2774 | |
2775 | @@ -587,10 +351,9 @@ |
2776 | tryCompareFunction(function() { return app.surface != null }, true); |
2777 | |
2778 | // Minimize the application we just launched |
2779 | - swipeFromLeftEdge(units.gu(27)); |
2780 | + swipeFromLeftEdge(units.gu(26) + 1); |
2781 | |
2782 | - // Wait for the whole UI to settle down |
2783 | - waitUntilApplicationWindowIsFullyHidden(); |
2784 | + waitUntilDashIsFocused(); |
2785 | |
2786 | greeter.show(); |
2787 | tryCompare(greeter, "showProgress", 1); |
2788 | @@ -606,8 +369,9 @@ |
2789 | |
2790 | showIndicators(); |
2791 | |
2792 | + var oldCount = ApplicationManager.count; |
2793 | ApplicationManager.startApplication("camera-app"); |
2794 | - tryCompare(ApplicationManager, "count", 1); |
2795 | + tryCompare(ApplicationManager, "count", oldCount + 1); |
2796 | |
2797 | tryCompare(indicators, "fullyClosed", true); |
2798 | } |
2799 | @@ -616,6 +380,7 @@ |
2800 | function test_showGreeterDBusCall() { |
2801 | var greeter = findChild(shell, "greeter") |
2802 | tryCompare(greeter, "showProgress", 0) |
2803 | + waitForRendering(greeter); |
2804 | LightDM.Greeter.showGreeter() |
2805 | tryCompare(greeter, "showProgress", 1) |
2806 | } |
2807 | @@ -624,6 +389,7 @@ |
2808 | sessionSpy.clear() |
2809 | |
2810 | var greeter = findChild(shell, "greeter") |
2811 | + waitForRendering(greeter) |
2812 | greeter.show() |
2813 | tryCompare(greeter, "showProgress", 1) |
2814 | |
2815 | |
2816 | === modified file 'tests/qmltests/tst_ShellWithPin.qml' |
2817 | --- tests/qmltests/tst_ShellWithPin.qml 2014-07-15 18:26:25 +0000 |
2818 | +++ tests/qmltests/tst_ShellWithPin.qml 2014-07-28 15:50:22 +0000 |
2819 | @@ -58,40 +58,6 @@ |
2820 | when: windowShown |
2821 | |
2822 | function initTestCase() { |
2823 | - var ok = false; |
2824 | - var attempts = 0; |
2825 | - var maxAttempts = 1000; |
2826 | - |
2827 | - // Qt loads a qml scene asynchronously. So early on, some findChild() calls made in |
2828 | - // tests may fail because the desired child item wasn't loaded yet. |
2829 | - // Thus here we try to ensure the scene has been fully loaded before proceeding with the tests. |
2830 | - // As I couldn't find an API in QQuickView & friends to tell me that the scene is 100% loaded |
2831 | - // (all items instantiated, etc), I resort to checking the existence of some key items until |
2832 | - // repeatedly until they're all there. |
2833 | - do { |
2834 | - var dashContentList = findChild(shell, "dashContentList"); |
2835 | - waitForRendering(dashContentList); |
2836 | - var homeLoader = findChild(dashContentList, "clickscope loader"); |
2837 | - ok = homeLoader !== null |
2838 | - && homeLoader.item !== undefined; |
2839 | - |
2840 | - var greeter = findChild(shell, "greeter"); |
2841 | - ok &= greeter !== null; |
2842 | - |
2843 | - var launcherPanel = findChild(shell, "launcherPanel"); |
2844 | - ok &= launcherPanel !== null; |
2845 | - |
2846 | - attempts++; |
2847 | - if (!ok) { |
2848 | - console.log("Attempt " + attempts + " failed. Waiting a bit before trying again."); |
2849 | - // wait a bit before retrying |
2850 | - wait(100); |
2851 | - } else { |
2852 | - console.log("All seem fine after " + attempts + " attempts."); |
2853 | - } |
2854 | - } while (!ok && attempts <= maxAttempts); |
2855 | - |
2856 | - verify(ok); |
2857 | |
2858 | sessionSpy.target = findChild(shell, "greeter") |
2859 | } |
2860 | @@ -110,10 +76,11 @@ |
2861 | } |
2862 | |
2863 | function killApps() { |
2864 | - while (ApplicationManager.count > 0) { |
2865 | - ApplicationManager.stopApplication(ApplicationManager.get(0).appId) |
2866 | + while (ApplicationManager.count > 1) { |
2867 | + var appIndex = ApplicationManager.get(0).appId == "unity8-dash" ? 1 : 0 |
2868 | + ApplicationManager.stopApplication(ApplicationManager.get(appIndex).appId); |
2869 | } |
2870 | - compare(ApplicationManager.count, 0) |
2871 | + compare(ApplicationManager.count, 1) |
2872 | } |
2873 | |
2874 | function swipeAwayGreeter() { |
See inline.
Now, on DashCommunicator... I was wondering if we should instead register a scope:/// url handler, and then just dispatch scope:/ //clickscope/ when needed.
Only tricky part would be on left edge, when we should bring the dash in from the left with your finger, url-dispatcher would request focus, but we should ignore that request then.