Merge lp:~mzanetti/unity8/tune-right-edge-push into lp:unity8
- tune-right-edge-push
- Merge into trunk
Status: | Superseded |
---|---|
Proposed branch: | lp:~mzanetti/unity8/tune-right-edge-push |
Merge into: | lp:unity8 |
Diff against target: |
3039 lines (+1686/-421) 50 files modified
data/com.canonical.Unity8.gschema.xml (+2/-2) debian/control (+3/-1) plugins/Greeter/Unity/Launcher/CMakeLists.txt (+1/-1) plugins/Greeter/Unity/Launcher/launcheritem.cpp (+13/-0) plugins/Greeter/Unity/Launcher/launcheritem.h (+3/-0) plugins/Unity/Launcher/CMakeLists.txt (+4/-1) plugins/Unity/Launcher/appdrawermodel.cpp (+62/-0) plugins/Unity/Launcher/appdrawermodel.h (+33/-0) plugins/Unity/Launcher/launcheritem.cpp (+13/-0) plugins/Unity/Launcher/launcheritem.h (+4/-0) plugins/Unity/Launcher/launchermodel.cpp (+6/-37) plugins/Unity/Launcher/launchermodel.h (+0/-14) plugins/Unity/Launcher/plugin.cpp (+2/-1) plugins/Unity/Launcher/ualwrapper.cpp (+73/-0) plugins/Unity/Launcher/ualwrapper.h (+35/-0) plugins/Utils/CMakeLists.txt (+4/-0) plugins/Utils/appdrawerproxymodel.cpp (+189/-0) plugins/Utils/appdrawerproxymodel.h (+87/-0) plugins/Utils/plugin.cpp (+2/-0) qml/Components/KeyboardShortcutsOverlay.qml (+13/-0) qml/Launcher/BackgroundBlur.qml (+81/-0) qml/Launcher/Drawer.qml (+306/-0) qml/Launcher/DrawerGridView.qml (+47/-0) qml/Launcher/DrawerListView.qml (+32/-0) qml/Launcher/Launcher.qml (+173/-31) qml/Launcher/MoreAppsHeader.qml (+46/-0) qml/Shell.qml (+10/-34) qml/Stage/Spread/WindowedRightEdgeMaths.qml (+19/-4) qml/Stage/Stage.qml (+4/-6) qml/Stage/StageMaths.qml (+2/-7) qml/Tutorial/TutorialLeftLong.qml (+1/-1) tests/mocks/Unity/Launcher/CMakeLists.txt (+5/-1) tests/mocks/Unity/Launcher/MockAppDrawerModel.cpp (+75/-0) tests/mocks/Unity/Launcher/MockAppDrawerModel.h (+32/-0) tests/mocks/Unity/Launcher/MockLauncherItem.cpp (+13/-0) tests/mocks/Unity/Launcher/MockLauncherItem.h (+6/-0) tests/mocks/Unity/Launcher/MockLauncherModel.cpp (+3/-0) tests/mocks/Unity/Launcher/plugin.cpp (+4/-0) tests/mocks/Utils/CMakeLists.txt (+4/-0) tests/mocks/Utils/plugin.cpp (+2/-0) tests/plugins/Greeter/Unity/Launcher/CMakeLists.txt (+1/-1) tests/plugins/Unity/Launcher/CMakeLists.txt (+2/-1) tests/qmltests/CMakeLists.txt (+1/-0) tests/qmltests/Dash/tst_DashShell.qml (+0/-29) tests/qmltests/Launcher/tst_Drawer.qml (+264/-0) tests/qmltests/Launcher/tst_Launcher.qml (+1/-1) tests/qmltests/Stage/tst_PhoneStage.qml (+0/-26) tests/qmltests/tst_OrientedShell.qml (+1/-13) tests/qmltests/tst_Shell.qml (+2/-143) tests/qmltests/tst_ShellWithPin.qml (+0/-66) |
To merge this branch: | bzr merge lp:~mzanetti/unity8/tune-right-edge-push |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Unity8 CI Bot | continuous-integration | Approve | |
Albert Astals Cid (community) | Approve | ||
Review via email: mp+311536@code.launchpad.net |
This proposal has been superseded by a proposal from 2016-12-06.
Commit message
tune right edge push
make it less intrusive when accidentally hitting the edge with the mouse
tweak visuals for the mouse case
Description of the change
* Are there any related MPs required for this MP to build/function as expected? Please list.
no
* Did you perform an exploratory manual test run of your code change and any related functionality?
yes
* If you changed the packaging (debian), did you subscribe the ubuntu-unity team to this MP?
no
* If you changed the UI, has there been a design review?
Showed a video to Vesa, he likes it. Added him as reviewer for confirmation
- 2704. By Michael Zanetti
-
tune right edge push as per design request
Unity8 CI Bot (unity8-ci-bot) wrote : | # |
Albert Astals Cid (aacid) wrote : | # |
Feels better, but please make progress a readonly property.
- 2705. By Michael Zanetti
-
make property readonly
Albert Astals Cid (aacid) wrote : | # |
* Did you perform an exploratory manual test run of the code change and any related functionality?
Yes
* Did CI run pass? If not, please explain why.
Yes
Unity8 CI Bot (unity8-ci-bot) wrote : | # |
PASSED: Continuous integration, rev:2705
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
- 2706. By Michael Zanetti
-
merge appdrawer as prereq
Unmerged revisions
Preview Diff
1 | === modified file 'data/com.canonical.Unity8.gschema.xml' |
2 | --- data/com.canonical.Unity8.gschema.xml 2016-11-16 05:54:50 +0000 |
3 | +++ data/com.canonical.Unity8.gschema.xml 2016-12-06 13:47:05 +0000 |
4 | @@ -12,7 +12,7 @@ |
5 | <description>The usage mode chosen will affect the Window Management behaviour.</description> |
6 | </key> |
7 | <key type="y" name="edge-barrier-sensitivity"> |
8 | - <default>35</default> |
9 | + <default>50</default> |
10 | <range min="1" max="100"/> |
11 | <summary>Sensitivity of screen edge barriers for the mouse pointer.</summary> |
12 | <description>Some UI actions like revealing the launcher or the applications spread are triggered by pushing the mouse pointer against a screen edge. This key defines how much you have to push in order to trigger the associated action.</description> |
13 | @@ -23,7 +23,7 @@ |
14 | <description>How much you have to push (in grid units)the mouse against an edge barrier when sensibility is 100.</description> |
15 | </key> |
16 | <key type="u" name="edge-barrier-max-push"> |
17 | - <default>60</default> |
18 | + <default>120</default> |
19 | <summary>Maximum push needed to overcome edge barrier</summary> |
20 | <description>How much you have to push (in grid units) the mouse against an edge barrier when sensibility is 1.</description> |
21 | </key> |
22 | |
23 | === modified file 'debian/control' |
24 | --- debian/control 2016-11-29 09:40:16 +0000 |
25 | +++ debian/control 2016-12-06 13:47:05 +0000 |
26 | @@ -38,7 +38,7 @@ |
27 | libubuntugestures5-private-dev (>= 1.3.2030), |
28 | libudev-dev, |
29 | libudm-common-dev, |
30 | - libunity-api-dev (>= 7.120), |
31 | + libunity-api-dev (>= 7.121), |
32 | libusermetricsoutput1-dev, |
33 | # Need those X11 libs touch emulation from mouse events in manual QML tests on a X11 desktop |
34 | libx11-dev[!arm64 !armhf], |
35 | @@ -49,6 +49,7 @@ |
36 | python3-all:any, |
37 | python3-setuptools, |
38 | qml-module-qt-labs-folderlistmodel, |
39 | + qml-module-qt-labs-settings, |
40 | qml-module-qtqml-statemachine, |
41 | qml-module-qtmultimedia (>= 5.4.1-1ubuntu19~overlay2), |
42 | qml-module-qtquick-layouts, |
43 | @@ -122,6 +123,7 @@ |
44 | qmenumodel-qml (>= 0.2.10), |
45 | qml-module-biometryd, |
46 | qml-module-qt-labs-folderlistmodel, |
47 | + qml-module-qt-labs-settings, |
48 | qml-module-qtqml-statemachine, |
49 | qml-module-qtquick-xmllistmodel, |
50 | qml-module-qtsysteminfo, |
51 | |
52 | === modified file 'plugins/Greeter/Unity/Launcher/CMakeLists.txt' |
53 | --- plugins/Greeter/Unity/Launcher/CMakeLists.txt 2016-10-28 12:08:59 +0000 |
54 | +++ plugins/Greeter/Unity/Launcher/CMakeLists.txt 2016-12-06 13:47:05 +0000 |
55 | @@ -1,4 +1,4 @@ |
56 | -pkg_check_modules(LAUNCHER_API REQUIRED unity-shell-launcher=10) |
57 | +pkg_check_modules(LAUNCHER_API REQUIRED unity-shell-launcher=11) |
58 | pkg_check_modules(GSETTINGS_QT REQUIRED gsettings-qt) |
59 | |
60 | add_definitions(-DSM_BUSNAME=systemBus) |
61 | |
62 | === modified file 'plugins/Greeter/Unity/Launcher/launcheritem.cpp' |
63 | --- plugins/Greeter/Unity/Launcher/launcheritem.cpp 2016-05-10 16:23:34 +0000 |
64 | +++ plugins/Greeter/Unity/Launcher/launcheritem.cpp 2016-12-06 13:47:05 +0000 |
65 | @@ -76,6 +76,19 @@ |
66 | } |
67 | } |
68 | |
69 | +QStringList LauncherItem::keywords() const |
70 | +{ |
71 | + return m_keywords; |
72 | +} |
73 | + |
74 | +void LauncherItem::setKeywords(const QStringList &keywords) |
75 | +{ |
76 | + if (m_keywords != keywords) { |
77 | + m_keywords = keywords; |
78 | + Q_EMIT keywordsChanged(keywords); |
79 | + } |
80 | +} |
81 | + |
82 | bool LauncherItem::pinned() const |
83 | { |
84 | return m_pinned; |
85 | |
86 | === modified file 'plugins/Greeter/Unity/Launcher/launcheritem.h' |
87 | --- plugins/Greeter/Unity/Launcher/launcheritem.h 2016-05-10 15:51:00 +0000 |
88 | +++ plugins/Greeter/Unity/Launcher/launcheritem.h 2016-12-06 13:47:05 +0000 |
89 | @@ -34,6 +34,7 @@ |
90 | QString appId() const override; |
91 | QString name() const override; |
92 | QString icon() const override; |
93 | + QStringList keywords() const override; |
94 | bool pinned() const override; |
95 | bool running() const override; |
96 | bool recent() const override; |
97 | @@ -49,6 +50,7 @@ |
98 | private: |
99 | void setName(const QString &name); |
100 | void setIcon(const QString &icon); |
101 | + void setKeywords(const QStringList &keywords); |
102 | void setPinned(bool pinned); |
103 | void setRunning(bool running); |
104 | void setRecent(bool recent); |
105 | @@ -63,6 +65,7 @@ |
106 | QString m_appId; |
107 | QString m_name; |
108 | QString m_icon; |
109 | + QStringList m_keywords; |
110 | bool m_pinned; |
111 | bool m_running; |
112 | bool m_recent; |
113 | |
114 | === modified file 'plugins/Unity/Launcher/CMakeLists.txt' |
115 | --- plugins/Unity/Launcher/CMakeLists.txt 2016-10-28 12:08:59 +0000 |
116 | +++ plugins/Unity/Launcher/CMakeLists.txt 2016-12-06 13:47:05 +0000 |
117 | @@ -1,4 +1,4 @@ |
118 | -pkg_check_modules(LAUNCHER_API REQUIRED unity-shell-launcher=10) |
119 | +pkg_check_modules(LAUNCHER_API REQUIRED unity-shell-launcher=11) |
120 | pkg_check_modules(GSETTINGS_QT REQUIRED gsettings-qt) |
121 | |
122 | add_definitions(-DSM_BUSNAME=systemBus) |
123 | @@ -25,6 +25,8 @@ |
124 | dbusinterface.cpp |
125 | gsettings.cpp |
126 | asadapter.cpp |
127 | + appdrawermodel.cpp |
128 | + ualwrapper.cpp |
129 | ${CMAKE_SOURCE_DIR}/plugins/AccountsService/AccountsServiceDBusAdaptor.cpp |
130 | ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/ApplicationManagerInterface.h |
131 | ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/ApplicationInfoInterface.h |
132 | @@ -32,6 +34,7 @@ |
133 | ${LAUNCHER_API_INCLUDEDIR}/unity/shell/launcher/LauncherItemInterface.h |
134 | ${LAUNCHER_API_INCLUDEDIR}/unity/shell/launcher/LauncherModelInterface.h |
135 | ${LAUNCHER_API_INCLUDEDIR}/unity/shell/launcher/QuickListModelInterface.h |
136 | + ${LAUNCHER_API_INCLUDEDIR}/unity/shell/launcher/AppDrawerModelInterface.h |
137 | ) |
138 | |
139 | add_library(UnityLauncher-qml MODULE |
140 | |
141 | === added file 'plugins/Unity/Launcher/appdrawermodel.cpp' |
142 | --- plugins/Unity/Launcher/appdrawermodel.cpp 1970-01-01 00:00:00 +0000 |
143 | +++ plugins/Unity/Launcher/appdrawermodel.cpp 2016-12-06 13:47:05 +0000 |
144 | @@ -0,0 +1,62 @@ |
145 | +/* |
146 | + * Copyright (C) 2016 Canonical, Ltd. |
147 | + * |
148 | + * This program is free software; you can redistribute it and/or modify |
149 | + * it under the terms of the GNU General Public License as published by |
150 | + * the Free Software Foundation; version 3. |
151 | + * |
152 | + * This program is distributed in the hope that it will be useful, |
153 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
154 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
155 | + * GNU General Public License for more details. |
156 | + * |
157 | + * You should have received a copy of the GNU General Public License |
158 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
159 | + */ |
160 | + |
161 | +#include "appdrawermodel.h" |
162 | +#include "ualwrapper.h" |
163 | + |
164 | +#include <QDebug> |
165 | +#include <QDateTime> |
166 | + |
167 | +AppDrawerModel::AppDrawerModel(QObject *parent): |
168 | + AppDrawerModelInterface(parent) |
169 | +{ |
170 | + Q_FOREACH (const QString &appId, UalWrapper::installedApps()) { |
171 | + UalWrapper::AppInfo info = UalWrapper::getApplicationInfo(appId); |
172 | + if (!info.valid) { |
173 | + qWarning() << "Failed to get app info for app" << appId; |
174 | + continue; |
175 | + } |
176 | + m_list.append(new LauncherItem(appId, info.name, info.icon, this)); |
177 | + m_list.last()->setKeywords(info.keywords); |
178 | + } |
179 | + qsrand(QDateTime::currentMSecsSinceEpoch() / 100); |
180 | +} |
181 | + |
182 | +int AppDrawerModel::rowCount(const QModelIndex &parent) const |
183 | +{ |
184 | + Q_UNUSED(parent) |
185 | + return m_list.count(); |
186 | +} |
187 | + |
188 | +QVariant AppDrawerModel::data(const QModelIndex &index, int role) const |
189 | +{ |
190 | + switch (role) { |
191 | + case RoleAppId: |
192 | + return m_list.at(index.row())->appId(); |
193 | + case RoleName: |
194 | + return m_list.at(index.row())->name(); |
195 | + case RoleIcon: |
196 | + return m_list.at(index.row())->icon(); |
197 | + case RoleKeywords: |
198 | + return m_list.at(index.row())->keywords(); |
199 | + case RoleUsage: |
200 | + // FIXME: u-a-l needs to provide API for usage stats. |
201 | + // don't forget to drop the qsrand() call in the ctor when dropping this. |
202 | + return qrand(); |
203 | + } |
204 | + |
205 | + return QVariant(); |
206 | +} |
207 | |
208 | === added file 'plugins/Unity/Launcher/appdrawermodel.h' |
209 | --- plugins/Unity/Launcher/appdrawermodel.h 1970-01-01 00:00:00 +0000 |
210 | +++ plugins/Unity/Launcher/appdrawermodel.h 2016-12-06 13:47:05 +0000 |
211 | @@ -0,0 +1,33 @@ |
212 | +/* |
213 | + * Copyright (C) 2016 Canonical, Ltd. |
214 | + * |
215 | + * This program is free software; you can redistribute it and/or modify |
216 | + * it under the terms of the GNU General Public License as published by |
217 | + * the Free Software Foundation; version 3. |
218 | + * |
219 | + * This program is distributed in the hope that it will be useful, |
220 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
221 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
222 | + * GNU General Public License for more details. |
223 | + * |
224 | + * You should have received a copy of the GNU General Public License |
225 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
226 | + */ |
227 | + |
228 | + |
229 | +#include <unity/shell/launcher/AppDrawerModelInterface.h> |
230 | + |
231 | +#include "launcheritem.h" |
232 | + |
233 | +class AppDrawerModel: public AppDrawerModelInterface |
234 | +{ |
235 | + Q_OBJECT |
236 | +public: |
237 | + AppDrawerModel(QObject* parent = nullptr); |
238 | + |
239 | + int rowCount(const QModelIndex &parent) const override; |
240 | + QVariant data(const QModelIndex &index, int role) const override; |
241 | + |
242 | +private: |
243 | + QList<LauncherItem*> m_list; |
244 | +}; |
245 | |
246 | === modified file 'plugins/Unity/Launcher/launcheritem.cpp' |
247 | --- plugins/Unity/Launcher/launcheritem.cpp 2016-10-28 11:54:16 +0000 |
248 | +++ plugins/Unity/Launcher/launcheritem.cpp 2016-12-06 13:47:05 +0000 |
249 | @@ -90,6 +90,19 @@ |
250 | } |
251 | } |
252 | |
253 | +QStringList LauncherItem::keywords() const |
254 | +{ |
255 | + return m_keywords; |
256 | +} |
257 | + |
258 | +void LauncherItem::setKeywords(const QStringList &keywords) |
259 | +{ |
260 | + if (m_keywords != keywords) { |
261 | + m_keywords = keywords; |
262 | + Q_EMIT keywordsChanged(keywords); |
263 | + } |
264 | +} |
265 | + |
266 | bool LauncherItem::pinned() const |
267 | { |
268 | return m_pinned; |
269 | |
270 | === modified file 'plugins/Unity/Launcher/launcheritem.h' |
271 | --- plugins/Unity/Launcher/launcheritem.h 2016-05-10 15:51:00 +0000 |
272 | +++ plugins/Unity/Launcher/launcheritem.h 2016-12-06 13:47:05 +0000 |
273 | @@ -37,6 +37,7 @@ |
274 | QString appId() const override; |
275 | QString name() const override; |
276 | QString icon() const override; |
277 | + QStringList keywords() const override; |
278 | bool pinned() const override; |
279 | bool running() const override; |
280 | bool recent() const override; |
281 | @@ -52,6 +53,7 @@ |
282 | private: |
283 | void setName(const QString &name); |
284 | void setIcon(const QString &icon); |
285 | + void setKeywords(const QStringList &keywords); |
286 | void setPinned(bool pinned); |
287 | void setRunning(bool running); |
288 | void setRecent(bool recent); |
289 | @@ -66,6 +68,7 @@ |
290 | QString m_appId; |
291 | QString m_name; |
292 | QString m_icon; |
293 | + QStringList m_keywords; |
294 | bool m_pinned; |
295 | bool m_running; |
296 | bool m_recent; |
297 | @@ -79,6 +82,7 @@ |
298 | QuickListEntry m_quitAction; |
299 | |
300 | friend class LauncherModel; |
301 | + friend class AppDrawerModel; |
302 | }; |
303 | |
304 | #endif // LAUNCHERITEM_H |
305 | |
306 | === modified file 'plugins/Unity/Launcher/launchermodel.cpp' |
307 | --- plugins/Unity/Launcher/launchermodel.cpp 2016-09-23 15:10:26 +0000 |
308 | +++ plugins/Unity/Launcher/launchermodel.cpp 2016-12-06 13:47:05 +0000 |
309 | @@ -19,18 +19,14 @@ |
310 | #include "gsettings.h" |
311 | #include "dbusinterface.h" |
312 | #include "asadapter.h" |
313 | +#include "ualwrapper.h" |
314 | |
315 | -#include <ubuntu-app-launch/appid.h> |
316 | -#include <ubuntu-app-launch/application.h> |
317 | -#include <ubuntu-app-launch/registry.h> |
318 | #include <unity/shell/application/ApplicationInfoInterface.h> |
319 | #include <unity/shell/application/MirSurfaceListInterface.h> |
320 | |
321 | #include <QDesktopServices> |
322 | #include <QDebug> |
323 | |
324 | -namespace ual = ubuntu::app_launch; |
325 | - |
326 | using namespace unity::shell::application; |
327 | |
328 | LauncherModel::LauncherModel(QObject *parent): |
329 | @@ -38,8 +34,7 @@ |
330 | m_settings(new GSettings(this)), |
331 | m_dbusIface(new DBusInterface(this)), |
332 | m_asAdapter(new ASAdapter()), |
333 | - m_appManager(nullptr), |
334 | - m_ualRegistry(std::make_shared<ual::Registry>()) |
335 | + m_appManager(nullptr) |
336 | { |
337 | connect(m_dbusIface, &DBusInterface::countChanged, this, &LauncherModel::countChanged); |
338 | connect(m_dbusIface, &DBusInterface::countVisibleChanged, this, &LauncherModel::countVisibleChanged); |
339 | @@ -159,7 +154,7 @@ |
340 | index = m_list.count(); |
341 | } |
342 | |
343 | - auto appInfo = getApplicationInfo(appId); |
344 | + UalWrapper::AppInfo appInfo = UalWrapper::getApplicationInfo(appId); |
345 | if (!appInfo.valid) { |
346 | qWarning() << "Can't pin application, appId not found:" << appId; |
347 | return; |
348 | @@ -335,32 +330,6 @@ |
349 | return -1; |
350 | } |
351 | |
352 | -LauncherModel::AppInfo LauncherModel::getApplicationInfo(const QString &appId) |
353 | -{ |
354 | - AppInfo info; |
355 | - |
356 | - ual::AppID ualAppId = ual::AppID::find(m_ualRegistry, appId.toStdString()); |
357 | - if (ualAppId.empty()) { |
358 | - return info; |
359 | - } |
360 | - |
361 | - std::shared_ptr<ual::Application> ualApp; |
362 | - try |
363 | - { |
364 | - ualApp = ual::Application::create(ualAppId, m_ualRegistry); |
365 | - } |
366 | - catch (std::runtime_error &e) |
367 | - { |
368 | - qWarning() << "Couldn't find application info for" << appId << "-" << e.what(); |
369 | - return info; |
370 | - } |
371 | - |
372 | - info.valid = true; |
373 | - info.name = QString::fromStdString(ualApp->info()->name()); |
374 | - info.icon = QString::fromStdString(ualApp->info()->iconPath()); |
375 | - return info; |
376 | -} |
377 | - |
378 | void LauncherModel::progressChanged(const QString &appId, int progress) |
379 | { |
380 | const int idx = findApplication(appId); |
381 | @@ -408,7 +377,7 @@ |
382 | } |
383 | } else { |
384 | // Need to create a new LauncherItem and show the highlight |
385 | - auto appInfo = getApplicationInfo(appId); |
386 | + UalWrapper::AppInfo appInfo = UalWrapper::getApplicationInfo(appId); |
387 | if (countVisible && appInfo.valid) { |
388 | LauncherItem *item = new LauncherItem(appId, |
389 | appInfo.name, |
390 | @@ -428,7 +397,7 @@ |
391 | // First walk through all the existing items and see if we need to remove something |
392 | QList<LauncherItem*> toBeRemoved; |
393 | Q_FOREACH (LauncherItem* item, m_list) { |
394 | - auto appInfo = getApplicationInfo(item->appId()); |
395 | + UalWrapper::AppInfo appInfo = UalWrapper::getApplicationInfo(item->appId()); |
396 | if (!appInfo.valid) { |
397 | // Application no longer available => drop it! |
398 | toBeRemoved << item; |
399 | @@ -480,7 +449,7 @@ |
400 | if (itemIndex == -1) { |
401 | // Need to add it. Just add it into the addedIndex to keep same ordering as the list |
402 | // in the settings. |
403 | - auto appInfo = getApplicationInfo(entry); |
404 | + UalWrapper::AppInfo appInfo = UalWrapper::getApplicationInfo(entry); |
405 | if (!appInfo.valid) { |
406 | continue; |
407 | } |
408 | |
409 | === modified file 'plugins/Unity/Launcher/launchermodel.h' |
410 | --- plugins/Unity/Launcher/launchermodel.h 2016-09-23 14:44:26 +0000 |
411 | +++ plugins/Unity/Launcher/launchermodel.h 2016-12-06 13:47:05 +0000 |
412 | @@ -27,12 +27,6 @@ |
413 | class DBusInterface; |
414 | class ASAdapter; |
415 | |
416 | -namespace ubuntu { |
417 | - namespace app_launch { |
418 | - class Registry; |
419 | - } |
420 | -} |
421 | - |
422 | using namespace unity::shell::launcher; |
423 | using namespace unity::shell::application; |
424 | |
425 | @@ -73,13 +67,6 @@ |
426 | |
427 | void unpin(const QString &appId); |
428 | |
429 | - struct AppInfo { |
430 | - bool valid = false; |
431 | - QString name; |
432 | - QString icon; |
433 | - }; |
434 | - AppInfo getApplicationInfo(const QString &appId); |
435 | - |
436 | private Q_SLOTS: |
437 | void countChanged(const QString &appId, int count); |
438 | void countVisibleChanged(const QString &appId, bool count); |
439 | @@ -98,7 +85,6 @@ |
440 | ASAdapter *m_asAdapter; |
441 | |
442 | ApplicationManagerInterface *m_appManager; |
443 | - std::shared_ptr<ubuntu::app_launch::Registry> m_ualRegistry; |
444 | |
445 | friend class LauncherModelTest; |
446 | }; |
447 | |
448 | === modified file 'plugins/Unity/Launcher/plugin.cpp' |
449 | --- plugins/Unity/Launcher/plugin.cpp 2015-09-14 09:11:08 +0000 |
450 | +++ plugins/Unity/Launcher/plugin.cpp 2016-12-06 13:47:05 +0000 |
451 | @@ -26,7 +26,7 @@ |
452 | // local |
453 | #include "launchermodel.h" |
454 | #include "launcheritem.h" |
455 | - |
456 | +#include "appdrawermodel.h" |
457 | |
458 | using namespace unity::shell::launcher; |
459 | |
460 | @@ -46,4 +46,5 @@ |
461 | qmlRegisterSingletonType<LauncherModel>(uri, 0, 1, "LauncherModel", modelProvider); |
462 | qmlRegisterUncreatableType<LauncherItem>(uri, 0, 1, "LauncherItem", QStringLiteral("Can't create new Launcher Items in QML. Get them from the LauncherModel.")); |
463 | qmlRegisterUncreatableType<QuickListModel>(uri, 0, 1, "QuickListModel", QStringLiteral("Can't create a QuickListModel in QML. Get them from the LauncherItems.")); |
464 | + qmlRegisterType<AppDrawerModel>(uri, 0, 1, "AppDrawerModel"); |
465 | } |
466 | |
467 | === added file 'plugins/Unity/Launcher/ualwrapper.cpp' |
468 | --- plugins/Unity/Launcher/ualwrapper.cpp 1970-01-01 00:00:00 +0000 |
469 | +++ plugins/Unity/Launcher/ualwrapper.cpp 2016-12-06 13:47:05 +0000 |
470 | @@ -0,0 +1,73 @@ |
471 | +/* |
472 | + * Copyright (C) 2016 Canonical, Ltd. |
473 | + * |
474 | + * This program is free software; you can redistribute it and/or modify |
475 | + * it under the terms of the GNU General Public License as published by |
476 | + * the Free Software Foundation; version 3. |
477 | + * |
478 | + * This program is distributed in the hope that it will be useful, |
479 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
480 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
481 | + * GNU General Public License for more details. |
482 | + * |
483 | + * You should have received a copy of the GNU General Public License |
484 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
485 | + */ |
486 | + |
487 | +#include <QDebug> |
488 | + |
489 | +#include "ualwrapper.h" |
490 | + |
491 | +#include <ubuntu-app-launch/registry.h> |
492 | +using namespace ubuntu::app_launch; |
493 | + |
494 | +UalWrapper::UalWrapper(QObject *parent): |
495 | + QObject(parent) |
496 | +{ |
497 | + |
498 | +} |
499 | + |
500 | +QStringList UalWrapper::installedApps() |
501 | +{ |
502 | + QStringList appIds; |
503 | + try { |
504 | + for (const std::shared_ptr<Application> &app : Registry::installedApps()) { |
505 | + if (!app->appId().package.value().empty()) { |
506 | + appIds << QString::fromStdString(app->appId().package.value() + "_" + app->appId().appname.value()); |
507 | + } else { |
508 | + appIds << QString::fromStdString(app->appId().appname); |
509 | + } |
510 | + } |
511 | + } catch (const std::runtime_error &e) { |
512 | + qWarning() << "ubuntu-all-launch threw an exception listing apps:" << e.what(); |
513 | + } |
514 | + |
515 | + return appIds; |
516 | +} |
517 | + |
518 | +UalWrapper::AppInfo UalWrapper::getApplicationInfo(const QString &appId) |
519 | +{ |
520 | + AppInfo info; |
521 | + |
522 | + try { |
523 | + AppID ualAppId = AppID::find(appId.toStdString()); |
524 | + if (ualAppId.empty()) { |
525 | + qWarning() << "Empty ualAppId result for" << appId; |
526 | + return info; |
527 | + } |
528 | + |
529 | + std::shared_ptr<Application> ualApp; |
530 | + ualApp = Application::create(ualAppId, Registry::getDefault()); |
531 | + |
532 | + info.name = QString::fromStdString(ualApp->info()->name()); |
533 | + info.icon = QString::fromStdString(ualApp->info()->iconPath()); |
534 | + for (const std::string &keyword : ualApp->info()->keywords().value()) { |
535 | + info.keywords << QString::fromStdString(keyword); |
536 | + } |
537 | + info.valid = true; |
538 | + } catch (const std::runtime_error &e) { |
539 | + qWarning() << "ubuntu-app-launch threw an exception getting app info for appId:" << appId << ":" << e.what(); |
540 | + } |
541 | + |
542 | + return info; |
543 | +} |
544 | |
545 | === added file 'plugins/Unity/Launcher/ualwrapper.h' |
546 | --- plugins/Unity/Launcher/ualwrapper.h 1970-01-01 00:00:00 +0000 |
547 | +++ plugins/Unity/Launcher/ualwrapper.h 2016-12-06 13:47:05 +0000 |
548 | @@ -0,0 +1,35 @@ |
549 | +/* |
550 | + * Copyright (C) 2016 Canonical, Ltd. |
551 | + * |
552 | + * This program is free software; you can redistribute it and/or modify |
553 | + * it under the terms of the GNU General Public License as published by |
554 | + * the Free Software Foundation; version 3. |
555 | + * |
556 | + * This program is distributed in the hope that it will be useful, |
557 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
558 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
559 | + * GNU General Public License for more details. |
560 | + * |
561 | + * You should have received a copy of the GNU General Public License |
562 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
563 | + */ |
564 | + |
565 | +#include <QObject> |
566 | + |
567 | +class UalWrapper: public QObject |
568 | +{ |
569 | + Q_OBJECT |
570 | +public: |
571 | + struct AppInfo { |
572 | + bool valid = false; |
573 | + QString name; |
574 | + QString icon; |
575 | + QStringList keywords; |
576 | + }; |
577 | + |
578 | + UalWrapper(QObject* parent = nullptr); |
579 | + |
580 | + static QStringList installedApps(); |
581 | + static AppInfo getApplicationInfo(const QString &appId); |
582 | + |
583 | +}; |
584 | |
585 | === modified file 'plugins/Utils/CMakeLists.txt' |
586 | --- plugins/Utils/CMakeLists.txt 2016-06-29 18:05:44 +0000 |
587 | +++ plugins/Utils/CMakeLists.txt 2016-12-06 13:47:05 +0000 |
588 | @@ -15,6 +15,10 @@ |
589 | ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/ApplicationManagerInterface.h |
590 | ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/ApplicationInfoInterface.h |
591 | applicationsfiltermodel.cpp |
592 | + ${LAUNCHER_API_INCLUDEDIR}/unity/shell/launcher/AppDrawerModelInterface.h |
593 | + ${LAUNCHER_API_INCLUDEDIR}/unity/shell/launcher/LauncherItemInterface.h |
594 | + ${LAUNCHER_API_INCLUDEDIR}/unity/shell/launcher/LauncherModelInterface.h |
595 | + appdrawerproxymodel.cpp |
596 | constants.cpp |
597 | WindowInputMonitor.cpp |
598 | inputwatcher.cpp |
599 | |
600 | === added file 'plugins/Utils/appdrawerproxymodel.cpp' |
601 | --- plugins/Utils/appdrawerproxymodel.cpp 1970-01-01 00:00:00 +0000 |
602 | +++ plugins/Utils/appdrawerproxymodel.cpp 2016-12-06 13:47:05 +0000 |
603 | @@ -0,0 +1,189 @@ |
604 | +/* |
605 | + * Copyright (C) 2016 Canonical, Ltd. |
606 | + * |
607 | + * This program is free software; you can redistribute it and/or modify |
608 | + * it under the terms of the GNU General Public License as published by |
609 | + * the Free Software Foundation; version 3. |
610 | + * |
611 | + * This program is distributed in the hope that it will be useful, |
612 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
613 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
614 | + * GNU General Public License for more details. |
615 | + * |
616 | + * You should have received a copy of the GNU General Public License |
617 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
618 | + */ |
619 | + |
620 | +#include "appdrawerproxymodel.h" |
621 | + |
622 | +#include <unity/shell/launcher/LauncherItemInterface.h> |
623 | + |
624 | +#include <QDebug> |
625 | + |
626 | +AppDrawerProxyModel::AppDrawerProxyModel(QObject *parent): |
627 | + QSortFilterProxyModel(parent) |
628 | +{ |
629 | + setSortRole(AppDrawerModelInterface::RoleName); |
630 | + setSortLocaleAware(true); |
631 | + sort(0); |
632 | + |
633 | + connect(this, &QAbstractListModel::rowsInserted, this, &AppDrawerProxyModel::countChanged); |
634 | + connect(this, &QAbstractListModel::rowsRemoved, this, &AppDrawerProxyModel::countChanged); |
635 | + connect(this, &QAbstractListModel::layoutChanged, this, &AppDrawerProxyModel::countChanged); |
636 | +} |
637 | + |
638 | +QAbstractItemModel *AppDrawerProxyModel::source() const |
639 | +{ |
640 | + return m_source; |
641 | +} |
642 | + |
643 | +void AppDrawerProxyModel::setSource(QAbstractItemModel *source) |
644 | +{ |
645 | + if (m_source != source) { |
646 | + m_source = source; |
647 | + setSourceModel(m_source); |
648 | + setSortRole(m_sortBy == SortByAToZ ? AppDrawerModelInterface::RoleName : AppDrawerModelInterface::RoleUsage); |
649 | + connect(m_source, &QAbstractItemModel::rowsRemoved, this, &AppDrawerProxyModel::invalidateFilter); |
650 | + connect(m_source, &QAbstractItemModel::rowsInserted, this, &AppDrawerProxyModel::invalidateFilter); |
651 | + Q_EMIT sourceChanged(); |
652 | + } |
653 | +} |
654 | + |
655 | +AppDrawerProxyModel::GroupBy AppDrawerProxyModel::group() const |
656 | +{ |
657 | + return m_group; |
658 | +} |
659 | + |
660 | +void AppDrawerProxyModel::setGroup(AppDrawerProxyModel::GroupBy group) |
661 | +{ |
662 | + if (m_group != group) { |
663 | + m_group = group; |
664 | + Q_EMIT groupChanged(); |
665 | + invalidateFilter(); |
666 | + } |
667 | +} |
668 | + |
669 | +QString AppDrawerProxyModel::filterLetter() const |
670 | +{ |
671 | + return m_filterLetter; |
672 | +} |
673 | + |
674 | +void AppDrawerProxyModel::setFilterLetter(const QString &filterLetter) |
675 | +{ |
676 | + if (m_filterLetter != filterLetter) { |
677 | + m_filterLetter = filterLetter; |
678 | + Q_EMIT filterLetterChanged(); |
679 | + invalidateFilter(); |
680 | + } |
681 | +} |
682 | + |
683 | +QString AppDrawerProxyModel::filterString() const |
684 | +{ |
685 | + return m_filterString; |
686 | +} |
687 | + |
688 | +void AppDrawerProxyModel::setFilterString(const QString &filterString) |
689 | +{ |
690 | + if (m_filterString != filterString) { |
691 | + m_filterString = filterString; |
692 | + Q_EMIT filterStringChanged(); |
693 | + invalidateFilter(); |
694 | + } |
695 | +} |
696 | + |
697 | +AppDrawerProxyModel::SortBy AppDrawerProxyModel::sortBy() const |
698 | +{ |
699 | + return m_sortBy; |
700 | +} |
701 | + |
702 | +void AppDrawerProxyModel::setSortBy(AppDrawerProxyModel::SortBy sortBy) |
703 | +{ |
704 | + if (m_sortBy != sortBy) { |
705 | + m_sortBy = sortBy; |
706 | + Q_EMIT sortByChanged(); |
707 | + setSortRole(m_sortBy == SortByAToZ ? AppDrawerModelInterface::RoleName : AppDrawerModelInterface::RoleUsage); |
708 | + sort(0); |
709 | + } |
710 | +} |
711 | + |
712 | +int AppDrawerProxyModel::count() const |
713 | +{ |
714 | + return rowCount(); |
715 | +} |
716 | + |
717 | +QVariant AppDrawerProxyModel::data(const QModelIndex &index, int role) const |
718 | +{ |
719 | + QModelIndex idx = mapToSource(index); |
720 | + if (role == Qt::UserRole) { |
721 | + QString name = m_source->data(idx, AppDrawerModelInterface::RoleName).toString(); |
722 | + return name.length() > 0 ? QString(name.at(0)).toUpper() : QChar(); |
723 | + } |
724 | + return m_source->data(idx, role); |
725 | +} |
726 | + |
727 | +QHash<int, QByteArray> AppDrawerProxyModel::roleNames() const |
728 | +{ |
729 | + if (m_source) { |
730 | + QHash<int, QByteArray> roles = m_source->roleNames(); |
731 | + roles.insert(Qt::UserRole, "letter"); |
732 | + return roles; |
733 | + } |
734 | + return QHash<int, QByteArray>(); |
735 | +} |
736 | + |
737 | +bool AppDrawerProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const |
738 | +{ |
739 | + Q_UNUSED(source_parent) |
740 | + |
741 | + if (m_group == GroupByAToZ && source_row > 0) { |
742 | + QString currentName = m_source->data(m_source->index(source_row, 0), AppDrawerModelInterface::RoleName).toString(); |
743 | + QChar currentLetter = currentName.length() > 0 ? currentName.at(0) : QChar(); |
744 | + QString previousName = m_source->data(m_source->index(source_row - 1,0 ), AppDrawerModelInterface::RoleName).toString(); |
745 | + QChar previousLetter = previousName.length() > 0 ? previousName.at(0) : QChar(); |
746 | + if (currentLetter.toLower() == previousLetter.toLower()) { |
747 | + return false; |
748 | + } |
749 | + } else if(m_group == GroupByAll && source_row > 0) { |
750 | + return false; |
751 | + } |
752 | + if (!m_filterLetter.isEmpty()) { |
753 | + QString currentName = m_source->data(m_source->index(source_row, 0), AppDrawerModelInterface::RoleName).toString(); |
754 | + QString currentLetter = currentName.length() > 0 ? QString(currentName.at(0)) : QString(); |
755 | + if (currentLetter.toLower() != m_filterLetter.toLower()) { |
756 | + return false; |
757 | + } |
758 | + } |
759 | + if (!m_filterString.isEmpty()) { |
760 | + QStringList allWords = m_source->data(m_source->index(source_row, 0), AppDrawerModelInterface::RoleKeywords).toStringList(); |
761 | + allWords.prepend(m_source->data(m_source->index(source_row, 0), AppDrawerModelInterface::RoleName).toString()); |
762 | + bool found = false; |
763 | + Q_FOREACH (const QString currentWord, allWords) { |
764 | + if (currentWord.toLower().startsWith(m_filterString.toLower())) { |
765 | + found = true; |
766 | + break; |
767 | + } |
768 | + } |
769 | + if (!found) { |
770 | + return false; |
771 | + } |
772 | + } |
773 | + return true; |
774 | +} |
775 | + |
776 | +QString AppDrawerProxyModel::appId(int index) const |
777 | +{ |
778 | + if (index >= 0 && index < rowCount()) { |
779 | + QModelIndex sourceIndex = mapToSource(this->index(index, 0)); |
780 | + |
781 | + AppDrawerModelInterface* adm = dynamic_cast<AppDrawerModelInterface*>(m_source); |
782 | + if (adm) { |
783 | + return adm->data(sourceIndex, AppDrawerModelInterface::RoleAppId).toString(); |
784 | + } |
785 | + |
786 | + AppDrawerProxyModel* adpm = qobject_cast<AppDrawerProxyModel*>(m_source); |
787 | + if (adpm) { |
788 | + return adpm->appId(sourceIndex.row()); |
789 | + } |
790 | + } |
791 | + return nullptr; |
792 | +} |
793 | |
794 | === added file 'plugins/Utils/appdrawerproxymodel.h' |
795 | --- plugins/Utils/appdrawerproxymodel.h 1970-01-01 00:00:00 +0000 |
796 | +++ plugins/Utils/appdrawerproxymodel.h 2016-12-06 13:47:05 +0000 |
797 | @@ -0,0 +1,87 @@ |
798 | +/* |
799 | + * Copyright (C) 2016 Canonical, Ltd. |
800 | + * |
801 | + * This program is free software; you can redistribute it and/or modify |
802 | + * it under the terms of the GNU General Public License as published by |
803 | + * the Free Software Foundation; version 3. |
804 | + * |
805 | + * This program is distributed in the hope that it will be useful, |
806 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
807 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
808 | + * GNU General Public License for more details. |
809 | + * |
810 | + * You should have received a copy of the GNU General Public License |
811 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
812 | + */ |
813 | + |
814 | +#include <QSortFilterProxyModel> |
815 | + |
816 | +#include <unity/shell/launcher/AppDrawerModelInterface.h> |
817 | + |
818 | +using namespace unity::shell::launcher; |
819 | + |
820 | +class AppDrawerProxyModel: public QSortFilterProxyModel |
821 | +{ |
822 | + Q_OBJECT |
823 | + Q_ENUMS(GroupBy) |
824 | + Q_ENUMS(SortBy) |
825 | + Q_PROPERTY(QAbstractItemModel* source READ source WRITE setSource NOTIFY sourceChanged) |
826 | + Q_PROPERTY(GroupBy group READ group WRITE setGroup NOTIFY groupChanged) |
827 | + Q_PROPERTY(QString filterLetter READ filterLetter WRITE setFilterLetter NOTIFY filterLetterChanged) |
828 | + Q_PROPERTY(QString filterString READ filterString WRITE setFilterString NOTIFY filterStringChanged) |
829 | + Q_PROPERTY(SortBy sortBy READ sortBy WRITE setSortBy NOTIFY sortByChanged) |
830 | + Q_PROPERTY(int count READ count NOTIFY countChanged) |
831 | + |
832 | +public: |
833 | + enum GroupBy { |
834 | + GroupByNone, |
835 | + GroupByAll, |
836 | + GroupByAToZ |
837 | + }; |
838 | + enum SortBy { |
839 | + SortByAToZ, |
840 | + SortByUsage |
841 | + }; |
842 | + |
843 | + AppDrawerProxyModel(QObject* parent = nullptr); |
844 | + |
845 | + QAbstractItemModel* source() const; |
846 | + void setSource(QAbstractItemModel* source); |
847 | + |
848 | + GroupBy group() const; |
849 | + void setGroup(GroupBy group); |
850 | + |
851 | + QString filterLetter() const; |
852 | + void setFilterLetter(const QString &filterLetter); |
853 | + |
854 | + QString filterString() const; |
855 | + void setFilterString(const QString &filterString); |
856 | + |
857 | + SortBy sortBy() const; |
858 | + void setSortBy(SortBy sortBy); |
859 | + |
860 | + int count() const; |
861 | + |
862 | + QVariant data(const QModelIndex &index, int role) const override; |
863 | + QHash<int, QByteArray> roleNames() const override; |
864 | + |
865 | + Q_INVOKABLE QString appId(int index) const; |
866 | + |
867 | +protected: |
868 | + bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override; |
869 | + |
870 | +Q_SIGNALS: |
871 | + void sourceChanged(); |
872 | + void groupChanged(); |
873 | + void filterLetterChanged(); |
874 | + void filterStringChanged(); |
875 | + void sortByChanged(); |
876 | + void countChanged(); |
877 | + |
878 | +private: |
879 | + QAbstractItemModel* m_source = nullptr; |
880 | + GroupBy m_group = GroupByNone; |
881 | + QString m_filterLetter; |
882 | + QString m_filterString; |
883 | + SortBy m_sortBy = SortByAToZ; |
884 | +}; |
885 | |
886 | === modified file 'plugins/Utils/plugin.cpp' |
887 | --- plugins/Utils/plugin.cpp 2016-06-28 20:38:00 +0000 |
888 | +++ plugins/Utils/plugin.cpp 2016-12-06 13:47:05 +0000 |
889 | @@ -39,6 +39,7 @@ |
890 | #include "deviceconfigparser.h" |
891 | #include "globalfunctions.h" |
892 | #include "URLDispatcher.h" |
893 | +#include "appdrawerproxymodel.h" |
894 | |
895 | static QObject *createWindowStateStorage(QQmlEngine *engine, QJSEngine *scriptEngine) |
896 | { |
897 | @@ -82,4 +83,5 @@ |
898 | qmlRegisterType<DeviceConfigParser>(uri, 0, 1, "DeviceConfigParser"); |
899 | qmlRegisterSingletonType<GlobalFunctions>(uri, 0, 1, "Functions", createGlobalFunctions); |
900 | qmlRegisterType<URLDispatcher>(uri, 0, 1, "URLDispatcher"); |
901 | + qmlRegisterType<AppDrawerProxyModel>(uri, 0, 1, "AppDrawerProxyModel"); |
902 | } |
903 | |
904 | === modified file 'qml/Components/KeyboardShortcutsOverlay.qml' |
905 | --- qml/Components/KeyboardShortcutsOverlay.qml 2016-05-11 11:09:42 +0000 |
906 | +++ qml/Components/KeyboardShortcutsOverlay.qml 2016-12-06 13:47:05 +0000 |
907 | @@ -173,6 +173,19 @@ |
908 | Layout.maximumWidth: maxTextSize |
909 | } |
910 | |
911 | + Label { |
912 | + text: i18n.tr("Super + A") |
913 | + fontSize: "small" |
914 | + font.weight: Font.Medium |
915 | + } |
916 | + Label { |
917 | + text: i18n.tr("Opens the Application Drawer.") |
918 | + fontSize: "small" |
919 | + font.weight: Font.Light |
920 | + wrapMode: Text.Wrap |
921 | + Layout.maximumWidth: maxTextSize |
922 | + } |
923 | + |
924 | |
925 | // Scopes section |
926 | Item { Layout.columnSpan: 2; height: units.gu(2) } |
927 | |
928 | === added file 'qml/Launcher/BackgroundBlur.qml' |
929 | --- qml/Launcher/BackgroundBlur.qml 1970-01-01 00:00:00 +0000 |
930 | +++ qml/Launcher/BackgroundBlur.qml 2016-12-06 13:47:05 +0000 |
931 | @@ -0,0 +1,81 @@ |
932 | +/* |
933 | + * Copyright (C) 2016 Canonical, Ltd. |
934 | + * |
935 | + * This program is free software; you can redistribute it and/or modify |
936 | + * it under the terms of the GNU General Public License as published by |
937 | + * the Free Software Foundation; version 3. |
938 | + * |
939 | + * This program is distributed in the hope that it will be useful, |
940 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
941 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
942 | + * GNU General Public License for more details. |
943 | + * |
944 | + * You should have received a copy of the GNU General Public License |
945 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
946 | + */ |
947 | + |
948 | +import QtQuick 2.4 |
949 | +import Ubuntu.Components 1.3 |
950 | +import QtGraphicalEffects 1.0 |
951 | + |
952 | +Item { |
953 | + id: root |
954 | + |
955 | + property int blurAmount: 32 |
956 | + property Item sourceItem |
957 | + property rect blurRect: Qt.rect(0,0,0,0) |
958 | + property alias cached: fastBlur.cached |
959 | + |
960 | + Rectangle { |
961 | + id: blurMask |
962 | + color: "yellow" |
963 | + x: blurRect.x |
964 | + y: blurRect.y |
965 | + width: blurRect.width |
966 | + height: blurRect.height |
967 | + } |
968 | + |
969 | + ShaderEffect { |
970 | + id: maskedBlurEffect |
971 | + x: blurRect.x |
972 | + y: blurRect.y |
973 | + width: blurRect.width |
974 | + height: blurRect.height |
975 | + |
976 | + property variant source: ShaderEffectSource { |
977 | + id: shaderEffectSource |
978 | + sourceItem: root.sourceItem |
979 | + hideSource: false |
980 | + sourceRect: root.blurRect |
981 | + } |
982 | + |
983 | + property var mask: ShaderEffectSource { |
984 | + sourceItem: blurMask |
985 | + hideSource: true |
986 | + } |
987 | + |
988 | + fragmentShader: " |
989 | + varying highp vec2 qt_TexCoord0; |
990 | + uniform sampler2D source; |
991 | + uniform sampler2D mask; |
992 | + void main(void) |
993 | + { |
994 | + highp vec4 sourceColor = texture2D(source, qt_TexCoord0); |
995 | + highp vec4 maskColor = texture2D(mask, qt_TexCoord0); |
996 | + |
997 | + sourceColor *= maskColor.a; |
998 | + |
999 | + gl_FragColor = sourceColor; |
1000 | + }" |
1001 | + } |
1002 | + |
1003 | + FastBlur { |
1004 | + id: fastBlur |
1005 | + x: blurRect.x |
1006 | + y: blurRect.y |
1007 | + width: blurRect.width |
1008 | + height: blurRect.height |
1009 | + source: maskedBlurEffect |
1010 | + radius: Math.min(blurAmount, 128) |
1011 | + } |
1012 | + } |
1013 | |
1014 | === added file 'qml/Launcher/Drawer.qml' |
1015 | --- qml/Launcher/Drawer.qml 1970-01-01 00:00:00 +0000 |
1016 | +++ qml/Launcher/Drawer.qml 2016-12-06 13:47:05 +0000 |
1017 | @@ -0,0 +1,306 @@ |
1018 | +/* |
1019 | + * Copyright (C) 2016 Canonical, Ltd. |
1020 | + * |
1021 | + * This program is free software; you can redistribute it and/or modify |
1022 | + * it under the terms of the GNU General Public License as published by |
1023 | + * the Free Software Foundation; version 3. |
1024 | + * |
1025 | + * This program is distributed in the hope that it will be useful, |
1026 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1027 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1028 | + * GNU General Public License for more details. |
1029 | + * |
1030 | + * You should have received a copy of the GNU General Public License |
1031 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1032 | + */ |
1033 | + |
1034 | +import QtQuick 2.4 |
1035 | +import Ubuntu.Components 1.3 |
1036 | +import Unity.Launcher 0.1 |
1037 | +import Utils 0.1 |
1038 | +import "../Components" |
1039 | +import Qt.labs.settings 1.0 |
1040 | + |
1041 | +FocusScope { |
1042 | + id: root |
1043 | + |
1044 | + property int panelWidth: 0 |
1045 | + readonly property bool moving: listLoader.item && listLoader.item.moving |
1046 | + |
1047 | + signal applicationSelected(string appId) |
1048 | + |
1049 | + property bool draggingHorizontally: false |
1050 | + property int dragDistance: 0 |
1051 | + |
1052 | + onFocusChanged: { |
1053 | + if (focus) { |
1054 | + searchField.selectAll(); |
1055 | + } |
1056 | + } |
1057 | + |
1058 | + function focusInput() { |
1059 | + searchField.selectAll(); |
1060 | + searchField.focus = true; |
1061 | + } |
1062 | + |
1063 | + Settings { |
1064 | + property alias selectedTab: sections.selectedIndex |
1065 | + } |
1066 | + |
1067 | + MouseArea { |
1068 | + anchors.fill: parent |
1069 | + hoverEnabled: true |
1070 | + acceptedButtons: Qt.AllButtons |
1071 | + onWheel: wheel.accepted = true |
1072 | + } |
1073 | + |
1074 | + Rectangle { |
1075 | + anchors.fill: parent |
1076 | + color: "#BF000000" |
1077 | + |
1078 | + AppDrawerModel { |
1079 | + id: appDrawerModel |
1080 | + } |
1081 | + |
1082 | + AppDrawerProxyModel { |
1083 | + id: sortProxyModel |
1084 | + source: appDrawerModel |
1085 | + filterString: searchField.displayText |
1086 | + sortBy: AppDrawerProxyModel.SortByAToZ |
1087 | + } |
1088 | + |
1089 | + Item { |
1090 | + id: contentContainer |
1091 | + anchors.fill: parent |
1092 | + anchors.leftMargin: root.panelWidth |
1093 | + |
1094 | + TextField { |
1095 | + id: searchField |
1096 | + anchors { left: parent.left; top: parent.top; right: parent.right; margins: units.gu(1) } |
1097 | + placeholderText: i18n.tr("Search…") |
1098 | + focus: true |
1099 | + onAccepted: { |
1100 | + if (searchField.displayText != "" && listLoader.item && listLoader.item.currentItem) { |
1101 | + root.applicationSelected(listLoader.item.getFirstAppId()); |
1102 | + } |
1103 | + } |
1104 | + } |
1105 | + |
1106 | + Item { |
1107 | + id: sectionsContainer |
1108 | + anchors { left: parent.left; top: searchField.bottom; right: parent.right; } |
1109 | + height: sections.height |
1110 | + clip: true |
1111 | + z: 2 |
1112 | + |
1113 | + Sections { |
1114 | + id: sections |
1115 | + width: parent.width |
1116 | + actions: [ |
1117 | + Action { |
1118 | + text: i18n.ctr("Apps sorted alphabetically", "A-Z") |
1119 | + // TODO: Disabling this for now as we don't get the right input from u-a-l yet. |
1120 | +// }, |
1121 | +// Action { |
1122 | +// text: i18n.ctr("Most used apps", "Most used") |
1123 | + } |
1124 | + ] |
1125 | + |
1126 | + Rectangle { |
1127 | + anchors.bottom: parent.bottom |
1128 | + height: units.dp(1) |
1129 | + color: 'gray' |
1130 | + width: contentContainer.width |
1131 | + } |
1132 | + } |
1133 | + } |
1134 | + |
1135 | + Loader { |
1136 | + id: listLoader |
1137 | + anchors { left: parent.left; top: sectionsContainer.bottom; right: parent.right; bottom: parent.bottom; leftMargin: units.gu(1); rightMargin: units.gu(1) } |
1138 | + sourceComponent: { |
1139 | + switch (sections.selectedIndex) { |
1140 | + case 0: return aToZComponent; |
1141 | + case 1: return mostUsedComponent; |
1142 | + } |
1143 | + } |
1144 | + Binding { |
1145 | + target: listLoader.item || null |
1146 | + property: "objectName" |
1147 | + value: "drawerItemList" |
1148 | + } |
1149 | + } |
1150 | + |
1151 | + MouseArea { |
1152 | + parent: listLoader.item ? listLoader.item : null |
1153 | + anchors.fill: parent |
1154 | + propagateComposedEvents: true |
1155 | + property int oldX: 0 |
1156 | + onPressed: { |
1157 | + oldX = mouseX; |
1158 | + } |
1159 | + onMouseXChanged: { |
1160 | + var diff = oldX - mouseX; |
1161 | + root.draggingHorizontally |= diff > units.gu(2); |
1162 | + if (!root.draggingHorizontally) { |
1163 | + return; |
1164 | + } |
1165 | + propagateComposedEvents = false; |
1166 | + parent.interactive = false; |
1167 | + root.dragDistance += diff; |
1168 | + oldX = mouseX |
1169 | + } |
1170 | + onReleased: { |
1171 | + if (root.draggingHorizontally) { |
1172 | + root.draggingHorizontally = false; |
1173 | + parent.interactive = true; |
1174 | + } |
1175 | + reactivateTimer.start(); |
1176 | + } |
1177 | + Timer { |
1178 | + id: reactivateTimer |
1179 | + interval: 0 |
1180 | + onTriggered: parent.propagateComposedEvents = true; |
1181 | + } |
1182 | + } |
1183 | + |
1184 | + Component { |
1185 | + id: mostUsedComponent |
1186 | + DrawerListView { |
1187 | + |
1188 | + header: MoreAppsHeader { |
1189 | + width: parent.width |
1190 | + height: units.gu(6) |
1191 | + } |
1192 | + |
1193 | + model: AppDrawerProxyModel { |
1194 | + source: sortProxyModel |
1195 | + group: AppDrawerProxyModel.GroupByAll |
1196 | + sortBy: AppDrawerProxyModel.SortByUsage |
1197 | + } |
1198 | + |
1199 | + delegate: UbuntuShape { |
1200 | + width: parent.width |
1201 | + color: "#20ffffff" |
1202 | + aspect: UbuntuShape.Flat |
1203 | + // NOTE: Cannot use gridView.rows here as it would evaluate to 0 at first and only update later, |
1204 | + // which messes up the ListView. |
1205 | + height: (Math.ceil(mostUsedGridView.model.count / mostUsedGridView.columns) * mostUsedGridView.delegateHeight) + units.gu(2) |
1206 | + |
1207 | + readonly property string appId: model.appId |
1208 | + |
1209 | + DrawerGridView { |
1210 | + id: mostUsedGridView |
1211 | + anchors.fill: parent |
1212 | + topMargin: units.gu(1) |
1213 | + bottomMargin: units.gu(1) |
1214 | + clip: true |
1215 | + |
1216 | + model: sortProxyModel |
1217 | + |
1218 | + delegateWidth: units.gu(8) |
1219 | + delegateHeight: units.gu(10) |
1220 | + delegate: drawerDelegateComponent |
1221 | + } |
1222 | + } |
1223 | + } |
1224 | + } |
1225 | + |
1226 | + Component { |
1227 | + id: aToZComponent |
1228 | + DrawerListView { |
1229 | + |
1230 | + header: MoreAppsHeader { |
1231 | + width: parent.width |
1232 | + height: units.gu(6) |
1233 | + } |
1234 | + |
1235 | + model: AppDrawerProxyModel { |
1236 | + source: sortProxyModel |
1237 | + sortBy: AppDrawerProxyModel.SortByAToZ |
1238 | + group: AppDrawerProxyModel.GroupByAToZ |
1239 | + } |
1240 | + |
1241 | + delegate: UbuntuShape { |
1242 | + width: parent.width |
1243 | + color: "#20ffffff" |
1244 | + aspect: UbuntuShape.Flat |
1245 | + |
1246 | + readonly property string appId: model.appId |
1247 | + |
1248 | + // NOTE: Cannot use gridView.rows here as it would evaluate to 0 at first and only update later, |
1249 | + // which messes up the ListView. |
1250 | + height: (Math.ceil(gridView.model.count / gridView.columns) * gridView.delegateHeight) + |
1251 | + categoryNameLabel.implicitHeight + units.gu(2) |
1252 | + |
1253 | + Label { |
1254 | + id: categoryNameLabel |
1255 | + anchors { left: parent.left; top: parent.top; right: parent.right; margins: units.gu(1) } |
1256 | + text: model.letter |
1257 | + } |
1258 | + |
1259 | + DrawerGridView { |
1260 | + id: gridView |
1261 | + anchors { left: parent.left; top: categoryNameLabel.bottom; right: parent.right; topMargin: units.gu(1) } |
1262 | + height: rows * delegateHeight |
1263 | + |
1264 | + interactive: false |
1265 | + |
1266 | + model: AppDrawerProxyModel { |
1267 | + id: categoryModel |
1268 | + source: sortProxyModel |
1269 | + filterLetter: model.letter |
1270 | + } |
1271 | + delegateWidth: units.gu(8) |
1272 | + delegateHeight: units.gu(10) |
1273 | + delegate: drawerDelegateComponent |
1274 | + } |
1275 | + } |
1276 | + } |
1277 | + } |
1278 | + } |
1279 | + |
1280 | + Component { |
1281 | + id: drawerDelegateComponent |
1282 | + AbstractButton { |
1283 | + width: GridView.view.cellWidth |
1284 | + height: units.gu(10) |
1285 | + objectName: "drawerItem_" + model.appId |
1286 | + |
1287 | + onClicked: root.applicationSelected(model.appId) |
1288 | + |
1289 | + Column { |
1290 | + width: units.gu(8) |
1291 | + anchors.horizontalCenter: parent.horizontalCenter |
1292 | + height: childrenRect.height |
1293 | + spacing: units.gu(1) |
1294 | + |
1295 | + UbuntuShape { |
1296 | + id: appIcon |
1297 | + width: units.gu(6) |
1298 | + height: 7.5 / 8 * width |
1299 | + anchors.horizontalCenter: parent.horizontalCenter |
1300 | + backgroundMode: UbuntuShape.SolidColor |
1301 | + backgroundColor: UbuntuColors.lightGrey |
1302 | + radius: "medium" |
1303 | + borderSource: 'undefined' |
1304 | + source: Image { |
1305 | + id: sourceImage |
1306 | + sourceSize.width: appIcon.width |
1307 | + source: model.icon |
1308 | + } |
1309 | + sourceFillMode: UbuntuShape.PreserveAspectCrop |
1310 | + } |
1311 | + |
1312 | + Label { |
1313 | + text: model.name |
1314 | + width: parent.width |
1315 | + horizontalAlignment: Text.AlignHCenter |
1316 | + fontSize: "small" |
1317 | + elide: Text.ElideRight |
1318 | + } |
1319 | + } |
1320 | + } |
1321 | + } |
1322 | + } |
1323 | +} |
1324 | |
1325 | === added file 'qml/Launcher/DrawerGridView.qml' |
1326 | --- qml/Launcher/DrawerGridView.qml 1970-01-01 00:00:00 +0000 |
1327 | +++ qml/Launcher/DrawerGridView.qml 2016-12-06 13:47:05 +0000 |
1328 | @@ -0,0 +1,47 @@ |
1329 | +/* |
1330 | + * Copyright (C) 2016 Canonical, Ltd. |
1331 | + * |
1332 | + * This program is free software; you can redistribute it and/or modify |
1333 | + * it under the terms of the GNU General Public License as published by |
1334 | + * the Free Software Foundation; version 3. |
1335 | + * |
1336 | + * This program is distributed in the hope that it will be useful, |
1337 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1338 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1339 | + * GNU General Public License for more details. |
1340 | + * |
1341 | + * You should have received a copy of the GNU General Public License |
1342 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1343 | + */ |
1344 | + |
1345 | +import QtQuick 2.4 |
1346 | +import "../Components" |
1347 | + |
1348 | +Item { |
1349 | + id: root |
1350 | + |
1351 | + property int delegateWidth: units.gu(10) |
1352 | + property int delegateHeight: units.gu(10) |
1353 | + property alias delegate: gridView.delegate |
1354 | + property alias model: gridView.model |
1355 | + property alias interactive: gridView.interactive |
1356 | + |
1357 | + property alias header: gridView.header |
1358 | + property alias topMargin: gridView.topMargin |
1359 | + property alias bottomMargin: gridView.bottomMargin |
1360 | + |
1361 | + readonly property int columns: width / delegateWidth |
1362 | + readonly property int rows: Math.ceil(gridView.model.count / root.columns) |
1363 | + |
1364 | + GridView { |
1365 | + id: gridView |
1366 | + anchors.fill: parent |
1367 | + leftMargin: spacing |
1368 | + |
1369 | + readonly property int overflow: width - (root.columns * root.delegateWidth) |
1370 | + readonly property real spacing: overflow / (root.columns) |
1371 | + |
1372 | + cellWidth: root.delegateWidth + spacing |
1373 | + cellHeight: root.delegateHeight |
1374 | + } |
1375 | +} |
1376 | |
1377 | === added file 'qml/Launcher/DrawerListView.qml' |
1378 | --- qml/Launcher/DrawerListView.qml 1970-01-01 00:00:00 +0000 |
1379 | +++ qml/Launcher/DrawerListView.qml 2016-12-06 13:47:05 +0000 |
1380 | @@ -0,0 +1,32 @@ |
1381 | +/* |
1382 | + * Copyright (C) 2016 Canonical, Ltd. |
1383 | + * |
1384 | + * This program is free software; you can redistribute it and/or modify |
1385 | + * it under the terms of the GNU General Public License as published by |
1386 | + * the Free Software Foundation; version 3. |
1387 | + * |
1388 | + * This program is distributed in the hope that it will be useful, |
1389 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1390 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1391 | + * GNU General Public License for more details. |
1392 | + * |
1393 | + * You should have received a copy of the GNU General Public License |
1394 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1395 | + */ |
1396 | + |
1397 | +import QtQuick 2.4 |
1398 | +import Ubuntu.Components 1.3 |
1399 | +import "../Components" |
1400 | + |
1401 | +ListView { |
1402 | + id: root |
1403 | + anchors.fill: parent |
1404 | + topMargin: units.gu(1) |
1405 | + bottomMargin: units.gu(1) |
1406 | + spacing: units.gu(1) |
1407 | + clip: true |
1408 | + |
1409 | + function getFirstAppId() { |
1410 | + return model.appId(0); |
1411 | + } |
1412 | +} |
1413 | |
1414 | === modified file 'qml/Launcher/Launcher.qml' |
1415 | --- qml/Launcher/Launcher.qml 2016-09-22 10:14:18 +0000 |
1416 | +++ qml/Launcher/Launcher.qml 2016-12-06 13:47:05 +0000 |
1417 | @@ -27,10 +27,12 @@ |
1418 | property bool lockedVisible: false |
1419 | property bool available: true // can be used to disable all interactions |
1420 | property alias inverted: panel.inverted |
1421 | + property Item blurSource: null |
1422 | + property int topPanelHeight: 0 |
1423 | + property bool drawerEnabled: true |
1424 | |
1425 | property int panelWidth: units.gu(10) |
1426 | property int dragAreaWidth: units.gu(1) |
1427 | - property int minimizeDistance: units.gu(26) |
1428 | property real progress: dragArea.dragging && dragArea.touchPosition.x > panelWidth ? |
1429 | (width * (dragArea.touchPosition.x-panelWidth) / (width - panelWidth)) : 0 |
1430 | |
1431 | @@ -43,13 +45,11 @@ |
1432 | readonly property alias shortcutHintsShown: panel.shortcutHintsShown |
1433 | |
1434 | readonly property bool shown: panel.x > -panel.width |
1435 | + readonly property bool drawerShown: drawer.x == 0 |
1436 | |
1437 | // emitted when an application is selected |
1438 | signal launcherApplicationSelected(string appId) |
1439 | |
1440 | - // emitted when the apps dash should be shown because of a swipe gesture |
1441 | - signal dash() |
1442 | - |
1443 | // emitted when the dash icon in the launcher has been tapped |
1444 | signal showDashHome() |
1445 | |
1446 | @@ -62,6 +62,9 @@ |
1447 | } |
1448 | |
1449 | onSuperPressedChanged: { |
1450 | + if (state == "drawer") |
1451 | + return; |
1452 | + |
1453 | if (superPressed) { |
1454 | superPressTimer.start(); |
1455 | superLongPressTimer.start(); |
1456 | @@ -132,7 +135,7 @@ |
1457 | } |
1458 | |
1459 | function pushEdge(amount) { |
1460 | - if (root.state === "") { |
1461 | + if (root.state === "" || root.state == "visible" || root.state == "visibleTemporary") { |
1462 | edgeBarrier.push(amount); |
1463 | } |
1464 | } |
1465 | @@ -143,6 +146,22 @@ |
1466 | switchToNextState("visible") |
1467 | } |
1468 | |
1469 | + function openDrawer(focusInputField) { |
1470 | + if (!drawerEnabled) { |
1471 | + return; |
1472 | + } |
1473 | + |
1474 | + panel.shortcutHintsShown = false; |
1475 | + superPressTimer.stop(); |
1476 | + superLongPressTimer.stop(); |
1477 | + root.focus = true; |
1478 | + drawer.focus = true; |
1479 | + if (focusInputField) { |
1480 | + drawer.focusInput(); |
1481 | + } |
1482 | + switchToNextState("drawer") |
1483 | + } |
1484 | + |
1485 | Keys.onPressed: { |
1486 | switch (event.key) { |
1487 | case Qt.Key_Backtab: |
1488 | @@ -278,7 +297,7 @@ |
1489 | InverseMouseArea { |
1490 | id: closeMouseArea |
1491 | anchors.fill: panel |
1492 | - enabled: root.state == "visible" && (!root.lockedVisible || panel.highlightIndex >= -1) |
1493 | + enabled: root.state == "visible" || root.state == "drawer" |
1494 | visible: enabled |
1495 | onPressed: { |
1496 | mouse.accepted = false; |
1497 | @@ -307,23 +326,61 @@ |
1498 | } |
1499 | } |
1500 | |
1501 | - EdgeBarrier { |
1502 | - id: edgeBarrier |
1503 | - edge: Qt.LeftEdge |
1504 | - target: parent |
1505 | - enabled: root.available |
1506 | - onPassed: { root.switchToNextState("visibleTemporary"); } |
1507 | - material: Component { |
1508 | - Item { |
1509 | - Rectangle { |
1510 | - width: parent.height |
1511 | - height: parent.width |
1512 | - rotation: -90 |
1513 | - anchors.centerIn: parent |
1514 | - gradient: Gradient { |
1515 | - GradientStop { position: 0.0; color: Qt.rgba(panel.color.r, panel.color.g, panel.color.b, .5)} |
1516 | - GradientStop { position: 1.0; color: Qt.rgba(panel.color.r,panel.color.g,panel.color.b,0)} |
1517 | - } |
1518 | + BackgroundBlur { |
1519 | + id: backgroundBlur |
1520 | + anchors.fill: parent |
1521 | + anchors.topMargin: root.inverted ? 0 : -root.topPanelHeight |
1522 | + visible: root.blurSource && drawer.x > -drawer.width |
1523 | + blurAmount: units.gu(6) |
1524 | + sourceItem: root.blurSource |
1525 | + blurRect: Qt.rect(panel.width, |
1526 | + root.topPanelHeight, |
1527 | + drawer.width + drawer.x - panel.width, |
1528 | + height - root.topPanelHeight) |
1529 | + cached: drawer.moving |
1530 | + } |
1531 | + |
1532 | + Drawer { |
1533 | + id: drawer |
1534 | + objectName: "drawer" |
1535 | + anchors { |
1536 | + top: parent.top |
1537 | + topMargin: root.inverted ? root.topPanelHeight : 0 |
1538 | + bottom: parent.bottom |
1539 | + right: parent.left |
1540 | + } |
1541 | + width: Math.min(root.width, units.gu(90)) * .9 |
1542 | + panelWidth: panel.width |
1543 | + visible: x > -width |
1544 | + |
1545 | + Behavior on anchors.rightMargin { |
1546 | + enabled: !dragArea.dragging && !launcherDragArea.drag.active && panel.animate && !drawer.draggingHorizontally |
1547 | + NumberAnimation { |
1548 | + duration: 300 |
1549 | + easing.type: Easing.OutCubic |
1550 | + } |
1551 | + } |
1552 | + |
1553 | + onApplicationSelected: { |
1554 | + root.hide(); |
1555 | + root.launcherApplicationSelected(appId) |
1556 | + root.focus = false; |
1557 | + } |
1558 | + |
1559 | + Keys.onEscapePressed: { |
1560 | + switchToNextState(""); |
1561 | + root.focus = false; |
1562 | + } |
1563 | + |
1564 | + onDragDistanceChanged: { |
1565 | + anchors.rightMargin = Math.max(-drawer.width, anchors.rightMargin + dragDistance); |
1566 | + } |
1567 | + onDraggingHorizontallyChanged: { |
1568 | + if (!draggingHorizontally) { |
1569 | + if (drawer.x < -units.gu(10)) { |
1570 | + root.hide(); |
1571 | + } else { |
1572 | + root.openDrawer(); |
1573 | } |
1574 | } |
1575 | } |
1576 | @@ -332,7 +389,7 @@ |
1577 | LauncherPanel { |
1578 | id: panel |
1579 | objectName: "launcherPanel" |
1580 | - enabled: root.available && root.state == "visible" || root.state == "visibleTemporary" |
1581 | + enabled: root.available && (root.state == "visible" || root.state == "visibleTemporary" || root.state == "drawer") |
1582 | width: root.panelWidth |
1583 | anchors { |
1584 | top: parent.top |
1585 | @@ -394,6 +451,38 @@ |
1586 | } |
1587 | } |
1588 | |
1589 | + EdgeBarrier { |
1590 | + id: edgeBarrier |
1591 | + edge: Qt.LeftEdge |
1592 | + target: parent |
1593 | + enabled: root.available |
1594 | + onProgressChanged: { |
1595 | + if (progress > .5 && root.state != "visibleTemporary" && root.state != "drawer" && root.state != "visible") { |
1596 | + root.switchToNextState("visibleTemporary"); |
1597 | + } |
1598 | + } |
1599 | + onPassed: { |
1600 | + if (root.drawerEnabled) { |
1601 | + root.switchToNextState("drawer"); |
1602 | + } |
1603 | + } |
1604 | + |
1605 | + material: Component { |
1606 | + Item { |
1607 | + Rectangle { |
1608 | + width: parent.height |
1609 | + height: parent.width |
1610 | + rotation: -90 |
1611 | + anchors.centerIn: parent |
1612 | + gradient: Gradient { |
1613 | + GradientStop { position: 0.0; color: Qt.rgba(panel.color.r, panel.color.g, panel.color.b, .5)} |
1614 | + GradientStop { position: 1.0; color: Qt.rgba(panel.color.r,panel.color.g,panel.color.b,0)} |
1615 | + } |
1616 | + } |
1617 | + } |
1618 | + } |
1619 | + } |
1620 | + |
1621 | SwipeArea { |
1622 | id: dragArea |
1623 | objectName: "launcherDragArea" |
1624 | @@ -405,25 +494,62 @@ |
1625 | width: root.dragAreaWidth |
1626 | height: root.height |
1627 | |
1628 | + function easeInOutCubic(t) { return t<.5 ? 4*t*t*t : (t-1)*(2*t-2)*(2*t-2)+1 } |
1629 | + |
1630 | + property var lastDragPoints: [] |
1631 | + |
1632 | + function dragDirection() { |
1633 | + if (lastDragPoints.length < 5) { |
1634 | + return "unknown"; |
1635 | + } |
1636 | + |
1637 | + var toRight = true; |
1638 | + var toLeft = true; |
1639 | + for (var i = lastDragPoints.length - 5; i < lastDragPoints.length; i++) { |
1640 | + if (toRight && lastDragPoints[i] < lastDragPoints[i-1]) { |
1641 | + toRight = false; |
1642 | + } |
1643 | + if (toLeft && lastDragPoints[i] > lastDragPoints[i-1]) { |
1644 | + toLeft = false; |
1645 | + } |
1646 | + } |
1647 | + return toRight ? "right" : toLeft ? "left" : "unknown"; |
1648 | + } |
1649 | + |
1650 | onDistanceChanged: { |
1651 | - if (!dragging || launcher.state == "visible") |
1652 | - return; |
1653 | + if (dragging && launcher.state != "visible" && launcher.state != "drawer") { |
1654 | + panel.x = -panel.width + Math.min(Math.max(0, distance), panel.width); |
1655 | + } |
1656 | |
1657 | - panel.x = -panel.width + Math.min(Math.max(0, distance), panel.width); |
1658 | + if (root.drawerEnabled && dragging && launcher.state != "drawer") { |
1659 | + lastDragPoints.push(distance) |
1660 | + var drawerHintDistance = panel.width + units.gu(1) |
1661 | + if (distance < drawerHintDistance) { |
1662 | + drawer.anchors.rightMargin = -Math.min(Math.max(0, distance), drawer.width); |
1663 | + } else { |
1664 | + var linearDrawerX = Math.min(Math.max(0, distance - drawerHintDistance), drawer.width); |
1665 | + var linearDrawerProgress = linearDrawerX / (drawer.width) |
1666 | + var easedDrawerProgress = easeInOutCubic(linearDrawerProgress); |
1667 | + drawer.anchors.rightMargin = -(drawerHintDistance + easedDrawerProgress * (drawer.width - drawerHintDistance)); |
1668 | + } |
1669 | + } |
1670 | } |
1671 | |
1672 | onDraggingChanged: { |
1673 | if (!dragging) { |
1674 | if (distance > panel.width / 2) { |
1675 | - root.switchToNextState("visible") |
1676 | - if (distance > minimizeDistance) { |
1677 | - root.dash(); |
1678 | + if (root.drawerEnabled && distance > panel.width * 3 && dragDirection() !== "left") { |
1679 | + root.switchToNextState("drawer"); |
1680 | + root.focus = true; |
1681 | + } else { |
1682 | + root.switchToNextState("visible"); |
1683 | } |
1684 | } else if (root.state === "") { |
1685 | // didn't drag far enough. rollback |
1686 | - root.switchToNextState("") |
1687 | + root.switchToNextState(""); |
1688 | } |
1689 | } |
1690 | + lastDragPoints = []; |
1691 | } |
1692 | } |
1693 | |
1694 | @@ -434,6 +560,10 @@ |
1695 | target: panel |
1696 | x: -root.panelWidth |
1697 | } |
1698 | + PropertyChanges { |
1699 | + target: drawer |
1700 | + anchors.rightMargin: 0 |
1701 | + } |
1702 | }, |
1703 | State { |
1704 | name: "visible" |
1705 | @@ -441,6 +571,18 @@ |
1706 | target: panel |
1707 | x: -root.x // so we never go past panelWidth, even when teased by tutorial |
1708 | } |
1709 | + PropertyChanges { |
1710 | + target: drawer |
1711 | + anchors.rightMargin: 0 |
1712 | + } |
1713 | + }, |
1714 | + State { |
1715 | + name: "drawer" |
1716 | + extend: "visible" |
1717 | + PropertyChanges { |
1718 | + target: drawer |
1719 | + anchors.rightMargin: -drawer.width + root.x // so we never go past panelWidth, even when teased by tutorial |
1720 | + } |
1721 | }, |
1722 | State { |
1723 | name: "visibleTemporary" |
1724 | |
1725 | === added file 'qml/Launcher/MoreAppsHeader.qml' |
1726 | --- qml/Launcher/MoreAppsHeader.qml 1970-01-01 00:00:00 +0000 |
1727 | +++ qml/Launcher/MoreAppsHeader.qml 2016-12-06 13:47:05 +0000 |
1728 | @@ -0,0 +1,46 @@ |
1729 | +import QtQuick 2.4 |
1730 | +import Ubuntu.Components 1.3 |
1731 | + |
1732 | +AbstractButton { |
1733 | + id: root |
1734 | + |
1735 | + onClicked: { |
1736 | + // TODO: Make this point to the snappy store as soon as we stop landing to vivid |
1737 | + Qt.openUrlExternally("scope://com.canonical.scopes.clickstore") |
1738 | + } |
1739 | + |
1740 | + UbuntuShape { |
1741 | + width: parent.width |
1742 | + height: parent.height - units.gu(1) |
1743 | + color: "#20ffffff" |
1744 | + aspect: UbuntuShape.Flat |
1745 | + |
1746 | + Row { |
1747 | + anchors.fill: parent |
1748 | + anchors.margins: units.gu(1) |
1749 | + spacing: units.gu(1) |
1750 | + |
1751 | + Icon { |
1752 | + height: units.gu(2.2) |
1753 | + width: height |
1754 | + name: "stock_application" |
1755 | + anchors.verticalCenter: parent.verticalCenter |
1756 | + color: "white" |
1757 | + } |
1758 | + |
1759 | + Label { |
1760 | + text: i18n.tr("More apps in the store") |
1761 | + anchors.verticalCenter: parent.verticalCenter |
1762 | + fontSize: "small" |
1763 | + } |
1764 | + |
1765 | + Icon { |
1766 | + height: units.gu(2.5) |
1767 | + width: height |
1768 | + anchors.verticalCenter: parent.verticalCenter |
1769 | + name: "go-next" |
1770 | + color: "white" |
1771 | + } |
1772 | + } |
1773 | + } |
1774 | +} |
1775 | |
1776 | === modified file 'qml/Shell.qml' |
1777 | --- qml/Shell.qml 2016-11-29 09:39:56 +0000 |
1778 | +++ qml/Shell.qml 2016-12-06 13:47:05 +0000 |
1779 | @@ -278,8 +278,6 @@ |
1780 | |
1781 | dragAreaWidth: shell.edgeSize |
1782 | background: wallpaperResolver.background |
1783 | - leftEdgeDragProgress: !greeter || greeter.locked || !tutorial.launcherLongSwipeEnabled ? 0 : |
1784 | - Math.max(0, (launcher.dragDistance * (stage.width - launcher.panelWidth) / stage.width) - launcher.panelWidth) |
1785 | |
1786 | applicationManager: ApplicationManager |
1787 | topLevelSurfaceList: topLevelSurfaceList |
1788 | @@ -301,14 +299,12 @@ |
1789 | |
1790 | interactive: (!greeter || !greeter.shown) |
1791 | && panel.indicators.fullyClosed |
1792 | - && launcher.progress == 0 |
1793 | && !notifications.useModal |
1794 | |
1795 | onInteractiveChanged: { if (interactive) { focus = true; } } |
1796 | |
1797 | leftMargin: shell.usageScenario == "desktop" && !settings.autohideLauncher ? launcher.panelWidth: 0 |
1798 | suspended: greeter.shown |
1799 | - keepDashRunning: launcher.shown || launcher.dashSwipe |
1800 | altTabPressed: physicalKeysMapper.altTabPressed |
1801 | oskEnabled: shell.oskEnabled |
1802 | spreadEnabled: tutorial.spreadEnabled && (!greeter || (!greeter.hasLockedApp && !greeter.shown)) |
1803 | @@ -323,7 +319,7 @@ |
1804 | topMargin: panel.panelHeight |
1805 | leftMargin: launcher.lockedVisible ? launcher.panelWidth : 0 |
1806 | } |
1807 | - z: notifications.useModal || panel.indicators.shown || wizard.active || tutorial.running ? overlay.z + 1 : overlay.z - 1 |
1808 | + z: notifications.useModal || panel.indicators.shown || wizard.active || tutorial.running || launcher.drawerShown ? overlay.z + 1 : overlay.z - 1 |
1809 | } |
1810 | |
1811 | Loader { |
1812 | @@ -345,7 +341,6 @@ |
1813 | enabled: panel.indicators.fullyClosed // hides OSK when panel is open |
1814 | hides: [launcher, panel.indicators] |
1815 | tabletMode: shell.usageScenario != "phone" |
1816 | - launcherOffset: launcher.progress |
1817 | forcedUnlock: wizard.active || shell.mode === "full-shell" |
1818 | background: wallpaperResolver.cachedBackground |
1819 | hasCustomBackground: wallpaperResolver.hasCustomBackground |
1820 | @@ -434,19 +429,6 @@ |
1821 | } |
1822 | } |
1823 | |
1824 | - function showDash() { |
1825 | - if (greeter.notifyShowingDashFromDrag()) { |
1826 | - launcher.fadeOut(); |
1827 | - } |
1828 | - |
1829 | - if (!greeter.locked && tutorial.launcherLongSwipeEnabled |
1830 | - && (ApplicationManager.focusedApplicationId != "unity8-dash" || stage.spreadShown)) { |
1831 | - ApplicationManager.requestFocusApplication("unity8-dash") |
1832 | - launcher.fadeOut(); |
1833 | - stage.closeSpread(); |
1834 | - } |
1835 | - } |
1836 | - |
1837 | Item { |
1838 | id: overlay |
1839 | z: 10 |
1840 | @@ -497,15 +479,6 @@ |
1841 | id: launcher |
1842 | objectName: "launcher" |
1843 | |
1844 | - /* |
1845 | - * Since the Dash doesn't have the same controll over surfaces that the |
1846 | - * Shell does, it can't slowly move the scope out of the way, as the shell |
1847 | - * does with apps, and the dash is show instantly. This allows for some |
1848 | - * leeway and prevents accidental home swipes. |
1849 | - */ |
1850 | - readonly property real offset: shell.focusedApplicationId == "unity8-dash" ? units.gu(12) : 0 |
1851 | - readonly property bool dashSwipe: progress > offset |
1852 | - |
1853 | anchors.top: parent.top |
1854 | anchors.topMargin: inverted ? 0 : panel.panelHeight |
1855 | anchors.bottom: parent.bottom |
1856 | @@ -521,14 +494,11 @@ |
1857 | superTabPressed: physicalKeysMapper.superTabPressed |
1858 | panelWidth: units.gu(settings.launcherWidth) |
1859 | lockedVisible: shell.usageScenario == "desktop" && !settings.autohideLauncher && !panel.fullscreenMode |
1860 | + blurSource: greeter.shown ? greeter : stages |
1861 | + topPanelHeight: panel.panelHeight |
1862 | + drawerEnabled: !greeter.shown |
1863 | |
1864 | onShowDashHome: showHome() |
1865 | - onDash: showDash() |
1866 | - onDashSwipeChanged: { |
1867 | - if (dashSwipe) { |
1868 | - dash.setCurrentScope(0, false, true) |
1869 | - } |
1870 | - } |
1871 | onLauncherApplicationSelected: { |
1872 | greeter.notifyUserRequestedApp(); |
1873 | shell.activateApplication(appId); |
1874 | @@ -545,6 +515,12 @@ |
1875 | } |
1876 | |
1877 | GlobalShortcut { |
1878 | + shortcut: Qt.MetaModifier | Qt.Key_A |
1879 | + onTriggered: { |
1880 | + launcher.openDrawer(true); |
1881 | + } |
1882 | + } |
1883 | + GlobalShortcut { |
1884 | shortcut: Qt.AltModifier | Qt.Key_F1 |
1885 | onTriggered: { |
1886 | launcher.openForKeyboardNavigation(); |
1887 | |
1888 | === modified file 'qml/Stage/Spread/WindowedRightEdgeMaths.qml' |
1889 | --- qml/Stage/Spread/WindowedRightEdgeMaths.qml 2016-09-20 12:03:51 +0000 |
1890 | +++ qml/Stage/Spread/WindowedRightEdgeMaths.qml 2016-12-06 13:47:05 +0000 |
1891 | @@ -25,21 +25,31 @@ |
1892 | // Input |
1893 | property int itemIndex: 0 |
1894 | property int normalZ: 0 |
1895 | - property real progress: 0 |
1896 | property int startWidth: 0 |
1897 | property int startHeight: 0 |
1898 | property int startX: 0 |
1899 | property int targetX: 0 |
1900 | property int startY: 0 |
1901 | property int targetY: 0 |
1902 | -// property real startAngle: 40 |
1903 | property real targetAngle: 0 |
1904 | property int targetHeight: 0 |
1905 | property real targetScale: 0 |
1906 | + property real swipeProgress: 0 |
1907 | + property real pushProgress: 0 |
1908 | |
1909 | // Config |
1910 | property real breakPoint: 0.4 |
1911 | |
1912 | + // internal |
1913 | + readonly property real progress: { |
1914 | + if (pushProgress > 0) { |
1915 | + // we don't do the full animation when pushing, just a little bit |
1916 | + return MathUtils.linearAnimation(0, 1, 0, breakPoint + .1, pushProgress) |
1917 | + } else { |
1918 | + return swipeProgress; |
1919 | + } |
1920 | + } |
1921 | + |
1922 | // Output |
1923 | |
1924 | readonly property real scaleToPreviewProgress: { |
1925 | @@ -68,12 +78,17 @@ |
1926 | |
1927 | readonly property int animatedZ: { |
1928 | if (progress < breakPoint + (1 - breakPoint) / 2) { |
1929 | - return itemIndex == 1 ? normalZ + 2 : normalZ |
1930 | + if (swipeProgress > 0) { |
1931 | + return itemIndex == 1 ? normalZ + 2 : normalZ |
1932 | + } |
1933 | + if (pushProgress > 0) { |
1934 | + return normalZ; |
1935 | + } |
1936 | } |
1937 | return itemIndex |
1938 | } |
1939 | |
1940 | - readonly property real opacityMask: itemIndex == 1 ? MathUtils.linearAnimation(0, breakPoint, 0, 1, progress) : 1 |
1941 | + readonly property real opacityMask: (swipeProgress > 0 && itemIndex == 1) ? MathUtils.linearAnimation(0, breakPoint, 0, 1, progress) : 1 |
1942 | |
1943 | readonly property real animatedScale: progress < breakPoint ? 1 : MathUtils.linearAnimation(breakPoint, 1, 1, targetScale, progress) |
1944 | |
1945 | |
1946 | === modified file 'qml/Stage/Stage.qml' |
1947 | --- qml/Stage/Stage.qml 2016-11-29 09:39:25 +0000 |
1948 | +++ qml/Stage/Stage.qml 2016-12-06 13:47:05 +0000 |
1949 | @@ -36,7 +36,6 @@ |
1950 | property url background |
1951 | property int dragAreaWidth |
1952 | property bool interactive |
1953 | - property bool keepDashRunning: true |
1954 | property real nativeHeight |
1955 | property real nativeWidth |
1956 | property QtObject orientations |
1957 | @@ -50,7 +49,6 @@ |
1958 | |
1959 | // Configuration |
1960 | property string mode: "staged" |
1961 | - property real leftEdgeDragProgress: 0 |
1962 | |
1963 | // Used by the tutorial code |
1964 | readonly property real rightEdgeDragProgress: rightEdgeDragArea.dragging ? rightEdgeDragArea.progress : 0 // How far left the stage has been dragged |
1965 | @@ -415,7 +413,7 @@ |
1966 | // in staged mode, when it switches to Windowed mode it will suddenly |
1967 | // resume all those apps at once. We might want to avoid that. |
1968 | value: root.mode === "windowed" |
1969 | - || (isDash && root.keepDashRunning) |
1970 | + || isDash |
1971 | || (!root.suspended && model.application && priv.focusedAppDelegate && |
1972 | (priv.focusedAppDelegate.appId === model.application.appId || |
1973 | priv.mainStageAppId === model.application.appId || |
1974 | @@ -478,7 +476,7 @@ |
1975 | visible: true |
1976 | blurRadius: 32 |
1977 | brightness: .65 |
1978 | - opacity: MathUtils.linearAnimation(spreadItem.rightEdgeBreakPoint, 1, 0, 1, Math.max(rightEdgeDragArea.progress, edgeBarrier.progress)) |
1979 | + opacity: MathUtils.linearAnimation(spreadItem.rightEdgeBreakPoint, 1, 0, 1, Math.max(rightEdgeDragArea.dragging ? rightEdgeDragArea.progress : 0, edgeBarrier.progress)) |
1980 | } |
1981 | }, |
1982 | State { |
1983 | @@ -1061,7 +1059,6 @@ |
1984 | sideStageX: sideStage.x |
1985 | itemIndex: appDelegate.itemIndex |
1986 | nextInStack: priv.nextInStack |
1987 | - leftEdgeDragProgress: root.leftEdgeDragProgress |
1988 | } |
1989 | |
1990 | StagedRightEdgeMaths { |
1991 | @@ -1164,7 +1161,8 @@ |
1992 | when: root.mode == "windowed" && (root.state == "windowedRightEdge" || rightEdgeFocusAnimation.running || hidingAnimation.running || edgeBarrier.progress > 0) |
1993 | PropertyChanges { |
1994 | target: windowedRightEdgeMaths |
1995 | - progress: Math.max(rightEdgeDragArea.progress, edgeBarrier.progress) |
1996 | + swipeProgress: rightEdgeDragArea.dragging ? rightEdgeDragArea.progress : 0 |
1997 | + pushProgress: edgeBarrier.progress |
1998 | } |
1999 | PropertyChanges { |
2000 | target: appDelegate |
2001 | |
2002 | === modified file 'qml/Stage/StageMaths.qml' |
2003 | --- qml/Stage/StageMaths.qml 2016-09-13 13:15:09 +0000 |
2004 | +++ qml/Stage/StageMaths.qml 2016-12-06 13:47:05 +0000 |
2005 | @@ -12,7 +12,6 @@ |
2006 | property int sideStageWidth: 0 |
2007 | property int sideStageX: sceneWidth |
2008 | property bool animateX: false |
2009 | - property int leftEdgeDragProgress: 0 |
2010 | |
2011 | property int stage: ApplicationInfoInterface.MainStage |
2012 | property var thisDelegate: null |
2013 | @@ -26,10 +25,6 @@ |
2014 | // of the last focused order. |
2015 | readonly property int itemZ: { |
2016 | // only shuffle when we've got a main and side stage |
2017 | - if (thisDelegate.isDash && thisDelegate != mainStageDelegate && leftEdgeDragProgress > 0) { |
2018 | - return -1; // Keep the dash behind all other apps for the left edge gesture |
2019 | - } |
2020 | - |
2021 | if (!sideStageDelegate) return itemIndex; |
2022 | |
2023 | // don't shuffle indexes greater than "actives or next" |
2024 | @@ -64,12 +59,12 @@ |
2025 | |
2026 | property int itemX: { |
2027 | if (mainStageDelegate == thisDelegate) { |
2028 | - return thisDelegate.isDash ? 0 : leftEdgeDragProgress; |
2029 | + return 0 |
2030 | } |
2031 | if (sideStageDelegate == thisDelegate) { |
2032 | return sideStageX; |
2033 | } |
2034 | - return thisDelegate.isDash && leftEdgeDragProgress > 0 ? 0 : sceneWidth; |
2035 | + return sceneWidth; |
2036 | } |
2037 | Behavior on itemX { enabled: root.animateX; UbuntuNumberAnimation {} } |
2038 | |
2039 | |
2040 | === modified file 'qml/Tutorial/TutorialLeftLong.qml' |
2041 | --- qml/Tutorial/TutorialLeftLong.qml 2016-04-29 09:12:21 +0000 |
2042 | +++ qml/Tutorial/TutorialLeftLong.qml 2016-12-06 13:47:05 +0000 |
2043 | @@ -25,7 +25,7 @@ |
2044 | |
2045 | // Unlike other tutorials, this one can't be skipped before we show it, so |
2046 | // only set opacityOverride if we're already shown. |
2047 | - opacityOverride: shown ? 1 - launcher.dragDistance / launcher.minimizeDistance : 1 |
2048 | + opacityOverride: shown ? 1 - launcher.dragDistance / (launcher.panelWidth * 3) : 1 |
2049 | |
2050 | mouseArea { |
2051 | anchors.leftMargin: launcher.dragAreaWidth |
2052 | |
2053 | === modified file 'tests/mocks/Unity/Launcher/CMakeLists.txt' |
2054 | --- tests/mocks/Unity/Launcher/CMakeLists.txt 2016-10-28 12:08:59 +0000 |
2055 | +++ tests/mocks/Unity/Launcher/CMakeLists.txt 2016-12-06 13:47:05 +0000 |
2056 | @@ -1,7 +1,8 @@ |
2057 | -pkg_check_modules(LAUNCHER_API REQUIRED unity-shell-launcher=10) |
2058 | +pkg_check_modules(LAUNCHER_API REQUIRED unity-shell-launcher=11) |
2059 | |
2060 | include_directories( |
2061 | ${CMAKE_CURRENT_SOURCE_DIR} |
2062 | + ${CMAKE_SOURCE_DIR}/plugins/Unity/Launcher/ |
2063 | ) |
2064 | |
2065 | set(MockLauncherModel_SOURCES |
2066 | @@ -9,10 +10,13 @@ |
2067 | ${LAUNCHER_API_INCLUDEDIR}/unity/shell/launcher/LauncherItemInterface.h |
2068 | ${LAUNCHER_API_INCLUDEDIR}/unity/shell/launcher/LauncherModelInterface.h |
2069 | ${LAUNCHER_API_INCLUDEDIR}/unity/shell/launcher/QuickListModelInterface.h |
2070 | + ${LAUNCHER_API_INCLUDEDIR}/unity/shell/launcher/AppDrawerModelInterface.h |
2071 | plugin.cpp |
2072 | MockLauncherModel.cpp |
2073 | MockLauncherItem.cpp |
2074 | MockQuickListModel.cpp |
2075 | + MockAppDrawerModel.cpp |
2076 | + ${CMAKE_SOURCE_DIR}/plugins/Utils/applicationsfiltermodel.cpp |
2077 | ) |
2078 | |
2079 | add_library(MockLauncherPlugin MODULE ${MockLauncherModel_SOURCES}) |
2080 | |
2081 | === added file 'tests/mocks/Unity/Launcher/MockAppDrawerModel.cpp' |
2082 | --- tests/mocks/Unity/Launcher/MockAppDrawerModel.cpp 1970-01-01 00:00:00 +0000 |
2083 | +++ tests/mocks/Unity/Launcher/MockAppDrawerModel.cpp 2016-12-06 13:47:05 +0000 |
2084 | @@ -0,0 +1,75 @@ |
2085 | +/* |
2086 | + * Copyright (C) 2016 Canonical, Ltd. |
2087 | + * |
2088 | + * This program is free software; you can redistribute it and/or modify |
2089 | + * it under the terms of the GNU General Public License as published by |
2090 | + * the Free Software Foundation; version 3. |
2091 | + * |
2092 | + * This program is distributed in the hope that it will be useful, |
2093 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2094 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2095 | + * GNU General Public License for more details. |
2096 | + * |
2097 | + * You should have received a copy of the GNU General Public License |
2098 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2099 | + */ |
2100 | + |
2101 | +#include "MockAppDrawerModel.h" |
2102 | + |
2103 | +#include <QDebug> |
2104 | +#include <QDateTime> |
2105 | + |
2106 | +MockAppDrawerModel::MockAppDrawerModel(QObject *parent): |
2107 | + AppDrawerModelInterface(parent) |
2108 | +{ |
2109 | + MockLauncherItem *item = new MockLauncherItem("dialer-app", "/usr/share/applications/dialer-app.desktop", "Dialer", "dialer-app", this); |
2110 | + m_list.append(item); |
2111 | + item = new MockLauncherItem("camera-app", "/usr/share/applications/camera-app.desktop", "Camera", "camera", this); |
2112 | + m_list.append(item); |
2113 | + item = new MockLauncherItem("camera-app2", "/usr/share/applications/camera-app2.desktop", "Camera2", "camera", this); |
2114 | + m_list.append(item); |
2115 | + item = new MockLauncherItem("gallery-app", "/usr/share/applications/gallery-app.desktop", "Gallery", "gallery", this); |
2116 | + m_list.append(item); |
2117 | + item = new MockLauncherItem("music-app", "/usr/share/applications/music-app.desktop", "Music", "soundcloud", this); |
2118 | + m_list.append(item); |
2119 | + item = new MockLauncherItem("facebook-webapp", "/usr/share/applications/facebook-webapp.desktop", "Facebook", "facebook", this); |
2120 | + m_list.append(item); |
2121 | + item = new MockLauncherItem("webbrowser-app", "/usr/share/applications/webbrowser-app.desktop", "Browser", "browser", this); |
2122 | + m_list.append(item); |
2123 | + item = new MockLauncherItem("twitter-webapp", "/usr/share/applications/twitter-webapp.desktop", "Twitter", "twitter", this); |
2124 | + m_list.append(item); |
2125 | + item = new MockLauncherItem("gmail-webapp", "/usr/share/applications/gmail-webapp.desktop", "GMail", "gmail", this); |
2126 | + m_list.append(item); |
2127 | + item = new MockLauncherItem("ubuntu-weather-app", "/usr/share/applications/ubuntu-weather-app.desktop", "Weather", "weather", this); |
2128 | + m_list.append(item); |
2129 | + item = new MockLauncherItem("notes-app", "/usr/share/applications/notes-app.desktop", "Notepad", "notepad", this); |
2130 | + m_list.append(item); |
2131 | + item = new MockLauncherItem("calendar-app", "/usr/share/applications/calendar-app.desktop","Calendar", "calendar", this); |
2132 | + m_list.append(item); |
2133 | + item = new MockLauncherItem("libreoffice", "/usr/share/applications/libreoffice.desktop","Libre Office", "libreoffice", this); |
2134 | + m_list.append(item); |
2135 | + qDebug() << "mock model created"; |
2136 | + |
2137 | + qsrand(QDateTime::currentMSecsSinceEpoch() / 1000); |
2138 | +} |
2139 | + |
2140 | +int MockAppDrawerModel::rowCount(const QModelIndex &parent) const |
2141 | +{ |
2142 | + return m_list.count(); |
2143 | +} |
2144 | + |
2145 | +QVariant MockAppDrawerModel::data(const QModelIndex &index, int role) const |
2146 | +{ |
2147 | + switch (role) { |
2148 | + case RoleAppId: |
2149 | + return m_list.at(index.row())->appId(); |
2150 | + case RoleName: |
2151 | + return m_list.at(index.row())->name(); |
2152 | + case RoleIcon: |
2153 | + return m_list.at(index.row())->icon(); |
2154 | + case RoleUsage: |
2155 | + return qrand(); |
2156 | + } |
2157 | + |
2158 | + return QVariant(); |
2159 | +} |
2160 | |
2161 | === added file 'tests/mocks/Unity/Launcher/MockAppDrawerModel.h' |
2162 | --- tests/mocks/Unity/Launcher/MockAppDrawerModel.h 1970-01-01 00:00:00 +0000 |
2163 | +++ tests/mocks/Unity/Launcher/MockAppDrawerModel.h 2016-12-06 13:47:05 +0000 |
2164 | @@ -0,0 +1,32 @@ |
2165 | +/* |
2166 | + * Copyright (C) 2016 Canonical, Ltd. |
2167 | + * |
2168 | + * This program is free software; you can redistribute it and/or modify |
2169 | + * it under the terms of the GNU General Public License as published by |
2170 | + * the Free Software Foundation; version 3. |
2171 | + * |
2172 | + * This program is distributed in the hope that it will be useful, |
2173 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2174 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2175 | + * GNU General Public License for more details. |
2176 | + * |
2177 | + * You should have received a copy of the GNU General Public License |
2178 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2179 | + */ |
2180 | + |
2181 | +#include <unity/shell/launcher/AppDrawerModelInterface.h> |
2182 | + |
2183 | +#include "MockLauncherItem.h" |
2184 | + |
2185 | +class MockAppDrawerModel: public AppDrawerModelInterface |
2186 | +{ |
2187 | + Q_OBJECT |
2188 | +public: |
2189 | + MockAppDrawerModel(QObject* parent = nullptr); |
2190 | + |
2191 | + int rowCount(const QModelIndex &parent) const override; |
2192 | + QVariant data(const QModelIndex &index, int role) const override; |
2193 | + |
2194 | +private: |
2195 | + QList<MockLauncherItem*> m_list; |
2196 | +}; |
2197 | |
2198 | === modified file 'tests/mocks/Unity/Launcher/MockLauncherItem.cpp' |
2199 | --- tests/mocks/Unity/Launcher/MockLauncherItem.cpp 2016-05-13 11:28:56 +0000 |
2200 | +++ tests/mocks/Unity/Launcher/MockLauncherItem.cpp 2016-12-06 13:47:05 +0000 |
2201 | @@ -67,6 +67,11 @@ |
2202 | return m_icon; |
2203 | } |
2204 | |
2205 | +QStringList MockLauncherItem::keywords() const |
2206 | +{ |
2207 | + return m_keywords; |
2208 | +} |
2209 | + |
2210 | bool MockLauncherItem::pinned() const |
2211 | { |
2212 | return m_pinned; |
2213 | @@ -200,3 +205,11 @@ |
2214 | { |
2215 | return m_quickList; |
2216 | } |
2217 | + |
2218 | +void MockLauncherItem::setKeywords(const QStringList &keywords) |
2219 | +{ |
2220 | + if (m_keywords != keywords) { |
2221 | + m_keywords = keywords; |
2222 | + Q_EMIT keywordsChanged(keywords); |
2223 | + } |
2224 | +} |
2225 | |
2226 | === modified file 'tests/mocks/Unity/Launcher/MockLauncherItem.h' |
2227 | --- tests/mocks/Unity/Launcher/MockLauncherItem.h 2016-05-10 15:51:00 +0000 |
2228 | +++ tests/mocks/Unity/Launcher/MockLauncherItem.h 2016-12-06 13:47:05 +0000 |
2229 | @@ -22,6 +22,8 @@ |
2230 | |
2231 | #include <unity/shell/launcher/LauncherItemInterface.h> |
2232 | |
2233 | +#include <QStringList> |
2234 | + |
2235 | class MockQuickListModel; |
2236 | |
2237 | using namespace unity::shell::launcher; |
2238 | @@ -37,6 +39,7 @@ |
2239 | QString desktopFile() const; |
2240 | QString name() const override; |
2241 | QString icon() const override; |
2242 | + QStringList keywords() const override; |
2243 | |
2244 | bool pinned() const override; |
2245 | bool running() const override; |
2246 | @@ -51,6 +54,7 @@ |
2247 | unity::shell::launcher::QuickListModelInterface *quickList() const override; |
2248 | |
2249 | private: |
2250 | + void setKeywords(const QStringList &keywords); |
2251 | void setPinned(bool pinned); |
2252 | void setRunning(bool running); |
2253 | void setRecent(bool recent); |
2254 | @@ -65,6 +69,7 @@ |
2255 | QString m_desktopFile; |
2256 | QString m_name; |
2257 | QString m_icon; |
2258 | + QStringList m_keywords; |
2259 | bool m_pinned; |
2260 | bool m_running; |
2261 | bool m_recent; |
2262 | @@ -77,6 +82,7 @@ |
2263 | MockQuickListModel *m_quickList; |
2264 | |
2265 | friend class MockLauncherModel; |
2266 | + friend class MockAppDrawerModel; |
2267 | }; |
2268 | |
2269 | #endif // MOCKLAUNCHERITEM_H |
2270 | |
2271 | === modified file 'tests/mocks/Unity/Launcher/MockLauncherModel.cpp' |
2272 | --- tests/mocks/Unity/Launcher/MockLauncherModel.cpp 2016-06-17 01:13:55 +0000 |
2273 | +++ tests/mocks/Unity/Launcher/MockLauncherModel.cpp 2016-12-06 13:47:05 +0000 |
2274 | @@ -36,6 +36,9 @@ |
2275 | item = new MockLauncherItem("camera-app2", "/usr/share/applications/camera-app2.desktop", "Camera2", "camera", this); |
2276 | item->setPinned(true); |
2277 | m_list.append(item); |
2278 | + item = new MockLauncherItem("camera-app3", "/usr/share/applications/camera-app2.desktop", "Camera2", "camera", this); |
2279 | + item->setPinned(true); |
2280 | + m_list.append(item); |
2281 | item = new MockLauncherItem("gallery-app", "/usr/share/applications/gallery-app.desktop", "Gallery", "gallery", this); |
2282 | item->setProgress(50); |
2283 | item->setCountVisible(true); |
2284 | |
2285 | === modified file 'tests/mocks/Unity/Launcher/plugin.cpp' |
2286 | --- tests/mocks/Unity/Launcher/plugin.cpp 2013-08-19 15:10:58 +0000 |
2287 | +++ tests/mocks/Unity/Launcher/plugin.cpp 2016-12-06 13:47:05 +0000 |
2288 | @@ -21,9 +21,11 @@ |
2289 | #include "MockLauncherModel.h" |
2290 | #include "MockLauncherItem.h" |
2291 | #include "MockQuickListModel.h" |
2292 | +#include "MockAppDrawerModel.h" |
2293 | |
2294 | #include <unity/shell/launcher/LauncherModelInterface.h> |
2295 | #include <unity/shell/launcher/LauncherItemInterface.h> |
2296 | +#include <unity/shell/launcher/AppDrawerModelInterface.h> |
2297 | |
2298 | #include <QtQml/qqml.h> |
2299 | |
2300 | @@ -41,8 +43,10 @@ |
2301 | qmlRegisterUncreatableType<LauncherModelInterface>(uri, 0, 1, "LauncherModelInterface", "Abstract Interface. Cannot be instantiated."); |
2302 | qmlRegisterUncreatableType<LauncherItemInterface>(uri, 0, 1, "LauncherItemInterface", "Abstract Interface. Cannot be instantiated."); |
2303 | qmlRegisterUncreatableType<QuickListModelInterface>(uri, 0, 1, "QuickListModelInterface", "Abstract Interface. Cannot be instantiated."); |
2304 | + qmlRegisterUncreatableType<AppDrawerModelInterface>(uri, 0, 1, "AppDrawerModelInterface", "Abstract Interface. Cannot be instantiated."); |
2305 | |
2306 | qmlRegisterSingletonType<MockLauncherModel>(uri, 0, 1, "LauncherModel", modelProvider); |
2307 | qmlRegisterUncreatableType<MockLauncherItem>(uri, 0, 1, "LauncherItem", "Can't create LauncherItems in QML. Get them from the LauncherModel"); |
2308 | qmlRegisterUncreatableType<MockQuickListModel>(uri, 0, 1, "QuickListModel", "Can't create QuickLists in QML. Get them from the LauncherItems"); |
2309 | + qmlRegisterType<MockAppDrawerModel>(uri, 0, 1, "AppDrawerModel"); |
2310 | } |
2311 | |
2312 | === modified file 'tests/mocks/Utils/CMakeLists.txt' |
2313 | --- tests/mocks/Utils/CMakeLists.txt 2016-06-29 18:05:44 +0000 |
2314 | +++ tests/mocks/Utils/CMakeLists.txt 2016-12-06 13:47:05 +0000 |
2315 | @@ -24,11 +24,15 @@ |
2316 | ${CMAKE_SOURCE_DIR}/plugins/Utils/inputeventgenerator.cpp |
2317 | ${CMAKE_SOURCE_DIR}/plugins/Utils/deviceconfigparser.cpp |
2318 | ${CMAKE_SOURCE_DIR}/plugins/Utils/globalfunctions.cpp |
2319 | + ${CMAKE_SOURCE_DIR}/plugins/Utils/appdrawerproxymodel.cpp |
2320 | ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/ApplicationManagerInterface.h |
2321 | ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/ApplicationInfoInterface.h |
2322 | ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/MirSurfaceInterface.h |
2323 | ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/MirSurfaceListInterface.h |
2324 | ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/Mir.h |
2325 | + ${LAUNCHER_API_INCLUDEDIR}/unity/shell/launcher/AppDrawerModelInterface.h |
2326 | + ${LAUNCHER_API_INCLUDEDIR}/unity/shell/launcher/LauncherModelInterface.h |
2327 | + ${LAUNCHER_API_INCLUDEDIR}/unity/shell/launcher/LauncherItemInterface.h |
2328 | constants.cpp |
2329 | plugin.cpp |
2330 | windowstatestorage.cpp |
2331 | |
2332 | === modified file 'tests/mocks/Utils/plugin.cpp' |
2333 | --- tests/mocks/Utils/plugin.cpp 2016-06-28 20:38:00 +0000 |
2334 | +++ tests/mocks/Utils/plugin.cpp 2016-12-06 13:47:05 +0000 |
2335 | @@ -40,6 +40,7 @@ |
2336 | #include <inputeventgenerator.h> |
2337 | #include <deviceconfigparser.h> |
2338 | #include <globalfunctions.h> |
2339 | +#include <appdrawerproxymodel.h> |
2340 | |
2341 | static QObject *createWindowStateStorage(QQmlEngine *engine, QJSEngine *scriptEngine) |
2342 | { |
2343 | @@ -82,4 +83,5 @@ |
2344 | qmlRegisterType<DeviceConfigParser>(uri, 0, 1, "DeviceConfigParser"); |
2345 | qmlRegisterSingletonType<GlobalFunctions>(uri, 0, 1, "Functions", createGlobalFunctions); |
2346 | qmlRegisterType<URLDispatcher>(uri, 0, 1, "URLDispatcher"); |
2347 | + qmlRegisterType<AppDrawerProxyModel>(uri, 0, 1, "AppDrawerProxyModel"); |
2348 | } |
2349 | |
2350 | === modified file 'tests/plugins/Greeter/Unity/Launcher/CMakeLists.txt' |
2351 | --- tests/plugins/Greeter/Unity/Launcher/CMakeLists.txt 2016-10-28 12:08:59 +0000 |
2352 | +++ tests/plugins/Greeter/Unity/Launcher/CMakeLists.txt 2016-12-06 13:47:05 +0000 |
2353 | @@ -1,4 +1,4 @@ |
2354 | -pkg_check_modules(LAUNCHER_API REQUIRED unity-shell-launcher=10) |
2355 | +pkg_check_modules(LAUNCHER_API REQUIRED unity-shell-launcher=11) |
2356 | |
2357 | include_directories( |
2358 | ${CMAKE_CURRENT_SOURCE_DIR} |
2359 | |
2360 | === modified file 'tests/plugins/Unity/Launcher/CMakeLists.txt' |
2361 | --- tests/plugins/Unity/Launcher/CMakeLists.txt 2016-10-28 12:08:59 +0000 |
2362 | +++ tests/plugins/Unity/Launcher/CMakeLists.txt 2016-12-06 13:47:05 +0000 |
2363 | @@ -1,5 +1,5 @@ |
2364 | pkg_check_modules(GSETTINGS_QT REQUIRED gsettings-qt) |
2365 | -pkg_check_modules(LAUNCHER_API REQUIRED unity-shell-launcher=10) |
2366 | +pkg_check_modules(LAUNCHER_API REQUIRED unity-shell-launcher=11) |
2367 | |
2368 | include_directories( |
2369 | ${CMAKE_CURRENT_SOURCE_DIR} |
2370 | @@ -30,6 +30,7 @@ |
2371 | ${CMAKE_SOURCE_DIR}/plugins/Unity/Launcher/quicklistmodel.cpp |
2372 | ${CMAKE_SOURCE_DIR}/plugins/Unity/Launcher/dbusinterface.cpp |
2373 | ${CMAKE_SOURCE_DIR}/plugins/Unity/Launcher/quicklistentry.cpp |
2374 | + ${CMAKE_SOURCE_DIR}/plugins/Unity/Launcher/ualwrapper.cpp |
2375 | ${LAUNCHER_API_INCLUDEDIR}/unity/shell/launcher/LauncherItemInterface.h |
2376 | ${LAUNCHER_API_INCLUDEDIR}/unity/shell/launcher/LauncherModelInterface.h |
2377 | ${LAUNCHER_API_INCLUDEDIR}/unity/shell/launcher/QuickListModelInterface.h |
2378 | |
2379 | === modified file 'tests/qmltests/CMakeLists.txt' |
2380 | --- tests/qmltests/CMakeLists.txt 2016-09-22 14:19:36 +0000 |
2381 | +++ tests/qmltests/CMakeLists.txt 2016-12-06 13:47:05 +0000 |
2382 | @@ -71,6 +71,7 @@ |
2383 | add_unity8_qmltest(Greeter NarrowView) |
2384 | add_unity8_qmltest(Greeter WideView) |
2385 | add_unity8_qmltest(Launcher Launcher) |
2386 | +add_unity8_qmltest(Launcher Drawer) |
2387 | add_unity8_qmltest(Notifications Notifications) |
2388 | add_unity8_qmltest(Notifications VisualSnapDecisionsQueue) |
2389 | add_unity8_qmltest(Notifications OptionToggle) |
2390 | |
2391 | === modified file 'tests/qmltests/Dash/tst_DashShell.qml' |
2392 | --- tests/qmltests/Dash/tst_DashShell.qml 2016-07-08 20:44:09 +0000 |
2393 | +++ tests/qmltests/Dash/tst_DashShell.qml 2016-12-06 13:47:05 +0000 |
2394 | @@ -112,34 +112,5 @@ |
2395 | mouseClick(buttonShowDashHome); |
2396 | tryCompare(dashContentList, "currentIndex", 0); |
2397 | } |
2398 | - |
2399 | - function test_setShortLauncherMoveResetNonActiveDash() { |
2400 | - var dashContentList = findChild(dash, "dashContentList"); |
2401 | - var startX = dash.width - units.gu(1); |
2402 | - var startY = dash.height / 2; |
2403 | - var stopX = units.gu(1) |
2404 | - var stopY = startY; |
2405 | - waitForRendering(dashContentList); |
2406 | - touchFlick(dash, startX, startY, stopX, stopY); |
2407 | - touchFlick(dash, startX, startY, stopX, stopY); |
2408 | - compare(dashContentList.currentIndex, 2, "Could not flick to scope id 2"); |
2409 | - |
2410 | - // Pretend the dash is not active |
2411 | - dash.windowActive = false; |
2412 | - |
2413 | - // Flick the greeter away |
2414 | - var startX = shell.width - units.gu(1); |
2415 | - var startY = shell.height / 2; |
2416 | - var stopX = units.gu(1) |
2417 | - var stopY = startY; |
2418 | - touchFlick(shell, startX, startY, stopX, stopY); |
2419 | - |
2420 | - var greeter = findChild(shell, "greeter"); |
2421 | - tryCompare(greeter, "shown", false); |
2422 | - |
2423 | - // Now do a small launcher movement |
2424 | - touchFlick(shell, stopX, startY, startX, stopY); |
2425 | - compare(dashContentList.currentIndex, 0, "Small launcher move did not reset dash on non active window"); |
2426 | - } |
2427 | } |
2428 | } |
2429 | |
2430 | === added file 'tests/qmltests/Launcher/tst_Drawer.qml' |
2431 | --- tests/qmltests/Launcher/tst_Drawer.qml 1970-01-01 00:00:00 +0000 |
2432 | +++ tests/qmltests/Launcher/tst_Drawer.qml 2016-12-06 13:47:05 +0000 |
2433 | @@ -0,0 +1,264 @@ |
2434 | +/* |
2435 | + * Copyright 2013-2016 Canonical Ltd. |
2436 | + * |
2437 | + * This program is free software; you can redistribute it and/or modify |
2438 | + * it under the terms of the GNU General Public License as published by |
2439 | + * the Free Software Foundation; version 3. |
2440 | + * |
2441 | + * This program is distributed in the hope that it will be useful, |
2442 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2443 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2444 | + * GNU General Public License for more details. |
2445 | + * |
2446 | + * You should have received a copy of the GNU General Public License |
2447 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2448 | + */ |
2449 | + |
2450 | +import QtQuick 2.4 |
2451 | +import QtQuick.Layouts 1.1 |
2452 | +import Ubuntu.Components 1.3 |
2453 | +import ".." |
2454 | +import "../../../qml/Launcher" |
2455 | +import Unity.Launcher 0.1 |
2456 | +import Utils 0.1 // For EdgeBarrierSettings |
2457 | +import Unity.Test 0.1 |
2458 | + |
2459 | +StyledItem { |
2460 | + id: root |
2461 | + theme.name: "Ubuntu.Components.Themes.SuruDark" |
2462 | + |
2463 | + width: units.gu(140) |
2464 | + height: units.gu(70) |
2465 | + Rectangle { |
2466 | + anchors.fill: parent |
2467 | + color: UbuntuColors.graphite // something neither white nor black |
2468 | + } |
2469 | + |
2470 | + Launcher { |
2471 | + id: launcher |
2472 | + x: 0 |
2473 | + y: 0 |
2474 | + width: units.gu(40) |
2475 | + height: root.height |
2476 | + |
2477 | + lockedVisible: lockedVisibleCheckBox.checked |
2478 | + |
2479 | + property string lastSelectedApplication |
2480 | + onLauncherApplicationSelected: { |
2481 | + lastSelectedApplication = appId |
2482 | + } |
2483 | + |
2484 | + Component.onCompleted: { |
2485 | + launcher.focus = true |
2486 | + edgeBarrierControls.target = testCase.findChild(this, "edgeBarrierController"); |
2487 | + } |
2488 | + } |
2489 | + |
2490 | + ColumnLayout { |
2491 | + anchors { bottom: parent.bottom; right: parent.right; margins: units.gu(1) } |
2492 | + spacing: units.gu(1) |
2493 | + width: childrenRect.width |
2494 | + |
2495 | + RowLayout { |
2496 | + CheckBox { |
2497 | + id: lockedVisibleCheckBox |
2498 | + checked: false |
2499 | + } |
2500 | + Label { |
2501 | + text: "Launcher always visible" |
2502 | + } |
2503 | + } |
2504 | + |
2505 | + Slider { |
2506 | + id: widthSlider |
2507 | + Layout.fillWidth: true |
2508 | + minimumValue: 6 |
2509 | + maximumValue: 12 |
2510 | + value: 10 |
2511 | + } |
2512 | + |
2513 | + MouseTouchEmulationCheckbox {} |
2514 | + |
2515 | + EdgeBarrierControls { |
2516 | + id: edgeBarrierControls |
2517 | + text: "Drag here to pull out launcher" |
2518 | + onDragged: { launcher.pushEdge(amount); } |
2519 | + } |
2520 | + } |
2521 | + |
2522 | + UnityTestCase { |
2523 | + id: testCase |
2524 | + when: windowShown |
2525 | + name: "Drawer" |
2526 | + |
2527 | + function dragDrawerIntoView() { |
2528 | + var startX = launcher.dragAreaWidth/2; |
2529 | + var startY = launcher.height/2; |
2530 | + touchFlick(launcher, |
2531 | + startX, startY, |
2532 | + startX+units.gu(35), startY); |
2533 | + |
2534 | + var drawer = findChild(launcher, "drawer"); |
2535 | + verify(!!drawer); |
2536 | + |
2537 | + // wait until it gets fully extended |
2538 | + // a tryCompare doesn't work since |
2539 | + // compare(-0.000005917593600024418, 0); |
2540 | + // is true and in this case we want exactly 0 or will have pain later on |
2541 | + tryCompareFunction( function(){ return drawer.x === 0; }, true ); |
2542 | + tryCompare(launcher, "state", "drawer"); |
2543 | + tryCompare(launcher, "drawerShown", true); |
2544 | + } |
2545 | + |
2546 | + function revealByEdgePush() { |
2547 | + // Place the mouse against the window/screen edge and push beyond the barrier threshold |
2548 | + // If the mouse did not move between two revealByEdgePush(), we need it to move out the |
2549 | + // area to make sure we're not just accumulating to the previous push |
2550 | + mouseMove(root, root.width, root.height / 2); |
2551 | + mouseMove(root, 1, root.height / 2); |
2552 | + |
2553 | + launcher.pushEdge(EdgeBarrierSettings.pushThreshold * 1.1); |
2554 | + |
2555 | + var drawer = findChild(launcher, "drawer"); |
2556 | + verify(!!drawer); |
2557 | + |
2558 | + // wait until it gets fully extended |
2559 | + tryCompare(drawer, "x", 0); |
2560 | + tryCompare(launcher, "state", "drawer"); |
2561 | + tryCompare(launcher, "drawerShown", true); |
2562 | + } |
2563 | + |
2564 | + function init() { |
2565 | + launcher.lastSelectedApplication = ""; |
2566 | + launcher.lockedVisible = false; |
2567 | + launcher.hide(); |
2568 | + var drawer = findChild(launcher, "drawer"); |
2569 | + tryCompare(drawer, "x", -drawer.width); |
2570 | + } |
2571 | + |
2572 | + function test_revealByEdgeDrag() { |
2573 | + dragDrawerIntoView(); |
2574 | + } |
2575 | + |
2576 | + function test_revealByEdgePush_data() { |
2577 | + return [ |
2578 | + { tag: "autohide launcher", autohide: true }, |
2579 | + { tag: "locked launcher", autohide: false } |
2580 | + ] |
2581 | + } |
2582 | + |
2583 | + function test_revealByEdgePush(data) { |
2584 | + launcher.lockedVisible = !data.autohide; |
2585 | + |
2586 | + var panel = findChild(launcher, "launcherPanel"); |
2587 | + tryCompare(panel, "x", data.autohide ? -panel.width : 0); |
2588 | + tryCompare(launcher, "state", data.autohide ? "" : "visible"); |
2589 | + waitForRendering(launcher) |
2590 | + |
2591 | + revealByEdgePush(); |
2592 | + } |
2593 | + |
2594 | + function test_hideByDraggingDrawer_data() { |
2595 | + return [ |
2596 | + {tag: "autohide", autohide: true, endState: ""}, |
2597 | + {tag: "locked", autohide: false, endState: "visible"} |
2598 | + ] |
2599 | + } |
2600 | + |
2601 | + function test_hideByDraggingDrawer(data) { |
2602 | + launcher.lockedVisible = !data.autohide; |
2603 | + |
2604 | + dragDrawerIntoView(); |
2605 | + waitForRendering(launcher); |
2606 | + |
2607 | + var drawer = findChild(launcher, "drawer"); |
2608 | + |
2609 | + mouseFlick(root, drawer.width - units.gu(1), drawer.height / 2, units.gu(2), drawer.height / 2, true, true); |
2610 | + |
2611 | + tryCompare(drawer.anchors, "rightMargin", 0); |
2612 | + tryCompare(launcher, "state", data.endState); |
2613 | + launcher.lockedVisible = false; |
2614 | + } |
2615 | + |
2616 | + function test_hideByClickingOutside() { |
2617 | + dragDrawerIntoView(); |
2618 | + |
2619 | + var drawer = findChild(launcher, "drawer"); |
2620 | + |
2621 | + mouseClick(root, drawer.width + units.gu(1), root.height / 2); |
2622 | + |
2623 | + tryCompare(launcher, "state", ""); |
2624 | + } |
2625 | + |
2626 | + function test_launchAppFromDrawer() { |
2627 | + dragDrawerIntoView(); |
2628 | + |
2629 | + var drawerList = findChild(launcher, "drawerItemList"); |
2630 | + var dialerApp = findChild(drawerList, "drawerItem_dialer-app"); |
2631 | + mouseClick(dialerApp, dialerApp.width / 2, dialerApp.height / 2); |
2632 | + |
2633 | + tryCompare(launcher, "lastSelectedApplication", "dialer-app"); |
2634 | + |
2635 | + tryCompare(launcher, "state", ""); |
2636 | + } |
2637 | + |
2638 | + function test_launcherGivesUpFocusAfterLaunchingFromDrawer() { |
2639 | + dragDrawerIntoView(); |
2640 | + |
2641 | + tryCompare(launcher, "focus", true); |
2642 | + |
2643 | + var drawerList = findChild(launcher, "drawerItemList"); |
2644 | + var dialerApp = findChild(drawerList, "drawerItem_dialer-app"); |
2645 | + mouseClick(dialerApp, dialerApp.width / 2, dialerApp.height / 2); |
2646 | + |
2647 | + tryCompare(launcher, "focus", false); |
2648 | + } |
2649 | + |
2650 | + function test_drawerDisabled() { |
2651 | + launcher.drawerEnabled = false; |
2652 | + |
2653 | + var startX = launcher.dragAreaWidth/2; |
2654 | + var startY = launcher.height/2; |
2655 | + touchFlick(launcher, |
2656 | + startX, startY, |
2657 | + startX+units.gu(35), startY); |
2658 | + |
2659 | + var drawer = findChild(launcher, "drawer"); |
2660 | + verify(!!drawer); |
2661 | + |
2662 | + tryCompare(launcher, "state", "visible"); |
2663 | + tryCompare(launcher, "drawerShown", false); |
2664 | + |
2665 | + launcher.drawerEnabled = true; |
2666 | + } |
2667 | + |
2668 | + function test_search() { |
2669 | + compare(launcher.lastSelectedApplication, ""); |
2670 | + |
2671 | + launcher.openDrawer(true) |
2672 | + typeString("cam"); |
2673 | + keyClick(Qt.Key_Enter); |
2674 | + |
2675 | + compare(launcher.lastSelectedApplication, "camera-app"); |
2676 | + } |
2677 | + |
2678 | + function test_dragDirectionOnLeftEdgeDrag_data() { |
2679 | + return [ |
2680 | + { tag: "reveal", direction: "right", endState: "drawer" }, |
2681 | + { tag: "cancel", direction: "left", endState: "visible" }, |
2682 | + ] |
2683 | + } |
2684 | + |
2685 | + function test_dragDirectionOnLeftEdgeDrag(data) { |
2686 | + var startX = launcher.dragAreaWidth/2; |
2687 | + var startY = launcher.height/2; |
2688 | + var stopX = startX + units.gu(35); |
2689 | + var endX = stopX + (units.gu(4) * (data.direction === "left" ? -1 : 1)) |
2690 | + |
2691 | + touchFlick(launcher, startX, startY, stopX, startY, true, false); |
2692 | + touchFlick(launcher, stopX, startY, endX, startY, false, true); |
2693 | + |
2694 | + tryCompare(launcher, "state", data.endState) |
2695 | + } |
2696 | + } |
2697 | +} |
2698 | |
2699 | === modified file 'tests/qmltests/Launcher/tst_Launcher.qml' |
2700 | --- tests/qmltests/Launcher/tst_Launcher.qml 2016-11-24 16:06:15 +0000 |
2701 | +++ tests/qmltests/Launcher/tst_Launcher.qml 2016-12-06 13:47:05 +0000 |
2702 | @@ -322,7 +322,7 @@ |
2703 | function revealByEdgePush() { |
2704 | // Place the mouse against the window/screen edge and push beyond the barrier threshold |
2705 | mouseMove(root, 1, root.height / 2); |
2706 | - launcher.pushEdge(EdgeBarrierSettings.pushThreshold * 1.1); |
2707 | + launcher.pushEdge(EdgeBarrierSettings.pushThreshold * .6); |
2708 | |
2709 | var panel = findChild(launcher, "launcherPanel"); |
2710 | verify(!!panel); |
2711 | |
2712 | === modified file 'tests/qmltests/Stage/tst_PhoneStage.qml' |
2713 | --- tests/qmltests/Stage/tst_PhoneStage.qml 2016-10-08 16:45:37 +0000 |
2714 | +++ tests/qmltests/Stage/tst_PhoneStage.qml 2016-12-06 13:47:05 +0000 |
2715 | @@ -334,32 +334,6 @@ |
2716 | tryCompare(firstApp, "focused", true); |
2717 | } |
2718 | |
2719 | - function test_leftEdge_data() { |
2720 | - return [ |
2721 | - { tag: "normal", inSpread: false, leftEdgeDragWidth: units.gu(20), shouldMoveApp: true }, |
2722 | - { tag: "inSpread", inSpread: true, leftEdgeDragWidth: units.gu(5), shouldMoveApp: false } |
2723 | - ] |
2724 | - } |
2725 | - |
2726 | - function test_leftEdge(data) { |
2727 | - addApps(2); |
2728 | - |
2729 | - if (data.inSpread) { |
2730 | - performEdgeSwipeToShowAppSpread(); |
2731 | - } |
2732 | - |
2733 | - var focusedDelegate = findChild(stage, "appDelegate_" + topLevelSurfaceList.idAt(0)); |
2734 | - var currentX = focusedDelegate.x; |
2735 | - |
2736 | - stage.leftEdgeDragProgress = data.leftEdgeDragWidth; |
2737 | - |
2738 | - tryCompare(focusedDelegate, "x", data.shouldMoveApp ? data.leftEdgeDragWidth : currentX); |
2739 | - |
2740 | - stage.leftEdgeDragProgress = 0; |
2741 | - |
2742 | - tryCompare(focusedDelegate, "x", currentX); |
2743 | - } |
2744 | - |
2745 | function test_focusedAppIsTheOnlyRunningApp() { |
2746 | addApps(2); |
2747 | |
2748 | |
2749 | === modified file 'tests/qmltests/tst_OrientedShell.qml' |
2750 | --- tests/qmltests/tst_OrientedShell.qml 2016-11-14 01:39:43 +0000 |
2751 | +++ tests/qmltests/tst_OrientedShell.qml 2016-12-06 13:47:05 +0000 |
2752 | @@ -999,7 +999,7 @@ |
2753 | var rotationStates = findInvisibleChild(orientedShell, "rotationStates"); |
2754 | waitUntilTransitionsEnd(rotationStates); |
2755 | |
2756 | - performLeftEdgeSwipeToSwitchToDash(); |
2757 | + ApplicationManager.requestFocusApplication("unity8-dash"); |
2758 | |
2759 | // Should be back to portrait |
2760 | tryCompare(shell, "transformRotationAngle", 0); |
2761 | @@ -1391,18 +1391,6 @@ |
2762 | waitUntilTransitionsEnd(rotationStates); |
2763 | } |
2764 | |
2765 | - function performLeftEdgeSwipeToSwitchToDash() { |
2766 | - var swipeLength = shell.width * 0.7; |
2767 | - |
2768 | - var touchStartX = 1; |
2769 | - var touchStartY = shell.height / 2; |
2770 | - touchFlick(shell, |
2771 | - touchStartX, touchStartY, |
2772 | - touchStartX + swipeLength, touchStartY); |
2773 | - |
2774 | - tryCompare(ApplicationManager, "focusedApplicationId", "unity8-dash"); |
2775 | - } |
2776 | - |
2777 | function performEdgeSwipeToSwitchToPreviousApp() { |
2778 | // swipe just enough to ensure an app switch action. |
2779 | // If we swipe too much we will trigger the spread mode |
2780 | |
2781 | === modified file 'tests/qmltests/tst_Shell.qml' |
2782 | --- tests/qmltests/tst_Shell.qml 2016-11-22 17:00:33 +0000 |
2783 | +++ tests/qmltests/tst_Shell.qml 2016-12-06 13:47:05 +0000 |
2784 | @@ -605,38 +605,6 @@ |
2785 | compare(ApplicationManager.get(0).appId, "unity8-dash"); |
2786 | } |
2787 | |
2788 | - function test_phoneLeftEdgeDrag_data() { |
2789 | - return [ |
2790 | - {tag: "without launcher", |
2791 | - revealLauncher: false, swipeLength: units.gu(30), appHides: true, focusedApp: "dialer-app", |
2792 | - launcherHides: true, greeterShown: false}, |
2793 | - |
2794 | - {tag: "with launcher", |
2795 | - revealLauncher: true, swipeLength: units.gu(30), appHides: true, focusedApp: "dialer-app", |
2796 | - launcherHides: true, greeterShown: false}, |
2797 | - |
2798 | - {tag: "small swipe", |
2799 | - revealLauncher: false, swipeLength: units.gu(25), appHides: false, focusedApp: "dialer-app", |
2800 | - launcherHides: false, greeterShown: false}, |
2801 | - |
2802 | - {tag: "long swipe", |
2803 | - revealLauncher: false, swipeLength: units.gu(30), appHides: true, focusedApp: "dialer-app", |
2804 | - launcherHides: true, greeterShown: false}, |
2805 | - |
2806 | - {tag: "small swipe with greeter", |
2807 | - revealLauncher: false, swipeLength: units.gu(25), appHides: false, focusedApp: "dialer-app", |
2808 | - launcherHides: false, greeterShown: true}, |
2809 | - |
2810 | - {tag: "long swipe with greeter", |
2811 | - revealLauncher: false, swipeLength: units.gu(30), appHides: true, focusedApp: "dialer-app", |
2812 | - launcherHides: true, greeterShown: true}, |
2813 | - |
2814 | - {tag: "swipe over dash", |
2815 | - revealLauncher: false, swipeLength: units.gu(30), appHides: true, focusedApp: "unity8-dash", |
2816 | - launcherHides: false, greeterShown: false}, |
2817 | - ]; |
2818 | - } |
2819 | - |
2820 | function test_snapDecisionDismissalReturnsFocus() { |
2821 | loadShell("phone"); |
2822 | swipeAwayGreeter(); |
2823 | @@ -701,80 +669,6 @@ |
2824 | mockNotificationsModel.append(n) |
2825 | } |
2826 | |
2827 | - function test_phoneLeftEdgeDrag(data) { |
2828 | - loadShell("phone"); |
2829 | - swipeAwayGreeter(); |
2830 | - dragLauncherIntoView(); |
2831 | - var appSurfaceId = topLevelSurfaceList.nextId; |
2832 | - tapOnAppIconInLauncher(); |
2833 | - waitUntilAppWindowIsFullyLoaded(appSurfaceId); |
2834 | - |
2835 | - var greeter = findChild(shell, "greeter"); |
2836 | - if (data.greeterShown) { |
2837 | - showGreeter(); |
2838 | - } |
2839 | - |
2840 | - if (data.revealLauncher) { |
2841 | - dragLauncherIntoView(); |
2842 | - } |
2843 | - |
2844 | - swipeFromLeftEdge(data.swipeLength); |
2845 | - if (data.appHides) { |
2846 | - waitUntilDashIsFocused(); |
2847 | - tryCompare(greeter, "shown", false); |
2848 | - } else { |
2849 | - tryCompare(greeter, "fullyShown", data.greeterShown); |
2850 | - } |
2851 | - |
2852 | - var launcher = findChild(shell, "launcherPanel"); |
2853 | - tryCompare(launcher, "x", data.launcherHides ? -launcher.width : 0) |
2854 | - |
2855 | - //FIXME: This check fails. Don't understand the rationale behind it. |
2856 | - /* |
2857 | - // Make sure the helper for sliding out the launcher wasn't touched. We want to fade it out here. |
2858 | - var animateTimer = findInvisibleChild(shell, "animateTimer"); |
2859 | - compare(animateTimer.nextState, "visible"); |
2860 | - */ |
2861 | - } |
2862 | - |
2863 | - function test_tabletLeftEdgeDrag_data() { |
2864 | - return [ |
2865 | - {tag: "without password", user: "no-password", loggedIn: true}, |
2866 | - {tag: "with password", user: "has-password", loggedIn: false}, |
2867 | - ] |
2868 | - } |
2869 | - |
2870 | - function test_tabletLeftEdgeDrag(data) { |
2871 | - setLightDMMockMode("full"); |
2872 | - loadShell("tablet"); |
2873 | - |
2874 | - selectUser(data.user) |
2875 | - |
2876 | - swipeFromLeftEdge(shell.width * 0.75) |
2877 | - wait(500) // to give time to handle dash() signal from Launcher |
2878 | - confirmLoggedIn(data.loggedIn) |
2879 | - } |
2880 | - |
2881 | - function test_longLeftEdgeSwipeTakesToAppsAndResetSearchString() { |
2882 | - loadShell("phone"); |
2883 | - swipeAwayGreeter(); |
2884 | - dragLauncherIntoView(); |
2885 | - dashCommunicatorSpy.clear(); |
2886 | - |
2887 | - var appSurfaceId = topLevelSurfaceList.nextId; |
2888 | - tapOnAppIconInLauncher(); |
2889 | - waitUntilAppWindowIsFullyLoaded(appSurfaceId); |
2890 | - |
2891 | - tryCompareFunction(function() { return ApplicationManager.focusedApplicationId !== "unity8-dash"; }, true); |
2892 | - |
2893 | - //Long left swipe |
2894 | - swipeFromLeftEdge(units.gu(30)); |
2895 | - |
2896 | - tryCompare(ApplicationManager, "focusedApplicationId", "unity8-dash"); |
2897 | - |
2898 | - compare(dashCommunicatorSpy.count, 1); |
2899 | - } |
2900 | - |
2901 | function test_ClickUbuntuIconInLauncherTakesToAppsAndResetSearchString() { |
2902 | loadShell("phone"); |
2903 | swipeAwayGreeter(); |
2904 | @@ -913,39 +807,6 @@ |
2905 | LightDM.Users.mockMode = mode; |
2906 | } |
2907 | |
2908 | - /* |
2909 | - Regression test for bug https://bugs.launchpad.net/touch-preview-images/+bug/1193419 |
2910 | - |
2911 | - When the user minimizes an application (left-edge swipe) he should always end up in the |
2912 | - "Applications" scope view. |
2913 | - |
2914 | - Steps: |
2915 | - - reveal launcher and launch an app that covers the dash |
2916 | - - perform long left edge swipe to go minimize the app and go back to the dash. |
2917 | - - verify the setCurrentScope() D-Bus call to the dash has been called for the correct scope id. |
2918 | - */ |
2919 | - function test_minimizingAppTakesToDashApps() { |
2920 | - loadShell("phone"); |
2921 | - swipeAwayGreeter(); |
2922 | - dragLauncherIntoView(); |
2923 | - |
2924 | - // Launch an app from the launcher |
2925 | - var appSurfaceId = topLevelSurfaceList.nextId; |
2926 | - tapOnAppIconInLauncher(); |
2927 | - waitUntilAppWindowIsFullyLoaded(appSurfaceId); |
2928 | - |
2929 | - verify(ApplicationManager.focusedApplicationId !== "unity8-dash") |
2930 | - |
2931 | - dashCommunicatorSpy.clear(); |
2932 | - // Minimize the application we just launched |
2933 | - swipeFromLeftEdge(shell.width * 0.75); |
2934 | - |
2935 | - tryCompare(ApplicationManager, "focusedApplicationId", "unity8-dash"); |
2936 | - |
2937 | - compare(dashCommunicatorSpy.count, 1); |
2938 | - compare(dashCommunicatorSpy.signalArguments[0][0], 0); |
2939 | - } |
2940 | - |
2941 | function test_showInputMethod() { |
2942 | loadShell("phone"); |
2943 | swipeAwayGreeter(); |
2944 | @@ -1166,7 +1027,7 @@ |
2945 | |
2946 | // Place the mouse against the window/screen edge and push beyond the barrier threshold |
2947 | mouseMove(shell, 0, shell.height / 2); |
2948 | - launcher.pushEdge(EdgeBarrierSettings.pushThreshold * 1.1); |
2949 | + launcher.pushEdge(EdgeBarrierSettings.pushThreshold * .8); |
2950 | |
2951 | var panel = findChild(launcher, "launcherPanel"); |
2952 | verify(panel); |
2953 | @@ -1186,9 +1047,7 @@ |
2954 | waitUntilAppWindowIsFullyLoaded(appSurfaceId); |
2955 | |
2956 | // Minimize the application we just launched |
2957 | - swipeFromLeftEdge(shell.width * 0.75); |
2958 | - |
2959 | - waitUntilDashIsFocused(); |
2960 | + swipeFromLeftEdge(units.gu(15)); |
2961 | |
2962 | showGreeter(); |
2963 | |
2964 | |
2965 | === modified file 'tests/qmltests/tst_ShellWithPin.qml' |
2966 | --- tests/qmltests/tst_ShellWithPin.qml 2016-09-22 10:33:39 +0000 |
2967 | +++ tests/qmltests/tst_ShellWithPin.qml 2016-12-06 13:47:05 +0000 |
2968 | @@ -547,71 +547,5 @@ |
2969 | var lockscreen = findChild(shell, "lockscreen"); |
2970 | verify(lockscreen.shown); |
2971 | } |
2972 | - |
2973 | - /* |
2974 | - Regression test for https://bugs.launchpad.net/ubuntu/+source/unity8/+bug/1393447 |
2975 | - |
2976 | - Do a left edge drag that is long enough to start displacing the greeter |
2977 | - but short engough so that the greeter comes back into place once the |
2978 | - finger is lifted. |
2979 | - |
2980 | - In this situation the launcher should remaing fully shown and hide itself |
2981 | - only after its idle timeout is triggered. |
2982 | - */ |
2983 | - function test_shortLeftEdgeSwipeMakesLauncherStayVisible() { |
2984 | - showGreeter(); |
2985 | - |
2986 | - var launcher = testCase.findChild(shell, "launcher") |
2987 | - var launcherPanel = testCase.findChild(launcher, "launcherPanel"); |
2988 | - |
2989 | - var toX = shell.width * 0.45; |
2990 | - touchFlick(shell, |
2991 | - 1 /* fromX */, shell.height * 0.5 /* fromY */, |
2992 | - toX /* toX */, shell.height * 0.5 /* toY */, |
2993 | - true /* beginTouch */, false /* endTouch */, |
2994 | - 50, 100); |
2995 | - |
2996 | - // Launcher must be fully shown by now |
2997 | - tryCompare(launcherPanel, "x", 0); |
2998 | - |
2999 | - // Greeter should be displaced |
3000 | - var coverPage = findChild(shell, "coverPage"); |
3001 | - tryCompareFunction(function() { return coverPage.mapToItem(shell, 0, 0).x > shell.width*0.2; }, true); |
3002 | - |
3003 | - touchRelease(shell, toX, shell.height * 0.5); |
3004 | - |
3005 | - // Upon release the greeter should have slid back into full view |
3006 | - tryCompareFunction(function() { return coverPage.mapToItem(shell, 0, 0).x === 0; }, true); |
3007 | - |
3008 | - // And the launcher should stay fully shown |
3009 | - for (var i = 0; i < 10; ++i) { |
3010 | - wait(50); |
3011 | - compare(launcherPanel.x, 0); |
3012 | - } |
3013 | - } |
3014 | - |
3015 | - function test_longLeftEdgeDrags() { |
3016 | - var coverPage = findChild(shell, "coverPage"); |
3017 | - var lockscreen = findChild(shell, "lockscreen"); |
3018 | - var launcher = findChild(shell, "launcherPanel"); |
3019 | - var galleryApp = ApplicationManager.startApplication("gallery-app"); |
3020 | - tryCompare(shell, "mainApp", galleryApp); |
3021 | - |
3022 | - // Show greeter |
3023 | - showGreeter(); |
3024 | - |
3025 | - // Swipe cover page away |
3026 | - touchFlick(shell, 2, shell.height / 2, units.gu(30), shell.height / 2); |
3027 | - tryCompare(launcher, "x", -launcher.width); |
3028 | - tryCompare(coverPage, "showProgress", 0); |
3029 | - compare(lockscreen.shown, true); |
3030 | - tryCompare(shell, "mainApp", galleryApp); |
3031 | - |
3032 | - // Now attempt a swipe on lockscreen |
3033 | - touchFlick(shell, 2, shell.height / 2, units.gu(30), shell.height / 2); |
3034 | - tryCompare(launcher, "x", 0); |
3035 | - compare(lockscreen.shown, true); |
3036 | - tryCompare(shell, "mainApp", galleryApp); |
3037 | - } |
3038 | } |
3039 | } |
PASSED: Continuous integration, rev:2704 /unity8- jenkins. ubuntu. com/job/ lp-unity8- ci/2524/ /unity8- jenkins. ubuntu. com/job/ build/3329 /unity8- jenkins. ubuntu. com/job/ test-0- autopkgtest/ label=amd64, release= vivid+overlay, testname= qmluitests. sh/1905 /unity8- jenkins. ubuntu. com/job/ test-0- autopkgtest/ label=amd64, release= xenial+ overlay, testname= qmluitests. sh/1905 /unity8- jenkins. ubuntu. com/job/ test-0- autopkgtest/ label=amd64, release= zesty,testname= qmluitests. sh/1905 /unity8- jenkins. ubuntu. com/job/ build-0- fetch/3357 /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=amd64, release= vivid+overlay/ 3209 /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=amd64, release= vivid+overlay/ 3209/artifact/ output/ *zip*/output. zip /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=amd64, release= xenial+ overlay/ 3209 /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=amd64, release= xenial+ overlay/ 3209/artifact/ output/ *zip*/output. zip /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=amd64, release= zesty/3209 /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=amd64, release= zesty/3209/ artifact/ output/ *zip*/output. zip /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=armhf, release= vivid+overlay/ 3209 /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=armhf, release= vivid+overlay/ 3209/artifact/ output/ *zip*/output. zip /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=armhf, release= xenial+ overlay/ 3209 /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=armhf, release= xenial+ overlay/ 3209/artifact/ output/ *zip*/output. zip /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=armhf, release= zesty/3209 /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=armhf, release= zesty/3209/ artifact/ output/ *zip*/output. zip /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=i386, release= vivid+overlay/ 3209 /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=i386, release= vivid+overlay/ 3209/artifact/ output/ *zip*/output. zip /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=i386, release= xenial+ overlay/ 3209 /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=i386, release= xenial+ overlay/ 3209/artifact/ output/ *zip*/output. zip /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=i386, release= zesty/3209 /unity8- jenkins. ubuntu. com/job/ build-2- binpkg/ arch=i386, release= zesty/3209/ artifact/ output/ *zip*/output. zip
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild: /unity8- jenkins. ubuntu. com/job/ lp-unity8- ci/2524/ rebuild
https:/