Merge lp:~mterry/unity8/warn-on-xapp into lp:unity8
- warn-on-xapp
- Merge into trunk
Status: | Work in progress |
---|---|
Proposed branch: | lp:~mterry/unity8/warn-on-xapp |
Merge into: | lp:unity8 |
Prerequisite: | lp:~mzanetti/unity8/modeswitchwarning |
Diff against target: |
752 lines (+258/-45) 27 files modified
CMakeLists.txt (+2/-1) debian/control (+6/-6) plugins/Greeter/Unity/Launcher/CMakeLists.txt (+0/-1) plugins/Greeter/Unity/Launcher/launcheritem.cpp (+14/-0) plugins/Greeter/Unity/Launcher/launcheritem.h (+3/-0) plugins/Greeter/Unity/Launcher/launchermodelas.cpp (+10/-4) plugins/Unity/Launcher/CMakeLists.txt (+0/-1) plugins/Unity/Launcher/desktopfilehandler.cpp (+12/-0) plugins/Unity/Launcher/desktopfilehandler.h (+1/-0) plugins/Unity/Launcher/launcheritem.cpp (+14/-0) plugins/Unity/Launcher/launcheritem.h (+3/-0) plugins/Unity/Launcher/launchermodel.cpp (+30/-22) plugins/Unity/Launcher/launchermodel.h (+1/-1) qml/Components/Dialogs.qml (+26/-4) qml/Components/LegacyAppLaunchWarningDialog.qml (+51/-0) qml/Shell.qml (+9/-0) tests/mocks/Unity/Application/Application.qmltypes (+5/-0) tests/mocks/Unity/Application/ApplicationManager.cpp (+14/-0) tests/mocks/Unity/Application/ApplicationManager.h (+1/-0) tests/mocks/Unity/Launcher/CMakeLists.txt (+0/-2) tests/mocks/Unity/Launcher/MockLauncherItem.cpp (+13/-0) tests/mocks/Unity/Launcher/MockLauncherItem.h (+3/-0) tests/mocks/Unity/Launcher/MockLauncherModel.cpp (+2/-0) tests/plugins/Greeter/Unity/Launcher/CMakeLists.txt (+0/-2) tests/plugins/Unity/Launcher/CMakeLists.txt (+0/-1) tests/plugins/Unity/Launcher/launchermodeltest.cpp (+3/-0) tests/qmltests/tst_Shell.qml (+35/-0) |
To merge this branch: | bzr merge lp:~mterry/unity8/warn-on-xapp |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Unity8 CI Bot | continuous-integration | Needs Fixing | |
Gerry Boland (community) | Needs Fixing | ||
PS Jenkins bot (community) | continuous-integration | Needs Fixing | |
Albert Astals Cid (community) | merges fine | Abstain | |
Michael Zanetti (community) | Needs Information | ||
Review via email: mp+277915@code.launchpad.net |
Commit message
Prevent user from launching legacy xapps when in tablet or phone mode.
Description of the change
Prevent user from launching legacy xapps when in tablet or phone mode.
There are open design questions ("what should the text be?" and "should we make the legacy icons look different?") that I'm waiting on answers for. But this can be reviewed from a technical POV already.
Note that the LauncherItem changes to support isTouchApp aren't used yet. But they might be if Design wants a different look for them.
== Checklist ==
* Are there any related MPs required for this MP to build/function as expected? Please list.
https:/
https:/
https:/
* Did you perform an exploratory manual test run of your code change and any related functionality?
Yes
* Did you make sure that your branch does not contain spurious tags?
Yes
* If you changed the packaging (debian), did you subscribe the ubuntu-unity team to this MP?
I'm on that team
* If you changed the UI, has there been a design review?
Not yet, working on it.
PS Jenkins bot (ps-jenkins) wrote : | # |
Michael Zanetti (mzanetti) wrote : | # |
As discussed on IRC, this probably won't cut it. For instance it won't prevent the dash to launch the app. also anything else can do Qt.openUrlExter
I think the proper way to go would be to extend ApplicationManager to request permission for launching an app with the shell. Let's do a hangout with Gerry regarding this today.
Albert Astals Cid (aacid) wrote : | # |
Text conflict in tests/qmltests/
1 conflicts encountered.
- 2042. By Michael Terry
-
Merge from trunk
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:2042
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Albert Astals Cid (aacid) wrote : | # |
Text conflict in CMakeLists.txt
1 conflicts encountered.
- 2043. By Michael Terry
-
Merge from trunk
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:2043
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 2044. By Michael Terry
-
Update to use new approval API in ApplicationManager
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:2044
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 2045. By Michael Terry
-
Fix typo by actually specifying appId when docking
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:2045
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Albert Astals Cid (aacid) wrote : | # |
Text conflict in CMakeLists.txt
1 conflicts encountered.
Gerry Boland (gerboland) wrote : | # |
=== modified file 'plugins/
+ case RoleAlerting:
+ return item->alerting();
Unrelated to this MP.
=== modified file 'plugins/
Off topic (since I see it being done elsewhere in the file)
+bool DesktopFileHand
+{
+ if (isValid()) {
+ QSettings settings(
+ settings.
+ settings.
+ return settings.
Rest looks ok to me, but would prefer launcher owner have a look.
Creating the QSettings object and parse the desktop file for each property read isn't very efficient. Any idea why we don't just parse it once at DesktopFileHandler creation?
Michael Zanetti (mzanetti) wrote : | # |
> +bool DesktopFileHand
> +{
> + if (isValid()) {
> + QSettings settings(
> + settings.
> + settings.
> + return settings.
> for empty or "false"
>
> Rest looks ok to me, but would prefer launcher owner have a look.
> Creating the QSettings object and parse the desktop file for each property
> read isn't very efficient. Any idea why we don't just parse it once at
> DesktopFileHandler creation?
From the QSettings docs: "Constructing and destroying a QSettings object is very fast."
Michael Zanetti (mzanetti) wrote : | # |
that said, parsing can be costly indeed. However, following the code around it, this is called only once when a launcher item is created. IMO we're ok here.
Michael Terry (mterry) wrote : | # |
Regarding the QSettings, I didn't want to make any big changes because Lukas has a rewrite of that code in https:/
And as mzanetti said, it's one time.
Regarding the unrelated Role switch statement resortings, it's just a bit of cleanup. Everytime a property gets added to the application interface, they need to be added to a bunch of switch statements around the place. And currently, they are all in different orders, which makes it hard to tell if any are missing from one. For example, when adding RoleIsTouchApp for this MP, I noticed that launchermodelas.cpp was missing RoleRecent and RoleAlerting. So I added them here and sorted them to all be the same order, so it's less likely we'll miss future ones. So tangentially related, but not wholly unrelated.
Unity8 CI Bot (unity8-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:2045
https:/
Executed test runs:
Click here to trigger a rebuild:
https:/
Albert Astals Cid (aacid) wrote : | # |
Text conflict in CMakeLists.txt
Text conflict in debian/control
2 conflicts
Unmerged revisions
- 2045. By Michael Terry
-
Fix typo by actually specifying appId when docking
- 2044. By Michael Terry
-
Update to use new approval API in ApplicationManager
- 2043. By Michael Terry
-
Merge from trunk
- 2042. By Michael Terry
-
Merge from trunk
- 2041. By Michael Terry
-
First pass at warning when launching a legacy app
- 2040. By Michael Terry
-
Merge in mzanetti's modeswitchwarning branch, we'll use a similar dialog
Preview Diff
1 | === modified file 'CMakeLists.txt' |
2 | --- CMakeLists.txt 2015-11-26 13:51:24 +0000 |
3 | +++ CMakeLists.txt 2015-12-02 17:26:09 +0000 |
4 | @@ -57,7 +57,8 @@ |
5 | find_package(Qt5Concurrent 5.4 REQUIRED) |
6 | find_package(Qt5Sql 5.4 REQUIRED) |
7 | |
8 | -pkg_check_modules(APPLICATION_API REQUIRED unity-shell-application=11) |
9 | +pkg_check_modules(APPLICATION_API REQUIRED unity-shell-application=12) |
10 | +pkg_check_modules(LAUNCHER_API REQUIRED unity-shell-launcher=8) |
11 | |
12 | # Standard install paths |
13 | include(GNUInstallDirs) |
14 | |
15 | === modified file 'debian/control' |
16 | --- debian/control 2015-11-26 13:51:24 +0000 |
17 | +++ debian/control 2015-12-02 17:26:09 +0000 |
18 | @@ -29,7 +29,7 @@ |
19 | libqt5xmlpatterns5-dev, |
20 | libsystemsettings-dev, |
21 | libudev-dev, |
22 | - libunity-api-dev (>= 7.103), |
23 | + libunity-api-dev (>= 7.104), |
24 | libusermetricsoutput1-dev, |
25 | libxcb1-dev, |
26 | pkg-config, |
27 | @@ -98,11 +98,11 @@ |
28 | qml-module-qtquick-xmllistmodel, |
29 | qml-module-qtsysteminfo, |
30 | qtdeclarative5-gsettings1.0, |
31 | - qtdeclarative5-qtmir-plugin (>= 0.4.5), |
32 | + qtdeclarative5-qtmir-plugin (>= 0.4.7), |
33 | qtdeclarative5-ubuntu-telephony0.1, |
34 | qtdeclarative5-ubuntu-web-plugin, |
35 | ubuntu-system-settings, |
36 | - unity-launcher-impl-7, |
37 | + unity-launcher-impl-8, |
38 | unity8-common (= ${source:Version}), |
39 | unity8-private (= ${binary:Version}), |
40 | unity8-private | unity-launcher-impl, |
41 | @@ -128,7 +128,7 @@ |
42 | qtdeclarative5-ubuntu-ui-toolkit-plugin (>= 1.3.1627) | qtdeclarative5-ubuntu-ui-toolkit-plugin-gles (>= 1.3.1627), |
43 | qtdeclarative5-unity-notifications-plugin (>= 0.1.2) | unity-notifications-impl, |
44 | ubuntu-thumbnailer-impl-0, |
45 | - unity-application-impl-11, |
46 | + unity-application-impl-12, |
47 | unity-notifications-impl-3, |
48 | unity-plugin-scopes | unity-scopes-impl, |
49 | unity-scopes-impl-7, |
50 | @@ -174,7 +174,7 @@ |
51 | Depends: ${misc:Depends}, |
52 | ${shlibs:Depends}, |
53 | Provides: unity-application-impl, |
54 | - unity-application-impl-11, |
55 | + unity-application-impl-12, |
56 | Replaces: unity8-autopilot (<< 8.02+15.04.20150422-0ubuntu1) |
57 | Description: Fake environment for running Unity 8 shell |
58 | Provides fake implementations of some QML modules used by Unity 8 shell |
59 | @@ -192,7 +192,7 @@ |
60 | ${misc:Depends}, |
61 | ${shlibs:Depends}, |
62 | Provides: unity-launcher-impl, |
63 | - unity-launcher-impl-7, |
64 | + unity-launcher-impl-8, |
65 | Description: Unity 8 private libs |
66 | The Unity 8 shell is the primary user interface for Ubuntu devices. |
67 | . |
68 | |
69 | === modified file 'plugins/Greeter/Unity/Launcher/CMakeLists.txt' |
70 | --- plugins/Greeter/Unity/Launcher/CMakeLists.txt 2015-08-03 13:47:44 +0000 |
71 | +++ plugins/Greeter/Unity/Launcher/CMakeLists.txt 2015-12-02 17:26:09 +0000 |
72 | @@ -1,4 +1,3 @@ |
73 | -pkg_check_modules(LAUNCHER_API REQUIRED unity-shell-launcher=7) |
74 | pkg_check_modules(GSETTINGS_QT REQUIRED gsettings-qt) |
75 | |
76 | add_definitions(-DSM_BUSNAME=systemBus) |
77 | |
78 | === modified file 'plugins/Greeter/Unity/Launcher/launcheritem.cpp' |
79 | --- plugins/Greeter/Unity/Launcher/launcheritem.cpp 2015-09-14 09:11:08 +0000 |
80 | +++ plugins/Greeter/Unity/Launcher/launcheritem.cpp 2015-12-02 17:26:09 +0000 |
81 | @@ -32,6 +32,7 @@ |
82 | m_countVisible(false), |
83 | m_focused(false), |
84 | m_alerting(false), |
85 | + m_isTouchApp(false), |
86 | m_quickList(new QuickListModel(this)) |
87 | { |
88 | QuickListEntry nameAction; |
89 | @@ -179,6 +180,19 @@ |
90 | } |
91 | } |
92 | |
93 | +bool LauncherItem::isTouchApp() const |
94 | +{ |
95 | + return m_isTouchApp; |
96 | +} |
97 | + |
98 | +void LauncherItem::setIsTouchApp(bool isTouchApp) |
99 | +{ |
100 | + if (m_isTouchApp != isTouchApp) { |
101 | + m_isTouchApp = isTouchApp; |
102 | + Q_EMIT isTouchAppChanged(isTouchApp); |
103 | + } |
104 | +} |
105 | + |
106 | unity::shell::launcher::QuickListModelInterface *LauncherItem::quickList() const |
107 | { |
108 | return m_quickList; |
109 | |
110 | === modified file 'plugins/Greeter/Unity/Launcher/launcheritem.h' |
111 | --- plugins/Greeter/Unity/Launcher/launcheritem.h 2015-06-02 13:50:46 +0000 |
112 | +++ plugins/Greeter/Unity/Launcher/launcheritem.h 2015-12-02 17:26:09 +0000 |
113 | @@ -42,6 +42,7 @@ |
114 | bool countVisible() const override; |
115 | bool focused() const override; |
116 | bool alerting() const override; |
117 | + bool isTouchApp() const override; |
118 | |
119 | unity::shell::launcher::QuickListModelInterface *quickList() const override; |
120 | |
121 | @@ -56,6 +57,7 @@ |
122 | void setCountVisible(bool countVisible); |
123 | void setFocused(bool focused); |
124 | void setAlerting(bool alerting); |
125 | + void setIsTouchApp(bool isTouchApp); |
126 | |
127 | |
128 | private: |
129 | @@ -70,6 +72,7 @@ |
130 | bool m_countVisible; |
131 | bool m_focused; |
132 | bool m_alerting; |
133 | + bool m_isTouchApp; |
134 | QuickListModel *m_quickList; |
135 | |
136 | friend class LauncherModel; |
137 | |
138 | === modified file 'plugins/Greeter/Unity/Launcher/launchermodelas.cpp' |
139 | --- plugins/Greeter/Unity/Launcher/launchermodelas.cpp 2015-10-26 14:05:14 +0000 |
140 | +++ plugins/Greeter/Unity/Launcher/launchermodelas.cpp 2015-12-02 17:26:09 +0000 |
141 | @@ -59,16 +59,22 @@ |
142 | return item->icon(); |
143 | case RolePinned: |
144 | return item->pinned(); |
145 | + case RoleRunning: |
146 | + return item->running(); |
147 | + case RoleRecent: |
148 | + return item->recent(); |
149 | + case RoleProgress: |
150 | + return item->progress(); |
151 | case RoleCount: |
152 | return item->count(); |
153 | case RoleCountVisible: |
154 | return item->countVisible(); |
155 | - case RoleProgress: |
156 | - return item->progress(); |
157 | case RoleFocused: |
158 | return item->focused(); |
159 | - case RoleRunning: |
160 | - return item->running(); |
161 | + case RoleAlerting: |
162 | + return item->alerting(); |
163 | + case RoleIsTouchApp: |
164 | + return item->isTouchApp(); |
165 | } |
166 | |
167 | return QVariant(); |
168 | |
169 | === modified file 'plugins/Unity/Launcher/CMakeLists.txt' |
170 | --- plugins/Unity/Launcher/CMakeLists.txt 2015-08-03 13:47:44 +0000 |
171 | +++ plugins/Unity/Launcher/CMakeLists.txt 2015-12-02 17:26:09 +0000 |
172 | @@ -1,4 +1,3 @@ |
173 | -pkg_check_modules(LAUNCHER_API REQUIRED unity-shell-launcher=7) |
174 | pkg_check_modules(GSETTINGS_QT REQUIRED gsettings-qt) |
175 | |
176 | add_definitions(-DSM_BUSNAME=systemBus) |
177 | |
178 | === modified file 'plugins/Unity/Launcher/desktopfilehandler.cpp' |
179 | --- plugins/Unity/Launcher/desktopfilehandler.cpp 2015-09-30 12:43:53 +0000 |
180 | +++ plugins/Unity/Launcher/desktopfilehandler.cpp 2015-12-02 17:26:09 +0000 |
181 | @@ -57,6 +57,18 @@ |
182 | return !m_filename.isEmpty(); |
183 | } |
184 | |
185 | +bool DesktopFileHandler::isTouchApp() const |
186 | +{ |
187 | + if (isValid()) { |
188 | + QSettings settings(m_filename, QSettings::IniFormat); |
189 | + settings.setIniCodec("UTF-8"); |
190 | + settings.beginGroup(QStringLiteral("Desktop Entry")); |
191 | + return settings.value(QStringLiteral("X-Ubuntu-Touch")).toBool(); // false for empty or "false" |
192 | + } else { |
193 | + return false; |
194 | + } |
195 | +} |
196 | + |
197 | void DesktopFileHandler::load() |
198 | { |
199 | m_filename.clear(); |
200 | |
201 | === modified file 'plugins/Unity/Launcher/desktopfilehandler.h' |
202 | --- plugins/Unity/Launcher/desktopfilehandler.h 2014-09-02 17:45:50 +0000 |
203 | +++ plugins/Unity/Launcher/desktopfilehandler.h 2015-12-02 17:26:09 +0000 |
204 | @@ -42,6 +42,7 @@ |
205 | void setAppId(const QString &appId); |
206 | |
207 | bool isValid() const; |
208 | + bool isTouchApp() const; |
209 | QString filename() const; |
210 | QString displayName() const; |
211 | QString icon() const; |
212 | |
213 | === modified file 'plugins/Unity/Launcher/launcheritem.cpp' |
214 | --- plugins/Unity/Launcher/launcheritem.cpp 2015-09-14 09:11:08 +0000 |
215 | +++ plugins/Unity/Launcher/launcheritem.cpp 2015-12-02 17:26:09 +0000 |
216 | @@ -35,6 +35,7 @@ |
217 | m_countVisible(false), |
218 | m_focused(false), |
219 | m_alerting(false), |
220 | + m_isTouchApp(false), |
221 | m_quickList(new QuickListModel(this)) |
222 | { |
223 | QuickListEntry nameAction; |
224 | @@ -212,6 +213,19 @@ |
225 | } |
226 | } |
227 | |
228 | +bool LauncherItem::isTouchApp() const |
229 | +{ |
230 | + return m_isTouchApp; |
231 | +} |
232 | + |
233 | +void LauncherItem::setIsTouchApp(bool isTouchApp) |
234 | +{ |
235 | + if (m_isTouchApp != isTouchApp) { |
236 | + m_isTouchApp = isTouchApp; |
237 | + Q_EMIT isTouchAppChanged(isTouchApp); |
238 | + } |
239 | +} |
240 | + |
241 | unity::shell::launcher::QuickListModelInterface *LauncherItem::quickList() const |
242 | { |
243 | return m_quickList; |
244 | |
245 | === modified file 'plugins/Unity/Launcher/launcheritem.h' |
246 | --- plugins/Unity/Launcher/launcheritem.h 2015-07-23 14:13:57 +0000 |
247 | +++ plugins/Unity/Launcher/launcheritem.h 2015-12-02 17:26:09 +0000 |
248 | @@ -45,6 +45,7 @@ |
249 | bool countVisible() const override; |
250 | bool focused() const override; |
251 | bool alerting() const override; |
252 | + bool isTouchApp() const override; |
253 | |
254 | unity::shell::launcher::QuickListModelInterface *quickList() const override; |
255 | |
256 | @@ -59,6 +60,7 @@ |
257 | void setCountVisible(bool countVisible); |
258 | void setFocused(bool focused); |
259 | void setAlerting(bool alerting); |
260 | + void setIsTouchApp(bool isTouchApp); |
261 | |
262 | private: |
263 | QString m_appId; |
264 | @@ -72,6 +74,7 @@ |
265 | bool m_countVisible; |
266 | bool m_focused; |
267 | bool m_alerting; |
268 | + bool m_isTouchApp; |
269 | QuickListModel *m_quickList; |
270 | QuickListEntry m_quitAction; |
271 | |
272 | |
273 | === modified file 'plugins/Unity/Launcher/launchermodel.cpp' |
274 | --- plugins/Unity/Launcher/launchermodel.cpp 2015-09-14 09:11:08 +0000 |
275 | +++ plugins/Unity/Launcher/launchermodel.cpp 2015-12-02 17:26:09 +0000 |
276 | @@ -76,18 +76,22 @@ |
277 | return item->icon(); |
278 | case RolePinned: |
279 | return item->pinned(); |
280 | + case RoleRunning: |
281 | + return item->running(); |
282 | + case RoleRecent: |
283 | + return item->recent(); |
284 | + case RoleProgress: |
285 | + return item->progress(); |
286 | case RoleCount: |
287 | return item->count(); |
288 | case RoleCountVisible: |
289 | return item->countVisible(); |
290 | - case RoleProgress: |
291 | - return item->progress(); |
292 | case RoleFocused: |
293 | return item->focused(); |
294 | case RoleAlerting: |
295 | return item->alerting(); |
296 | - case RoleRunning: |
297 | - return item->running(); |
298 | + case RoleIsTouchApp: |
299 | + return item->isTouchApp(); |
300 | default: |
301 | qWarning() << Q_FUNC_INFO << "missing role, implement me"; |
302 | return QVariant(); |
303 | @@ -147,6 +151,21 @@ |
304 | } |
305 | } |
306 | |
307 | +LauncherItem *LauncherModel::loadLauncherItem(const QString &appId) |
308 | +{ |
309 | + DesktopFileHandler desktopFile(appId); |
310 | + if (!desktopFile.isValid()) { |
311 | + return nullptr; |
312 | + } |
313 | + |
314 | + LauncherItem *item = new LauncherItem(appId, |
315 | + desktopFile.displayName(), |
316 | + desktopFile.icon(), |
317 | + this); |
318 | + item->setIsTouchApp(desktopFile.isTouchApp()); |
319 | + return item; |
320 | +} |
321 | + |
322 | void LauncherModel::pin(const QString &appId, int index) |
323 | { |
324 | int currentIndex = findApplication(appId); |
325 | @@ -166,17 +185,13 @@ |
326 | index = m_list.count(); |
327 | } |
328 | |
329 | - DesktopFileHandler desktopFile(appId); |
330 | - if (!desktopFile.isValid()) { |
331 | + LauncherItem *item = loadLauncherItem(appId); |
332 | + if (!item) { |
333 | qWarning() << "Can't pin this application, there is no .desktop file available."; |
334 | return; |
335 | } |
336 | |
337 | beginInsertRows(QModelIndex(), index, index); |
338 | - LauncherItem *item = new LauncherItem(appId, |
339 | - desktopFile.displayName(), |
340 | - desktopFile.icon(), |
341 | - this); |
342 | item->setPinned(true); |
343 | m_list.insert(index, item); |
344 | endInsertRows(); |
345 | @@ -385,11 +400,8 @@ |
346 | } |
347 | } else { |
348 | // Need to create a new LauncherItem and show the highlight |
349 | - DesktopFileHandler desktopFile(appId); |
350 | - if (countVisible && desktopFile.isValid()) { |
351 | - LauncherItem *item = new LauncherItem(appId, |
352 | - desktopFile.displayName(), |
353 | - desktopFile.icon()); |
354 | + LauncherItem *item = loadLauncherItem(appId); |
355 | + if (countVisible && item) { |
356 | item->setCountVisible(true); |
357 | beginInsertRows(QModelIndex(), m_list.count(), m_list.count()); |
358 | m_list.append(item); |
359 | @@ -447,16 +459,12 @@ |
360 | if (itemIndex == -1) { |
361 | // Need to add it. Just add it into the addedIndex to keep same ordering as the list |
362 | // in the settings. |
363 | - DesktopFileHandler desktopFile(entry); |
364 | - if (!desktopFile.isValid()) { |
365 | + LauncherItem *item = loadLauncherItem(entry); |
366 | + if (!item) { |
367 | qWarning() << "Couldn't find a .desktop file for" << entry << ". Skipping..."; |
368 | continue; |
369 | } |
370 | |
371 | - LauncherItem *item = new LauncherItem(entry, |
372 | - desktopFile.displayName(), |
373 | - desktopFile.icon(), |
374 | - this); |
375 | item->setPinned(true); |
376 | beginInsertRows(QModelIndex(), addedIndex, addedIndex); |
377 | m_list.insert(addedIndex, item); |
378 | @@ -521,7 +529,7 @@ |
379 | item->setRecent(true); |
380 | item->setRunning(true); |
381 | item->setFocused(app->focused()); |
382 | - |
383 | + item->setIsTouchApp(app->isTouchApp()); |
384 | beginInsertRows(QModelIndex(), m_list.count(), m_list.count()); |
385 | m_list.append(item); |
386 | endInsertRows(); |
387 | |
388 | === modified file 'plugins/Unity/Launcher/launchermodel.h' |
389 | --- plugins/Unity/Launcher/launchermodel.h 2015-07-29 12:32:57 +0000 |
390 | +++ plugins/Unity/Launcher/launchermodel.h 2015-12-02 17:26:09 +0000 |
391 | @@ -68,8 +68,8 @@ |
392 | |
393 | private: |
394 | void storeAppList(); |
395 | - |
396 | void unpin(const QString &appId); |
397 | + LauncherItem *loadLauncherItem(const QString &appId); |
398 | |
399 | private Q_SLOTS: |
400 | void countChanged(const QString &appId, int count); |
401 | |
402 | === modified file 'qml/Components/Dialogs.qml' |
403 | --- qml/Components/Dialogs.qml 2015-11-06 10:06:58 +0000 |
404 | +++ qml/Components/Dialogs.qml 2015-12-02 17:26:09 +0000 |
405 | @@ -46,6 +46,19 @@ |
406 | d.showPowerDialog(); |
407 | } |
408 | |
409 | + function showLegacyAppLaunchDialog(appId) { |
410 | + if (usageScenario != "desktop" && !d.legacyAppLaunchWarningPopup) { |
411 | + var comp = Qt.createComponent(Qt.resolvedUrl("LegacyAppLaunchWarningDialog.qml")) |
412 | + d.legacyAppLaunchWarningPopup = comp.createObject(root, {appId: appId}); |
413 | + d.legacyAppLaunchWarningPopup.cancel.connect(function() { |
414 | + ApplicationManager.approveApplicationStart(d.legacyAppLaunchWarningPopup.appId, false); |
415 | + d.legacyAppLaunchWarningPopup.hide(); |
416 | + d.legacyAppLaunchWarningPopup.destroy(); |
417 | + d.legacyAppLaunchWarningPopup = null; |
418 | + }); |
419 | + } |
420 | + } |
421 | + |
422 | onUsageScenarioChanged: { |
423 | if (usageScenario != "desktop" && legacyAppsModel.count > 0 && !d.modeSwitchWarningPopup) { |
424 | var comp = Qt.createComponent(Qt.resolvedUrl("ModeSwitchWarningDialog.qml")) |
425 | @@ -58,10 +71,18 @@ |
426 | d.modeSwitchWarningPopup.destroy(); |
427 | d.modeSwitchWarningPopup = null; |
428 | }) |
429 | - } else if (usageScenario == "desktop" && d.modeSwitchWarningPopup) { |
430 | - d.modeSwitchWarningPopup.hide(); |
431 | - d.modeSwitchWarningPopup.destroy(); |
432 | - d.modeSwitchWarningPopup = null; |
433 | + } else if (usageScenario == "desktop") { |
434 | + if (d.modeSwitchWarningPopup) { |
435 | + d.modeSwitchWarningPopup.hide(); |
436 | + d.modeSwitchWarningPopup.destroy(); |
437 | + d.modeSwitchWarningPopup = null; |
438 | + } |
439 | + if (d.legacyAppLaunchWarningPopup) { |
440 | + ApplicationManager.approveApplicationStart(d.legacyAppLaunchWarningPopup.appId, true); |
441 | + d.legacyAppLaunchWarningPopup.hide(); |
442 | + d.legacyAppLaunchWarningPopup.destroy(); |
443 | + d.legacyAppLaunchWarningPopup = null; |
444 | + } |
445 | } |
446 | } |
447 | |
448 | @@ -118,6 +139,7 @@ |
449 | objectName: "dialogsPrivate" |
450 | |
451 | property var modeSwitchWarningPopup: null |
452 | + property var legacyAppLaunchWarningPopup: null |
453 | |
454 | function showPowerDialog() { |
455 | if (!dialogLoader.active) { |
456 | |
457 | === added file 'qml/Components/LegacyAppLaunchWarningDialog.qml' |
458 | --- qml/Components/LegacyAppLaunchWarningDialog.qml 1970-01-01 00:00:00 +0000 |
459 | +++ qml/Components/LegacyAppLaunchWarningDialog.qml 2015-12-02 17:26:09 +0000 |
460 | @@ -0,0 +1,51 @@ |
461 | +/* |
462 | + * Copyright (C) 2015 Canonical, Ltd. |
463 | + * |
464 | + * This program is free software; you can redistribute it and/or modify |
465 | + * it under the terms of the GNU General Public License as published by |
466 | + * the Free Software Foundation; version 3. |
467 | + * |
468 | + * This program is distributed in the hope that it will be useful, |
469 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
470 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
471 | + * GNU General Public License for more details. |
472 | + * |
473 | + * You should have received a copy of the GNU General Public License |
474 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
475 | + */ |
476 | + |
477 | +import QtQuick 2.4 |
478 | +import QtQuick.Layouts 1.1 |
479 | +import Ubuntu.Components 1.3 |
480 | +import Ubuntu.Components.ListItems 1.3 |
481 | + |
482 | +ShellDialog { |
483 | + id: root |
484 | + objectName: "legacyAppLaunchWarningDialog" |
485 | + |
486 | + property string appId |
487 | + |
488 | + signal cancel() |
489 | + |
490 | + Label { |
491 | + text: i18n.tr("Dock your device to open this app") |
492 | + fontSize: "large" |
493 | + wrapMode: Text.Wrap |
494 | + color: "#5D5D5D" |
495 | + } |
496 | + |
497 | + ThinDivider {} |
498 | + |
499 | + RowLayout { |
500 | + layoutDirection: Qt.RightToLeft |
501 | + |
502 | + Button { |
503 | + objectName: "cancelButton" |
504 | + text: i18n.tr("Cancel") |
505 | + color: UbuntuColors.lightGrey |
506 | + onClicked: { |
507 | + root.cancel(); |
508 | + } |
509 | + } |
510 | + } |
511 | +} |
512 | |
513 | === modified file 'qml/Shell.qml' |
514 | --- qml/Shell.qml 2015-11-26 13:28:43 +0000 |
515 | +++ qml/Shell.qml 2015-12-02 17:26:09 +0000 |
516 | @@ -216,6 +216,15 @@ |
517 | onApplicationAdded: { |
518 | launcher.hide(); |
519 | } |
520 | + |
521 | + onApplicationStartApprovalRequested: { |
522 | + var app = ApplicationManager.findApplication(appId); |
523 | + if (!app.isTouchApp && shell.usageScenario !== "desktop") { |
524 | + dialogs.showLegacyAppLaunchDialog(appId); |
525 | + } else { |
526 | + ApplicationManager.approveApplicationStart(appId, true); |
527 | + } |
528 | + } |
529 | } |
530 | |
531 | Loader { |
532 | |
533 | === modified file 'tests/mocks/Unity/Application/Application.qmltypes' |
534 | --- tests/mocks/Unity/Application/Application.qmltypes 2015-02-13 09:01:16 +0000 |
535 | +++ tests/mocks/Unity/Application/Application.qmltypes 2015-12-02 17:26:09 +0000 |
536 | @@ -164,6 +164,11 @@ |
537 | type: "bool" |
538 | Parameter { name: "appId"; type: "string" } |
539 | } |
540 | + Method { |
541 | + name: "approveApplicationStart" |
542 | + Parameter { name: "appId"; type: "string" } |
543 | + Parameter { name: "approved"; type: "bool" } |
544 | + } |
545 | Method { name: "availableApplications"; type: "QStringList" } |
546 | Method { |
547 | name: "add" |
548 | |
549 | === modified file 'tests/mocks/Unity/Application/ApplicationManager.cpp' |
550 | --- tests/mocks/Unity/Application/ApplicationManager.cpp 2015-11-05 14:04:32 +0000 |
551 | +++ tests/mocks/Unity/Application/ApplicationManager.cpp 2015-12-02 17:26:09 +0000 |
552 | @@ -219,6 +219,8 @@ |
553 | } |
554 | application->setState(ApplicationInfo::Starting); |
555 | |
556 | + Q_EMIT applicationStartApprovalRequested(appId); |
557 | + |
558 | return application; |
559 | } |
560 | |
561 | @@ -253,6 +255,18 @@ |
562 | return true; |
563 | } |
564 | |
565 | +bool ApplicationManager::approveApplicationStart(const QString &appId, bool approved) |
566 | +{ |
567 | + ApplicationInfo *application = findApplication(appId); |
568 | + if (application == nullptr) |
569 | + return false; |
570 | + |
571 | + if (!approved) { |
572 | + remove(application); |
573 | + } |
574 | + return true; |
575 | +} |
576 | + |
577 | QString ApplicationManager::focusedApplicationId() const { |
578 | for (ApplicationInfo *app : m_runningApplications) { |
579 | if (app->focused()) { |
580 | |
581 | === modified file 'tests/mocks/Unity/Application/ApplicationManager.h' |
582 | --- tests/mocks/Unity/Application/ApplicationManager.h 2015-10-01 17:43:10 +0000 |
583 | +++ tests/mocks/Unity/Application/ApplicationManager.h 2015-12-02 17:26:09 +0000 |
584 | @@ -67,6 +67,7 @@ |
585 | Q_INVOKABLE ApplicationInfo *startApplication(const QString &appId, const QStringList &arguments = QStringList()) override; |
586 | Q_INVOKABLE ApplicationInfo *startApplication(const QString &appId, ExecFlags flags, const QStringList &arguments = QStringList()); |
587 | Q_INVOKABLE bool stopApplication(const QString &appId) override; |
588 | + Q_INVOKABLE bool approveApplicationStart(const QString &appId, bool approved) override; |
589 | |
590 | QString focusedApplicationId() const override; |
591 | |
592 | |
593 | === modified file 'tests/mocks/Unity/Launcher/CMakeLists.txt' |
594 | --- tests/mocks/Unity/Launcher/CMakeLists.txt 2015-07-23 10:31:56 +0000 |
595 | +++ tests/mocks/Unity/Launcher/CMakeLists.txt 2015-12-02 17:26:09 +0000 |
596 | @@ -1,5 +1,3 @@ |
597 | -pkg_check_modules(LAUNCHER_API REQUIRED unity-shell-launcher=7) |
598 | - |
599 | include_directories( |
600 | ${CMAKE_CURRENT_SOURCE_DIR} |
601 | ) |
602 | |
603 | === modified file 'tests/mocks/Unity/Launcher/MockLauncherItem.cpp' |
604 | --- tests/mocks/Unity/Launcher/MockLauncherItem.cpp 2015-09-22 10:44:21 +0000 |
605 | +++ tests/mocks/Unity/Launcher/MockLauncherItem.cpp 2015-12-02 17:26:09 +0000 |
606 | @@ -182,6 +182,19 @@ |
607 | } |
608 | } |
609 | |
610 | +bool MockLauncherItem::isTouchApp() const |
611 | +{ |
612 | + return m_isTouchApp; |
613 | +} |
614 | + |
615 | +void MockLauncherItem::setIsTouchApp(bool isTouchApp) |
616 | +{ |
617 | + if (m_isTouchApp != isTouchApp) { |
618 | + m_isTouchApp = isTouchApp; |
619 | + Q_EMIT isTouchAppChanged(isTouchApp); |
620 | + } |
621 | +} |
622 | + |
623 | unity::shell::launcher::QuickListModelInterface *MockLauncherItem::quickList() const |
624 | { |
625 | return m_quickList; |
626 | |
627 | === modified file 'tests/mocks/Unity/Launcher/MockLauncherItem.h' |
628 | --- tests/mocks/Unity/Launcher/MockLauncherItem.h 2015-07-23 14:13:57 +0000 |
629 | +++ tests/mocks/Unity/Launcher/MockLauncherItem.h 2015-12-02 17:26:09 +0000 |
630 | @@ -46,6 +46,7 @@ |
631 | bool countVisible() const override; |
632 | bool focused() const override; |
633 | bool alerting() const override; |
634 | + bool isTouchApp() const override; |
635 | |
636 | unity::shell::launcher::QuickListModelInterface *quickList() const override; |
637 | |
638 | @@ -58,6 +59,7 @@ |
639 | void setCountVisible(bool countVisible); |
640 | void setFocused(bool focused); |
641 | void setAlerting(bool alerting); |
642 | + void setIsTouchApp(bool isTouchApp); |
643 | |
644 | QString m_appId; |
645 | QString m_desktopFile; |
646 | @@ -71,6 +73,7 @@ |
647 | bool m_countVisible; |
648 | bool m_focused; |
649 | bool m_alerting; |
650 | + bool m_isTouchApp; |
651 | MockQuickListModel *m_quickList; |
652 | |
653 | friend class MockLauncherModel; |
654 | |
655 | === modified file 'tests/mocks/Unity/Launcher/MockLauncherModel.cpp' |
656 | --- tests/mocks/Unity/Launcher/MockLauncherModel.cpp 2015-11-04 11:29:16 +0000 |
657 | +++ tests/mocks/Unity/Launcher/MockLauncherModel.cpp 2015-12-02 17:26:09 +0000 |
658 | @@ -117,6 +117,8 @@ |
659 | return item->focused(); |
660 | case RoleAlerting: |
661 | return item->alerting(); |
662 | + case RoleIsTouchApp: |
663 | + return item->isTouchApp(); |
664 | } |
665 | |
666 | return QVariant(); |
667 | |
668 | === modified file 'tests/plugins/Greeter/Unity/Launcher/CMakeLists.txt' |
669 | --- tests/plugins/Greeter/Unity/Launcher/CMakeLists.txt 2015-10-26 14:05:14 +0000 |
670 | +++ tests/plugins/Greeter/Unity/Launcher/CMakeLists.txt 2015-12-02 17:26:09 +0000 |
671 | @@ -1,5 +1,3 @@ |
672 | -pkg_check_modules(LAUNCHER_API REQUIRED unity-shell-launcher=7) |
673 | - |
674 | include_directories( |
675 | ${CMAKE_CURRENT_SOURCE_DIR} |
676 | ${CMAKE_CURRENT_BINARY_DIR} |
677 | |
678 | === modified file 'tests/plugins/Unity/Launcher/CMakeLists.txt' |
679 | --- tests/plugins/Unity/Launcher/CMakeLists.txt 2015-10-26 14:05:14 +0000 |
680 | +++ tests/plugins/Unity/Launcher/CMakeLists.txt 2015-12-02 17:26:09 +0000 |
681 | @@ -1,5 +1,4 @@ |
682 | pkg_check_modules(GSETTINGS_QT REQUIRED gsettings-qt) |
683 | -pkg_check_modules(LAUNCHER_API REQUIRED unity-shell-launcher=7) |
684 | |
685 | include_directories( |
686 | ${CMAKE_CURRENT_SOURCE_DIR} |
687 | |
688 | === modified file 'tests/plugins/Unity/Launcher/launchermodeltest.cpp' |
689 | --- tests/plugins/Unity/Launcher/launchermodeltest.cpp 2015-11-06 13:27:15 +0000 |
690 | +++ tests/plugins/Unity/Launcher/launchermodeltest.cpp 2015-12-02 17:26:09 +0000 |
691 | @@ -101,6 +101,9 @@ |
692 | } |
693 | return false; |
694 | } |
695 | + bool approveApplicationStart(const QString &, bool) override { |
696 | + return true; |
697 | + } |
698 | bool focusApplication(const QString &appId) override { |
699 | Q_FOREACH(MockApp* app, m_list) { |
700 | app->setFocused(app->appId() == appId); |
701 | |
702 | === modified file 'tests/qmltests/tst_Shell.qml' |
703 | --- tests/qmltests/tst_Shell.qml 2015-11-24 17:44:18 +0000 |
704 | +++ tests/qmltests/tst_Shell.qml 2015-12-02 17:26:09 +0000 |
705 | @@ -25,6 +25,7 @@ |
706 | import Unity.Application 0.1 |
707 | import Unity.Connectivity 0.1 |
708 | import Unity.Indicators 0.1 |
709 | +import Unity.Launcher 0.1 |
710 | import Unity.Notifications 1.0 |
711 | import Unity.Test 0.1 |
712 | import Powerd 0.1 |
713 | @@ -1947,5 +1948,39 @@ |
714 | compare(ApplicationManager.findApplication("libreoffice") === null, true); |
715 | } |
716 | } |
717 | + |
718 | + function test_preventOpeningLegacyAppsWithoutDesktop_data() { |
719 | + return [ |
720 | + {tag: "cancel", plug: false }, |
721 | + {tag: "dock", plug: true } |
722 | + ]; |
723 | + } |
724 | + |
725 | + function test_preventOpeningLegacyAppsWithoutDesktop(data) { |
726 | + loadShell("phone"); |
727 | + |
728 | + // Start a legacy app |
729 | + ApplicationManager.startApplication("libreoffice"); |
730 | + |
731 | + // The popup should appear |
732 | + var popup = findChild(root, "legacyAppLaunchWarningDialog"); |
733 | + verify(popup !== null); |
734 | + |
735 | + if (data.plug) { |
736 | + shell.usageScenario = "desktop"; |
737 | + waitForRendering(shell); |
738 | + } else { |
739 | + var cancelButton = findChild(popup, "cancelButton"); |
740 | + mouseClick(cancelButton); |
741 | + waitForRendering(root); |
742 | + } |
743 | + |
744 | + // Popup must be gone now |
745 | + popup = findChild(root, "legacyAppLaunchWarningDialog"); |
746 | + verify(popup === null); |
747 | + |
748 | + // And libreoffice will be started or not depending on user action |
749 | + compare(ApplicationManager.findApplication("libreoffice") !== null, data.plug); |
750 | + } |
751 | } |
752 | } |
FAILED: Continuous integration, rev:2041 jenkins. qa.ubuntu. com/job/ unity8- ci/6743/ jenkins. qa.ubuntu. com/job/ generic- deb-autopilot- vivid-touch/ 5275/console jenkins. qa.ubuntu. com/job/ generic- deb-autopilot- xenial- touch/158/ console jenkins. qa.ubuntu. com/job/ unity-phablet- qmluitests- vivid/1456/ console jenkins. qa.ubuntu. com/job/ unity8- qmluitest- xenial- amd64/158/ console jenkins. qa.ubuntu. com/job/ unity8- vivid-amd64- ci/1350/ console jenkins. qa.ubuntu. com/job/ unity8- vivid-i386- ci/1351/ console jenkins. qa.ubuntu. com/job/ unity8- xenial- amd64-ci/ 157/console jenkins. qa.ubuntu. com/job/ unity8- xenial- i386-ci/ 157/console jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- vivid-armhf/ 5295/console jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- xenial- armhf/158/ console
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/unity8- ci/6743/ rebuild
http://