Merge lp:~mterry/unity8/warn-on-xapp into lp:unity8

Proposed by Michael Terry
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
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://code.launchpad.net/~mterry/unity-api/warn-on-xapp/+merge/277922
 https://code.launchpad.net/~mterry/qtmir/warn-on-xapp/+merge/279172
 https://code.launchpad.net/~mterry/ubuntu-app-launch/warn-on-xapp/+merge/278497

 * 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.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
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.openUrlExternally(legacyApp).

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.

review: Needs Information
Revision history for this message
Albert Astals Cid (aacid) wrote :

Text conflict in tests/qmltests/tst_Shell.qml
1 conflicts encountered.

review: Needs Fixing
lp:~mterry/unity8/warn-on-xapp updated
2042. By Michael Terry

Merge from trunk

Revision history for this message
Michael Terry (mterry) wrote :

Fixed conflicts.

Revision history for this message
Albert Astals Cid (aacid) :
review: Abstain (merges fine)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Albert Astals Cid (aacid) wrote :

Text conflict in CMakeLists.txt
1 conflicts encountered.

review: Needs Fixing
lp:~mterry/unity8/warn-on-xapp updated
2043. By Michael Terry

Merge from trunk

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Albert Astals Cid (aacid) :
review: Abstain (merges fine)
lp:~mterry/unity8/warn-on-xapp updated
2044. By Michael Terry

Update to use new approval API in ApplicationManager

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
lp:~mterry/unity8/warn-on-xapp updated
2045. By Michael Terry

Fix typo by actually specifying appId when docking

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Albert Astals Cid (aacid) wrote :

Text conflict in CMakeLists.txt
1 conflicts encountered.

Revision history for this message
Gerry Boland (gerboland) wrote :

=== modified file 'plugins/Greeter/Unity/Launcher/launchermodelas.cpp'
+ case RoleAlerting:
+ return item->alerting();
Unrelated to this MP.

=== modified file 'plugins/Unity/Launcher/desktopfilehandler.cpp'
Off topic (since I see it being done elsewhere in the file)

+bool DesktopFileHandler::isTouchApp() const
+{
+ if (isValid()) {
+ QSettings settings(m_filename, QSettings::IniFormat);
+ settings.setIniCodec("UTF-8");
+ settings.beginGroup(QStringLiteral("Desktop Entry"));
+ return settings.value(QStringLiteral("X-Ubuntu-Touch")).toBool(); // false 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?

review: Needs Fixing
Revision history for this message
Michael Zanetti (mzanetti) wrote :

> +bool DesktopFileHandler::isTouchApp() const
> +{
> + if (isValid()) {
> + QSettings settings(m_filename, QSettings::IniFormat);
> + settings.setIniCodec("UTF-8");
> + settings.beginGroup(QStringLiteral("Desktop Entry"));
> + return settings.value(QStringLiteral("X-Ubuntu-Touch")).toBool(); // false
> 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."

Revision history for this message
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.

Revision history for this message
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://code.launchpad.net/~lukas-kde/unity8/desktopFileActions/+merge/276408 which converts to GKeyFile.

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.

Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote :

FAILED: Continuous integration, rev:2045
https://unity8-jenkins.ubuntu.com/job/lp-unity8-1-ci/28/
Executed test runs:

Click here to trigger a rebuild:
https://unity8-jenkins.ubuntu.com/job/lp-unity8-1-ci/28/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
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

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'CMakeLists.txt'
--- CMakeLists.txt 2015-11-26 13:51:24 +0000
+++ CMakeLists.txt 2015-12-02 17:26:09 +0000
@@ -57,7 +57,8 @@
57find_package(Qt5Concurrent 5.4 REQUIRED)57find_package(Qt5Concurrent 5.4 REQUIRED)
58find_package(Qt5Sql 5.4 REQUIRED)58find_package(Qt5Sql 5.4 REQUIRED)
5959
60pkg_check_modules(APPLICATION_API REQUIRED unity-shell-application=11)60pkg_check_modules(APPLICATION_API REQUIRED unity-shell-application=12)
61pkg_check_modules(LAUNCHER_API REQUIRED unity-shell-launcher=8)
6162
62# Standard install paths63# Standard install paths
63include(GNUInstallDirs)64include(GNUInstallDirs)
6465
=== modified file 'debian/control'
--- debian/control 2015-11-26 13:51:24 +0000
+++ debian/control 2015-12-02 17:26:09 +0000
@@ -29,7 +29,7 @@
29 libqt5xmlpatterns5-dev,29 libqt5xmlpatterns5-dev,
30 libsystemsettings-dev,30 libsystemsettings-dev,
31 libudev-dev,31 libudev-dev,
32 libunity-api-dev (>= 7.103),32 libunity-api-dev (>= 7.104),
33 libusermetricsoutput1-dev,33 libusermetricsoutput1-dev,
34 libxcb1-dev,34 libxcb1-dev,
35 pkg-config,35 pkg-config,
@@ -98,11 +98,11 @@
98 qml-module-qtquick-xmllistmodel,98 qml-module-qtquick-xmllistmodel,
99 qml-module-qtsysteminfo,99 qml-module-qtsysteminfo,
100 qtdeclarative5-gsettings1.0,100 qtdeclarative5-gsettings1.0,
101 qtdeclarative5-qtmir-plugin (>= 0.4.5),101 qtdeclarative5-qtmir-plugin (>= 0.4.7),
102 qtdeclarative5-ubuntu-telephony0.1,102 qtdeclarative5-ubuntu-telephony0.1,
103 qtdeclarative5-ubuntu-web-plugin,103 qtdeclarative5-ubuntu-web-plugin,
104 ubuntu-system-settings,104 ubuntu-system-settings,
105 unity-launcher-impl-7,105 unity-launcher-impl-8,
106 unity8-common (= ${source:Version}),106 unity8-common (= ${source:Version}),
107 unity8-private (= ${binary:Version}),107 unity8-private (= ${binary:Version}),
108 unity8-private | unity-launcher-impl,108 unity8-private | unity-launcher-impl,
@@ -128,7 +128,7 @@
128 qtdeclarative5-ubuntu-ui-toolkit-plugin (>= 1.3.1627) | qtdeclarative5-ubuntu-ui-toolkit-plugin-gles (>= 1.3.1627),128 qtdeclarative5-ubuntu-ui-toolkit-plugin (>= 1.3.1627) | qtdeclarative5-ubuntu-ui-toolkit-plugin-gles (>= 1.3.1627),
129 qtdeclarative5-unity-notifications-plugin (>= 0.1.2) | unity-notifications-impl,129 qtdeclarative5-unity-notifications-plugin (>= 0.1.2) | unity-notifications-impl,
130 ubuntu-thumbnailer-impl-0,130 ubuntu-thumbnailer-impl-0,
131 unity-application-impl-11,131 unity-application-impl-12,
132 unity-notifications-impl-3,132 unity-notifications-impl-3,
133 unity-plugin-scopes | unity-scopes-impl,133 unity-plugin-scopes | unity-scopes-impl,
134 unity-scopes-impl-7,134 unity-scopes-impl-7,
@@ -174,7 +174,7 @@
174Depends: ${misc:Depends},174Depends: ${misc:Depends},
175 ${shlibs:Depends},175 ${shlibs:Depends},
176Provides: unity-application-impl,176Provides: unity-application-impl,
177 unity-application-impl-11,177 unity-application-impl-12,
178Replaces: unity8-autopilot (<< 8.02+15.04.20150422-0ubuntu1)178Replaces: unity8-autopilot (<< 8.02+15.04.20150422-0ubuntu1)
179Description: Fake environment for running Unity 8 shell179Description: Fake environment for running Unity 8 shell
180 Provides fake implementations of some QML modules used by Unity 8 shell180 Provides fake implementations of some QML modules used by Unity 8 shell
@@ -192,7 +192,7 @@
192 ${misc:Depends},192 ${misc:Depends},
193 ${shlibs:Depends},193 ${shlibs:Depends},
194Provides: unity-launcher-impl,194Provides: unity-launcher-impl,
195 unity-launcher-impl-7,195 unity-launcher-impl-8,
196Description: Unity 8 private libs196Description: Unity 8 private libs
197 The Unity 8 shell is the primary user interface for Ubuntu devices.197 The Unity 8 shell is the primary user interface for Ubuntu devices.
198 .198 .
199199
=== modified file 'plugins/Greeter/Unity/Launcher/CMakeLists.txt'
--- plugins/Greeter/Unity/Launcher/CMakeLists.txt 2015-08-03 13:47:44 +0000
+++ plugins/Greeter/Unity/Launcher/CMakeLists.txt 2015-12-02 17:26:09 +0000
@@ -1,4 +1,3 @@
1pkg_check_modules(LAUNCHER_API REQUIRED unity-shell-launcher=7)
2pkg_check_modules(GSETTINGS_QT REQUIRED gsettings-qt)1pkg_check_modules(GSETTINGS_QT REQUIRED gsettings-qt)
32
4add_definitions(-DSM_BUSNAME=systemBus)3add_definitions(-DSM_BUSNAME=systemBus)
54
=== modified file 'plugins/Greeter/Unity/Launcher/launcheritem.cpp'
--- plugins/Greeter/Unity/Launcher/launcheritem.cpp 2015-09-14 09:11:08 +0000
+++ plugins/Greeter/Unity/Launcher/launcheritem.cpp 2015-12-02 17:26:09 +0000
@@ -32,6 +32,7 @@
32 m_countVisible(false),32 m_countVisible(false),
33 m_focused(false),33 m_focused(false),
34 m_alerting(false),34 m_alerting(false),
35 m_isTouchApp(false),
35 m_quickList(new QuickListModel(this))36 m_quickList(new QuickListModel(this))
36{37{
37 QuickListEntry nameAction;38 QuickListEntry nameAction;
@@ -179,6 +180,19 @@
179 }180 }
180}181}
181182
183bool LauncherItem::isTouchApp() const
184{
185 return m_isTouchApp;
186}
187
188void LauncherItem::setIsTouchApp(bool isTouchApp)
189{
190 if (m_isTouchApp != isTouchApp) {
191 m_isTouchApp = isTouchApp;
192 Q_EMIT isTouchAppChanged(isTouchApp);
193 }
194}
195
182unity::shell::launcher::QuickListModelInterface *LauncherItem::quickList() const196unity::shell::launcher::QuickListModelInterface *LauncherItem::quickList() const
183{197{
184 return m_quickList;198 return m_quickList;
185199
=== modified file 'plugins/Greeter/Unity/Launcher/launcheritem.h'
--- plugins/Greeter/Unity/Launcher/launcheritem.h 2015-06-02 13:50:46 +0000
+++ plugins/Greeter/Unity/Launcher/launcheritem.h 2015-12-02 17:26:09 +0000
@@ -42,6 +42,7 @@
42 bool countVisible() const override;42 bool countVisible() const override;
43 bool focused() const override;43 bool focused() const override;
44 bool alerting() const override;44 bool alerting() const override;
45 bool isTouchApp() const override;
4546
46 unity::shell::launcher::QuickListModelInterface *quickList() const override;47 unity::shell::launcher::QuickListModelInterface *quickList() const override;
4748
@@ -56,6 +57,7 @@
56 void setCountVisible(bool countVisible);57 void setCountVisible(bool countVisible);
57 void setFocused(bool focused);58 void setFocused(bool focused);
58 void setAlerting(bool alerting);59 void setAlerting(bool alerting);
60 void setIsTouchApp(bool isTouchApp);
5961
6062
61private:63private:
@@ -70,6 +72,7 @@
70 bool m_countVisible;72 bool m_countVisible;
71 bool m_focused;73 bool m_focused;
72 bool m_alerting;74 bool m_alerting;
75 bool m_isTouchApp;
73 QuickListModel *m_quickList;76 QuickListModel *m_quickList;
7477
75 friend class LauncherModel;78 friend class LauncherModel;
7679
=== modified file 'plugins/Greeter/Unity/Launcher/launchermodelas.cpp'
--- plugins/Greeter/Unity/Launcher/launchermodelas.cpp 2015-10-26 14:05:14 +0000
+++ plugins/Greeter/Unity/Launcher/launchermodelas.cpp 2015-12-02 17:26:09 +0000
@@ -59,16 +59,22 @@
59 return item->icon();59 return item->icon();
60 case RolePinned:60 case RolePinned:
61 return item->pinned();61 return item->pinned();
62 case RoleRunning:
63 return item->running();
64 case RoleRecent:
65 return item->recent();
66 case RoleProgress:
67 return item->progress();
62 case RoleCount:68 case RoleCount:
63 return item->count();69 return item->count();
64 case RoleCountVisible:70 case RoleCountVisible:
65 return item->countVisible();71 return item->countVisible();
66 case RoleProgress:
67 return item->progress();
68 case RoleFocused:72 case RoleFocused:
69 return item->focused();73 return item->focused();
70 case RoleRunning:74 case RoleAlerting:
71 return item->running();75 return item->alerting();
76 case RoleIsTouchApp:
77 return item->isTouchApp();
72 }78 }
7379
74 return QVariant();80 return QVariant();
7581
=== modified file 'plugins/Unity/Launcher/CMakeLists.txt'
--- plugins/Unity/Launcher/CMakeLists.txt 2015-08-03 13:47:44 +0000
+++ plugins/Unity/Launcher/CMakeLists.txt 2015-12-02 17:26:09 +0000
@@ -1,4 +1,3 @@
1pkg_check_modules(LAUNCHER_API REQUIRED unity-shell-launcher=7)
2pkg_check_modules(GSETTINGS_QT REQUIRED gsettings-qt)1pkg_check_modules(GSETTINGS_QT REQUIRED gsettings-qt)
32
4add_definitions(-DSM_BUSNAME=systemBus)3add_definitions(-DSM_BUSNAME=systemBus)
54
=== modified file 'plugins/Unity/Launcher/desktopfilehandler.cpp'
--- plugins/Unity/Launcher/desktopfilehandler.cpp 2015-09-30 12:43:53 +0000
+++ plugins/Unity/Launcher/desktopfilehandler.cpp 2015-12-02 17:26:09 +0000
@@ -57,6 +57,18 @@
57 return !m_filename.isEmpty();57 return !m_filename.isEmpty();
58}58}
5959
60bool DesktopFileHandler::isTouchApp() const
61{
62 if (isValid()) {
63 QSettings settings(m_filename, QSettings::IniFormat);
64 settings.setIniCodec("UTF-8");
65 settings.beginGroup(QStringLiteral("Desktop Entry"));
66 return settings.value(QStringLiteral("X-Ubuntu-Touch")).toBool(); // false for empty or "false"
67 } else {
68 return false;
69 }
70}
71
60void DesktopFileHandler::load()72void DesktopFileHandler::load()
61{73{
62 m_filename.clear();74 m_filename.clear();
6375
=== modified file 'plugins/Unity/Launcher/desktopfilehandler.h'
--- plugins/Unity/Launcher/desktopfilehandler.h 2014-09-02 17:45:50 +0000
+++ plugins/Unity/Launcher/desktopfilehandler.h 2015-12-02 17:26:09 +0000
@@ -42,6 +42,7 @@
42 void setAppId(const QString &appId);42 void setAppId(const QString &appId);
4343
44 bool isValid() const;44 bool isValid() const;
45 bool isTouchApp() const;
45 QString filename() const;46 QString filename() const;
46 QString displayName() const;47 QString displayName() const;
47 QString icon() const;48 QString icon() const;
4849
=== modified file 'plugins/Unity/Launcher/launcheritem.cpp'
--- plugins/Unity/Launcher/launcheritem.cpp 2015-09-14 09:11:08 +0000
+++ plugins/Unity/Launcher/launcheritem.cpp 2015-12-02 17:26:09 +0000
@@ -35,6 +35,7 @@
35 m_countVisible(false),35 m_countVisible(false),
36 m_focused(false),36 m_focused(false),
37 m_alerting(false),37 m_alerting(false),
38 m_isTouchApp(false),
38 m_quickList(new QuickListModel(this))39 m_quickList(new QuickListModel(this))
39{40{
40 QuickListEntry nameAction;41 QuickListEntry nameAction;
@@ -212,6 +213,19 @@
212 }213 }
213}214}
214215
216bool LauncherItem::isTouchApp() const
217{
218 return m_isTouchApp;
219}
220
221void LauncherItem::setIsTouchApp(bool isTouchApp)
222{
223 if (m_isTouchApp != isTouchApp) {
224 m_isTouchApp = isTouchApp;
225 Q_EMIT isTouchAppChanged(isTouchApp);
226 }
227}
228
215unity::shell::launcher::QuickListModelInterface *LauncherItem::quickList() const229unity::shell::launcher::QuickListModelInterface *LauncherItem::quickList() const
216{230{
217 return m_quickList;231 return m_quickList;
218232
=== modified file 'plugins/Unity/Launcher/launcheritem.h'
--- plugins/Unity/Launcher/launcheritem.h 2015-07-23 14:13:57 +0000
+++ plugins/Unity/Launcher/launcheritem.h 2015-12-02 17:26:09 +0000
@@ -45,6 +45,7 @@
45 bool countVisible() const override;45 bool countVisible() const override;
46 bool focused() const override;46 bool focused() const override;
47 bool alerting() const override;47 bool alerting() const override;
48 bool isTouchApp() const override;
4849
49 unity::shell::launcher::QuickListModelInterface *quickList() const override;50 unity::shell::launcher::QuickListModelInterface *quickList() const override;
5051
@@ -59,6 +60,7 @@
59 void setCountVisible(bool countVisible);60 void setCountVisible(bool countVisible);
60 void setFocused(bool focused);61 void setFocused(bool focused);
61 void setAlerting(bool alerting);62 void setAlerting(bool alerting);
63 void setIsTouchApp(bool isTouchApp);
6264
63private:65private:
64 QString m_appId;66 QString m_appId;
@@ -72,6 +74,7 @@
72 bool m_countVisible;74 bool m_countVisible;
73 bool m_focused;75 bool m_focused;
74 bool m_alerting;76 bool m_alerting;
77 bool m_isTouchApp;
75 QuickListModel *m_quickList;78 QuickListModel *m_quickList;
76 QuickListEntry m_quitAction;79 QuickListEntry m_quitAction;
7780
7881
=== modified file 'plugins/Unity/Launcher/launchermodel.cpp'
--- plugins/Unity/Launcher/launchermodel.cpp 2015-09-14 09:11:08 +0000
+++ plugins/Unity/Launcher/launchermodel.cpp 2015-12-02 17:26:09 +0000
@@ -76,18 +76,22 @@
76 return item->icon();76 return item->icon();
77 case RolePinned:77 case RolePinned:
78 return item->pinned();78 return item->pinned();
79 case RoleRunning:
80 return item->running();
81 case RoleRecent:
82 return item->recent();
83 case RoleProgress:
84 return item->progress();
79 case RoleCount:85 case RoleCount:
80 return item->count();86 return item->count();
81 case RoleCountVisible:87 case RoleCountVisible:
82 return item->countVisible();88 return item->countVisible();
83 case RoleProgress:
84 return item->progress();
85 case RoleFocused:89 case RoleFocused:
86 return item->focused();90 return item->focused();
87 case RoleAlerting:91 case RoleAlerting:
88 return item->alerting();92 return item->alerting();
89 case RoleRunning:93 case RoleIsTouchApp:
90 return item->running();94 return item->isTouchApp();
91 default:95 default:
92 qWarning() << Q_FUNC_INFO << "missing role, implement me";96 qWarning() << Q_FUNC_INFO << "missing role, implement me";
93 return QVariant();97 return QVariant();
@@ -147,6 +151,21 @@
147 }151 }
148}152}
149153
154LauncherItem *LauncherModel::loadLauncherItem(const QString &appId)
155{
156 DesktopFileHandler desktopFile(appId);
157 if (!desktopFile.isValid()) {
158 return nullptr;
159 }
160
161 LauncherItem *item = new LauncherItem(appId,
162 desktopFile.displayName(),
163 desktopFile.icon(),
164 this);
165 item->setIsTouchApp(desktopFile.isTouchApp());
166 return item;
167}
168
150void LauncherModel::pin(const QString &appId, int index)169void LauncherModel::pin(const QString &appId, int index)
151{170{
152 int currentIndex = findApplication(appId);171 int currentIndex = findApplication(appId);
@@ -166,17 +185,13 @@
166 index = m_list.count();185 index = m_list.count();
167 }186 }
168187
169 DesktopFileHandler desktopFile(appId);188 LauncherItem *item = loadLauncherItem(appId);
170 if (!desktopFile.isValid()) {189 if (!item) {
171 qWarning() << "Can't pin this application, there is no .desktop file available.";190 qWarning() << "Can't pin this application, there is no .desktop file available.";
172 return;191 return;
173 }192 }
174193
175 beginInsertRows(QModelIndex(), index, index);194 beginInsertRows(QModelIndex(), index, index);
176 LauncherItem *item = new LauncherItem(appId,
177 desktopFile.displayName(),
178 desktopFile.icon(),
179 this);
180 item->setPinned(true);195 item->setPinned(true);
181 m_list.insert(index, item);196 m_list.insert(index, item);
182 endInsertRows();197 endInsertRows();
@@ -385,11 +400,8 @@
385 }400 }
386 } else {401 } else {
387 // Need to create a new LauncherItem and show the highlight402 // Need to create a new LauncherItem and show the highlight
388 DesktopFileHandler desktopFile(appId);403 LauncherItem *item = loadLauncherItem(appId);
389 if (countVisible && desktopFile.isValid()) {404 if (countVisible && item) {
390 LauncherItem *item = new LauncherItem(appId,
391 desktopFile.displayName(),
392 desktopFile.icon());
393 item->setCountVisible(true);405 item->setCountVisible(true);
394 beginInsertRows(QModelIndex(), m_list.count(), m_list.count());406 beginInsertRows(QModelIndex(), m_list.count(), m_list.count());
395 m_list.append(item);407 m_list.append(item);
@@ -447,16 +459,12 @@
447 if (itemIndex == -1) {459 if (itemIndex == -1) {
448 // Need to add it. Just add it into the addedIndex to keep same ordering as the list460 // Need to add it. Just add it into the addedIndex to keep same ordering as the list
449 // in the settings.461 // in the settings.
450 DesktopFileHandler desktopFile(entry);462 LauncherItem *item = loadLauncherItem(entry);
451 if (!desktopFile.isValid()) {463 if (!item) {
452 qWarning() << "Couldn't find a .desktop file for" << entry << ". Skipping...";464 qWarning() << "Couldn't find a .desktop file for" << entry << ". Skipping...";
453 continue;465 continue;
454 }466 }
455467
456 LauncherItem *item = new LauncherItem(entry,
457 desktopFile.displayName(),
458 desktopFile.icon(),
459 this);
460 item->setPinned(true);468 item->setPinned(true);
461 beginInsertRows(QModelIndex(), addedIndex, addedIndex);469 beginInsertRows(QModelIndex(), addedIndex, addedIndex);
462 m_list.insert(addedIndex, item);470 m_list.insert(addedIndex, item);
@@ -521,7 +529,7 @@
521 item->setRecent(true);529 item->setRecent(true);
522 item->setRunning(true);530 item->setRunning(true);
523 item->setFocused(app->focused());531 item->setFocused(app->focused());
524532 item->setIsTouchApp(app->isTouchApp());
525 beginInsertRows(QModelIndex(), m_list.count(), m_list.count());533 beginInsertRows(QModelIndex(), m_list.count(), m_list.count());
526 m_list.append(item);534 m_list.append(item);
527 endInsertRows();535 endInsertRows();
528536
=== modified file 'plugins/Unity/Launcher/launchermodel.h'
--- plugins/Unity/Launcher/launchermodel.h 2015-07-29 12:32:57 +0000
+++ plugins/Unity/Launcher/launchermodel.h 2015-12-02 17:26:09 +0000
@@ -68,8 +68,8 @@
6868
69private:69private:
70 void storeAppList();70 void storeAppList();
71
72 void unpin(const QString &appId);71 void unpin(const QString &appId);
72 LauncherItem *loadLauncherItem(const QString &appId);
7373
74private Q_SLOTS:74private Q_SLOTS:
75 void countChanged(const QString &appId, int count);75 void countChanged(const QString &appId, int count);
7676
=== modified file 'qml/Components/Dialogs.qml'
--- qml/Components/Dialogs.qml 2015-11-06 10:06:58 +0000
+++ qml/Components/Dialogs.qml 2015-12-02 17:26:09 +0000
@@ -46,6 +46,19 @@
46 d.showPowerDialog();46 d.showPowerDialog();
47 }47 }
4848
49 function showLegacyAppLaunchDialog(appId) {
50 if (usageScenario != "desktop" && !d.legacyAppLaunchWarningPopup) {
51 var comp = Qt.createComponent(Qt.resolvedUrl("LegacyAppLaunchWarningDialog.qml"))
52 d.legacyAppLaunchWarningPopup = comp.createObject(root, {appId: appId});
53 d.legacyAppLaunchWarningPopup.cancel.connect(function() {
54 ApplicationManager.approveApplicationStart(d.legacyAppLaunchWarningPopup.appId, false);
55 d.legacyAppLaunchWarningPopup.hide();
56 d.legacyAppLaunchWarningPopup.destroy();
57 d.legacyAppLaunchWarningPopup = null;
58 });
59 }
60 }
61
49 onUsageScenarioChanged: {62 onUsageScenarioChanged: {
50 if (usageScenario != "desktop" && legacyAppsModel.count > 0 && !d.modeSwitchWarningPopup) {63 if (usageScenario != "desktop" && legacyAppsModel.count > 0 && !d.modeSwitchWarningPopup) {
51 var comp = Qt.createComponent(Qt.resolvedUrl("ModeSwitchWarningDialog.qml"))64 var comp = Qt.createComponent(Qt.resolvedUrl("ModeSwitchWarningDialog.qml"))
@@ -58,10 +71,18 @@
58 d.modeSwitchWarningPopup.destroy();71 d.modeSwitchWarningPopup.destroy();
59 d.modeSwitchWarningPopup = null;72 d.modeSwitchWarningPopup = null;
60 })73 })
61 } else if (usageScenario == "desktop" && d.modeSwitchWarningPopup) {74 } else if (usageScenario == "desktop") {
62 d.modeSwitchWarningPopup.hide();75 if (d.modeSwitchWarningPopup) {
63 d.modeSwitchWarningPopup.destroy();76 d.modeSwitchWarningPopup.hide();
64 d.modeSwitchWarningPopup = null;77 d.modeSwitchWarningPopup.destroy();
78 d.modeSwitchWarningPopup = null;
79 }
80 if (d.legacyAppLaunchWarningPopup) {
81 ApplicationManager.approveApplicationStart(d.legacyAppLaunchWarningPopup.appId, true);
82 d.legacyAppLaunchWarningPopup.hide();
83 d.legacyAppLaunchWarningPopup.destroy();
84 d.legacyAppLaunchWarningPopup = null;
85 }
65 }86 }
66 }87 }
6788
@@ -118,6 +139,7 @@
118 objectName: "dialogsPrivate"139 objectName: "dialogsPrivate"
119140
120 property var modeSwitchWarningPopup: null141 property var modeSwitchWarningPopup: null
142 property var legacyAppLaunchWarningPopup: null
121143
122 function showPowerDialog() {144 function showPowerDialog() {
123 if (!dialogLoader.active) {145 if (!dialogLoader.active) {
124146
=== added file 'qml/Components/LegacyAppLaunchWarningDialog.qml'
--- qml/Components/LegacyAppLaunchWarningDialog.qml 1970-01-01 00:00:00 +0000
+++ qml/Components/LegacyAppLaunchWarningDialog.qml 2015-12-02 17:26:09 +0000
@@ -0,0 +1,51 @@
1/*
2 * Copyright (C) 2015 Canonical, Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17import QtQuick 2.4
18import QtQuick.Layouts 1.1
19import Ubuntu.Components 1.3
20import Ubuntu.Components.ListItems 1.3
21
22ShellDialog {
23 id: root
24 objectName: "legacyAppLaunchWarningDialog"
25
26 property string appId
27
28 signal cancel()
29
30 Label {
31 text: i18n.tr("Dock your device to open this app")
32 fontSize: "large"
33 wrapMode: Text.Wrap
34 color: "#5D5D5D"
35 }
36
37 ThinDivider {}
38
39 RowLayout {
40 layoutDirection: Qt.RightToLeft
41
42 Button {
43 objectName: "cancelButton"
44 text: i18n.tr("Cancel")
45 color: UbuntuColors.lightGrey
46 onClicked: {
47 root.cancel();
48 }
49 }
50 }
51}
052
=== modified file 'qml/Shell.qml'
--- qml/Shell.qml 2015-11-26 13:28:43 +0000
+++ qml/Shell.qml 2015-12-02 17:26:09 +0000
@@ -216,6 +216,15 @@
216 onApplicationAdded: {216 onApplicationAdded: {
217 launcher.hide();217 launcher.hide();
218 }218 }
219
220 onApplicationStartApprovalRequested: {
221 var app = ApplicationManager.findApplication(appId);
222 if (!app.isTouchApp && shell.usageScenario !== "desktop") {
223 dialogs.showLegacyAppLaunchDialog(appId);
224 } else {
225 ApplicationManager.approveApplicationStart(appId, true);
226 }
227 }
219 }228 }
220229
221 Loader {230 Loader {
222231
=== modified file 'tests/mocks/Unity/Application/Application.qmltypes'
--- tests/mocks/Unity/Application/Application.qmltypes 2015-02-13 09:01:16 +0000
+++ tests/mocks/Unity/Application/Application.qmltypes 2015-12-02 17:26:09 +0000
@@ -164,6 +164,11 @@
164 type: "bool"164 type: "bool"
165 Parameter { name: "appId"; type: "string" }165 Parameter { name: "appId"; type: "string" }
166 }166 }
167 Method {
168 name: "approveApplicationStart"
169 Parameter { name: "appId"; type: "string" }
170 Parameter { name: "approved"; type: "bool" }
171 }
167 Method { name: "availableApplications"; type: "QStringList" }172 Method { name: "availableApplications"; type: "QStringList" }
168 Method {173 Method {
169 name: "add"174 name: "add"
170175
=== modified file 'tests/mocks/Unity/Application/ApplicationManager.cpp'
--- tests/mocks/Unity/Application/ApplicationManager.cpp 2015-11-05 14:04:32 +0000
+++ tests/mocks/Unity/Application/ApplicationManager.cpp 2015-12-02 17:26:09 +0000
@@ -219,6 +219,8 @@
219 }219 }
220 application->setState(ApplicationInfo::Starting);220 application->setState(ApplicationInfo::Starting);
221221
222 Q_EMIT applicationStartApprovalRequested(appId);
223
222 return application;224 return application;
223}225}
224226
@@ -253,6 +255,18 @@
253 return true;255 return true;
254}256}
255257
258bool ApplicationManager::approveApplicationStart(const QString &appId, bool approved)
259{
260 ApplicationInfo *application = findApplication(appId);
261 if (application == nullptr)
262 return false;
263
264 if (!approved) {
265 remove(application);
266 }
267 return true;
268}
269
256QString ApplicationManager::focusedApplicationId() const {270QString ApplicationManager::focusedApplicationId() const {
257 for (ApplicationInfo *app : m_runningApplications) {271 for (ApplicationInfo *app : m_runningApplications) {
258 if (app->focused()) {272 if (app->focused()) {
259273
=== modified file 'tests/mocks/Unity/Application/ApplicationManager.h'
--- tests/mocks/Unity/Application/ApplicationManager.h 2015-10-01 17:43:10 +0000
+++ tests/mocks/Unity/Application/ApplicationManager.h 2015-12-02 17:26:09 +0000
@@ -67,6 +67,7 @@
67 Q_INVOKABLE ApplicationInfo *startApplication(const QString &appId, const QStringList &arguments = QStringList()) override;67 Q_INVOKABLE ApplicationInfo *startApplication(const QString &appId, const QStringList &arguments = QStringList()) override;
68 Q_INVOKABLE ApplicationInfo *startApplication(const QString &appId, ExecFlags flags, const QStringList &arguments = QStringList());68 Q_INVOKABLE ApplicationInfo *startApplication(const QString &appId, ExecFlags flags, const QStringList &arguments = QStringList());
69 Q_INVOKABLE bool stopApplication(const QString &appId) override;69 Q_INVOKABLE bool stopApplication(const QString &appId) override;
70 Q_INVOKABLE bool approveApplicationStart(const QString &appId, bool approved) override;
7071
71 QString focusedApplicationId() const override;72 QString focusedApplicationId() const override;
7273
7374
=== modified file 'tests/mocks/Unity/Launcher/CMakeLists.txt'
--- tests/mocks/Unity/Launcher/CMakeLists.txt 2015-07-23 10:31:56 +0000
+++ tests/mocks/Unity/Launcher/CMakeLists.txt 2015-12-02 17:26:09 +0000
@@ -1,5 +1,3 @@
1pkg_check_modules(LAUNCHER_API REQUIRED unity-shell-launcher=7)
2
3include_directories(1include_directories(
4 ${CMAKE_CURRENT_SOURCE_DIR}2 ${CMAKE_CURRENT_SOURCE_DIR}
5)3)
64
=== modified file 'tests/mocks/Unity/Launcher/MockLauncherItem.cpp'
--- tests/mocks/Unity/Launcher/MockLauncherItem.cpp 2015-09-22 10:44:21 +0000
+++ tests/mocks/Unity/Launcher/MockLauncherItem.cpp 2015-12-02 17:26:09 +0000
@@ -182,6 +182,19 @@
182 }182 }
183}183}
184184
185bool MockLauncherItem::isTouchApp() const
186{
187 return m_isTouchApp;
188}
189
190void MockLauncherItem::setIsTouchApp(bool isTouchApp)
191{
192 if (m_isTouchApp != isTouchApp) {
193 m_isTouchApp = isTouchApp;
194 Q_EMIT isTouchAppChanged(isTouchApp);
195 }
196}
197
185unity::shell::launcher::QuickListModelInterface *MockLauncherItem::quickList() const198unity::shell::launcher::QuickListModelInterface *MockLauncherItem::quickList() const
186{199{
187 return m_quickList;200 return m_quickList;
188201
=== modified file 'tests/mocks/Unity/Launcher/MockLauncherItem.h'
--- tests/mocks/Unity/Launcher/MockLauncherItem.h 2015-07-23 14:13:57 +0000
+++ tests/mocks/Unity/Launcher/MockLauncherItem.h 2015-12-02 17:26:09 +0000
@@ -46,6 +46,7 @@
46 bool countVisible() const override;46 bool countVisible() const override;
47 bool focused() const override;47 bool focused() const override;
48 bool alerting() const override;48 bool alerting() const override;
49 bool isTouchApp() const override;
4950
50 unity::shell::launcher::QuickListModelInterface *quickList() const override;51 unity::shell::launcher::QuickListModelInterface *quickList() const override;
5152
@@ -58,6 +59,7 @@
58 void setCountVisible(bool countVisible);59 void setCountVisible(bool countVisible);
59 void setFocused(bool focused);60 void setFocused(bool focused);
60 void setAlerting(bool alerting);61 void setAlerting(bool alerting);
62 void setIsTouchApp(bool isTouchApp);
6163
62 QString m_appId;64 QString m_appId;
63 QString m_desktopFile;65 QString m_desktopFile;
@@ -71,6 +73,7 @@
71 bool m_countVisible;73 bool m_countVisible;
72 bool m_focused;74 bool m_focused;
73 bool m_alerting;75 bool m_alerting;
76 bool m_isTouchApp;
74 MockQuickListModel *m_quickList;77 MockQuickListModel *m_quickList;
7578
76 friend class MockLauncherModel;79 friend class MockLauncherModel;
7780
=== modified file 'tests/mocks/Unity/Launcher/MockLauncherModel.cpp'
--- tests/mocks/Unity/Launcher/MockLauncherModel.cpp 2015-11-04 11:29:16 +0000
+++ tests/mocks/Unity/Launcher/MockLauncherModel.cpp 2015-12-02 17:26:09 +0000
@@ -117,6 +117,8 @@
117 return item->focused();117 return item->focused();
118 case RoleAlerting:118 case RoleAlerting:
119 return item->alerting();119 return item->alerting();
120 case RoleIsTouchApp:
121 return item->isTouchApp();
120 }122 }
121123
122 return QVariant();124 return QVariant();
123125
=== modified file 'tests/plugins/Greeter/Unity/Launcher/CMakeLists.txt'
--- tests/plugins/Greeter/Unity/Launcher/CMakeLists.txt 2015-10-26 14:05:14 +0000
+++ tests/plugins/Greeter/Unity/Launcher/CMakeLists.txt 2015-12-02 17:26:09 +0000
@@ -1,5 +1,3 @@
1pkg_check_modules(LAUNCHER_API REQUIRED unity-shell-launcher=7)
2
3include_directories(1include_directories(
4 ${CMAKE_CURRENT_SOURCE_DIR}2 ${CMAKE_CURRENT_SOURCE_DIR}
5 ${CMAKE_CURRENT_BINARY_DIR}3 ${CMAKE_CURRENT_BINARY_DIR}
64
=== modified file 'tests/plugins/Unity/Launcher/CMakeLists.txt'
--- tests/plugins/Unity/Launcher/CMakeLists.txt 2015-10-26 14:05:14 +0000
+++ tests/plugins/Unity/Launcher/CMakeLists.txt 2015-12-02 17:26:09 +0000
@@ -1,5 +1,4 @@
1pkg_check_modules(GSETTINGS_QT REQUIRED gsettings-qt)1pkg_check_modules(GSETTINGS_QT REQUIRED gsettings-qt)
2pkg_check_modules(LAUNCHER_API REQUIRED unity-shell-launcher=7)
32
4include_directories(3include_directories(
5 ${CMAKE_CURRENT_SOURCE_DIR}4 ${CMAKE_CURRENT_SOURCE_DIR}
65
=== modified file 'tests/plugins/Unity/Launcher/launchermodeltest.cpp'
--- tests/plugins/Unity/Launcher/launchermodeltest.cpp 2015-11-06 13:27:15 +0000
+++ tests/plugins/Unity/Launcher/launchermodeltest.cpp 2015-12-02 17:26:09 +0000
@@ -101,6 +101,9 @@
101 }101 }
102 return false;102 return false;
103 }103 }
104 bool approveApplicationStart(const QString &, bool) override {
105 return true;
106 }
104 bool focusApplication(const QString &appId) override {107 bool focusApplication(const QString &appId) override {
105 Q_FOREACH(MockApp* app, m_list) {108 Q_FOREACH(MockApp* app, m_list) {
106 app->setFocused(app->appId() == appId);109 app->setFocused(app->appId() == appId);
107110
=== modified file 'tests/qmltests/tst_Shell.qml'
--- tests/qmltests/tst_Shell.qml 2015-11-24 17:44:18 +0000
+++ tests/qmltests/tst_Shell.qml 2015-12-02 17:26:09 +0000
@@ -25,6 +25,7 @@
25import Unity.Application 0.125import Unity.Application 0.1
26import Unity.Connectivity 0.126import Unity.Connectivity 0.1
27import Unity.Indicators 0.127import Unity.Indicators 0.1
28import Unity.Launcher 0.1
28import Unity.Notifications 1.029import Unity.Notifications 1.0
29import Unity.Test 0.130import Unity.Test 0.1
30import Powerd 0.131import Powerd 0.1
@@ -1947,5 +1948,39 @@
1947 compare(ApplicationManager.findApplication("libreoffice") === null, true);1948 compare(ApplicationManager.findApplication("libreoffice") === null, true);
1948 }1949 }
1949 }1950 }
1951
1952 function test_preventOpeningLegacyAppsWithoutDesktop_data() {
1953 return [
1954 {tag: "cancel", plug: false },
1955 {tag: "dock", plug: true }
1956 ];
1957 }
1958
1959 function test_preventOpeningLegacyAppsWithoutDesktop(data) {
1960 loadShell("phone");
1961
1962 // Start a legacy app
1963 ApplicationManager.startApplication("libreoffice");
1964
1965 // The popup should appear
1966 var popup = findChild(root, "legacyAppLaunchWarningDialog");
1967 verify(popup !== null);
1968
1969 if (data.plug) {
1970 shell.usageScenario = "desktop";
1971 waitForRendering(shell);
1972 } else {
1973 var cancelButton = findChild(popup, "cancelButton");
1974 mouseClick(cancelButton);
1975 waitForRendering(root);
1976 }
1977
1978 // Popup must be gone now
1979 popup = findChild(root, "legacyAppLaunchWarningDialog");
1980 verify(popup === null);
1981
1982 // And libreoffice will be started or not depending on user action
1983 compare(ApplicationManager.findApplication("libreoffice") !== null, data.plug);
1984 }
1950 }1985 }
1951}1986}

Subscribers

People subscribed via source and target branches