on xenial help sign in
Merge trunk
9ce7f4eChristopher Lee
Applications/Application.qml+1−1
@@ -16,7 +16,7 @@
16
16
17import QtQuick 2.0
17import QtQuick 2.0
18import "applications.js" as ApplicationsModel
18import "applications.js" as ApplicationsModel
19−import Ubuntu.Application 0.1
19+import Unity.Application 0.1
20
20
21/* This class is temporary. It is meant to be API compatible with qthybris' Application
21/* This class is temporary. It is meant to be API compatible with qthybris' Application
22 class.
22 class.
Bottombar/Bottombar.qml+1−1
@@ -18,7 +18,7 @@ import QtQuick 2.0
18import "../Components"
18import "../Components"
19import "../Components/Math.js" as MathLocal
19import "../Components/Math.js" as MathLocal
20import Unity 0.1
20import Unity 0.1
21−import Ubuntu.Application 0.1
21+import Unity.Application 0.1
22import Ubuntu.Gestures 0.1
22import Ubuntu.Gestures 0.1
23
23
24Item {
24Item {
CMakeLists.txt+4
@@ -62,10 +62,13 @@ set(SHELL_PRIVATE_LIBDIR ${CMAKE_INSTALL_LIBDIR}/unity8)
62
62
63configure_file(paths.h.in ${CMAKE_CURRENT_BINARY_DIR}/paths.h @ONLY)
63configure_file(paths.h.in ${CMAKE_CURRENT_BINARY_DIR}/paths.h @ONLY)
64
64
65+pkg_check_modules(UNITY-MIR REQUIRED unity-mir)
66+
65include_directories(
67include_directories(
66 ${CMAKE_CURRENT_BINARY_DIR}
68 ${CMAKE_CURRENT_BINARY_DIR}
67 ${CMAKE_CURRENT_SOURCE_DIR}
69 ${CMAKE_CURRENT_SOURCE_DIR}
68 ${Qt5Gui_PRIVATE_INCLUDE_DIRS}
70 ${Qt5Gui_PRIVATE_INCLUDE_DIRS}
71+ ${UNITY-MIR_INCLUDE_DIRS}
69 )
72 )
70
73
71set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden")
74set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden")
@@ -118,6 +121,7 @@ target_link_libraries(${SHELL_APP}
118 ${Qt5Qml_LIBRARIES}
121 ${Qt5Qml_LIBRARIES}
119 ${Qt5Quick_LIBRARIES}
122 ${Qt5Quick_LIBRARIES}
120 ${XCB_LDFLAGS}
123 ${XCB_LDFLAGS}
124+ ${CMAKE_DL_LIBS}
121 )
125 )
122
126
123# install binaries
127# install binaries
Components/ApplicationManagerWrapper.qml+89−42
@@ -15,15 +15,15 @@
15 */
15 */
16
16
17import QtQuick 2.0
17import QtQuick 2.0
18−import Ubuntu.Application 0.1
18+import Unity.Application 0.1
19
19
20Item {
20Item {
21 id: applicationManager
21 id: applicationManager
22
22
23− property var mainStageApplications: ApplicationManager.mainStageApplications
23+ property alias mainStageApplications: mainStageModel
24− property var sideStageApplications: ApplicationManager.sideStageApplications
24+ property alias sideStageApplications: sideStageModel
25− property var mainStageFocusedApplication: ApplicationManager.mainStageFocusedApplication
25+ property variant mainStageFocusedApplication: null
26− property var sideStageFocusedApplication: ApplicationManager.sideStageFocusedApplication
26+ property variant sideStageFocusedApplication: null
27 property bool sideStageEnabled: true
27 property bool sideStageEnabled: true
28 signal focusRequested(string desktopFile)
28 signal focusRequested(string desktopFile)
29 property bool keyboardVisible: ApplicationManager.keyboardVisible
29 property bool keyboardVisible: ApplicationManager.keyboardVisible
@@ -31,32 +31,76 @@ Item {
31
31
32 property bool fake: ApplicationManager.fake ? ApplicationManager.fake : false
32 property bool fake: ApplicationManager.fake ? ApplicationManager.fake : false
33
33
34− Component.onCompleted: {
34+ ApplicationsModelStageFiltered {
35− // Start the watcher so that the ApplicationManager applications model can be populated.
35+ id: mainStageModel
36− ApplicationManager.startWatcher();
36+ stage: ApplicationInfo.MainStage
37+ }
38+
39+ ApplicationsModelStageFiltered {
40+ id: sideStageModel
41+ stage: ApplicationInfo.SideStage
42+ }
43+
44+ Connections {
45+ target: ApplicationManager
46+ onFocusedApplicationIdChanged: {
47+ var app = ApplicationManager.findApplication(ApplicationManager.focusedApplicationId)
48+ if (!app) { //nothing at all focused, so clear all
49+ mainStageFocusedApplication = null;
50+ sideStageFocusedApplication = null;
51+ } else {
52+ if (app.stage == ApplicationInfo.MainStage) {
53+ mainStageFocusedApplication = app;
54+ // possible the side stage app being unfocused fired this signal, so check for it
55+ if (sideStageFocusedApplication && !sideStageFocusedApplication.focused)
56+ sideStageFocusedApplication = null;
57+ } else {
58+ sideStageFocusedApplication = app;
59+ // possible the main stage app being unfocused fired this signal, so check for it
60+ if (mainStageFocusedApplication && !mainStageFocusedApplication.focused)
61+ mainStageFocusedApplication = null;
62+ }
63+ }
64+ }
37 }
65 }
38
66
39 function activateApplication(desktopFile, argument) {
67 function activateApplication(desktopFile, argument) {
40− var application;
68+ var appId;
41− application = getApplicationFromDesktopFile(desktopFile, ApplicationInfo.MainStage);
69+
42− if (application == null) {
70+ // HACK: Applications identified sometimes with with appId, but mostly with desktopFile.
43− application = getApplicationFromDesktopFile(desktopFile, ApplicationInfo.SideStage);
71+ // TODO: convert entire shell to use appId only.
72+ if (desktopFile.indexOf(".desktop") >= 0) {
73+ appId = desktopFileToAppId(desktopFile);
74+ } else {
75+ appId = desktopFile;
44 }
76 }
77+
78+ var application = ApplicationManager.findApplication(appId);
45− if (application != null) {
79+ if (application !== null) {
46 return application;
80 return application;
47 }
81 }
48
82
49 var execFlags = sideStageEnabled ? ApplicationManager.NoFlag : ApplicationManager.ForceMainStage;
83 var execFlags = sideStageEnabled ? ApplicationManager.NoFlag : ApplicationManager.ForceMainStage;
50
84
51 if (argument) {
85 if (argument) {
52− return ApplicationManager.startProcess(desktopFile, execFlags, [argument]);
86+ return ApplicationManager.startApplication(appId, execFlags, [argument]);
53 } else {
87 } else {
54− return ApplicationManager.startProcess(desktopFile, execFlags);
88+ return ApplicationManager.startApplication(appId, execFlags);
55 }
89 }
56 }
90 }
57
91
58− function stopProcess(application) {
92+ function stopApplication(application) {
93+ var appId;
94+
95+ // HACK: Applications identified sometimes with with appId, but mostly with desktopFile.
96+ // TODO: convert entire shell to use appId only.
97+ if (typeof application == "string") {
98+ appId = application;
99+ } else {
100+ appId = desktopFileToAppId(application.desktopFile);
101+ }
102+
59− ApplicationManager.stopProcess(application)
103+ ApplicationManager.stopApplication(appId);
60 }
104 }
61
105
62 function focusApplication(application) {
106 function focusApplication(application) {
@@ -64,51 +108,54 @@ Item {
64 return;
108 return;
65 }
109 }
66
110
67− ApplicationManager.focusApplication(application.handle);
111+ ApplicationManager.focusApplication(application.appId);
68 }
112 }
69
113
70 function unfocusCurrentApplication() {
114 function unfocusCurrentApplication() {
71− ApplicationManager.unfocusCurrentApplication(ApplicationInfo.MainStage);
115+ ApplicationManager.unfocusCurrentApplication();
72 }
116 }
73
117
74 function moveRunningApplicationStackPosition(from, to, stage) {
118 function moveRunningApplicationStackPosition(from, to, stage) {
75− var applications;
119+ if (from == to || from < 0 || to < 0) return;
120+
76 if (stage == ApplicationInfo.SideStage) {
121 if (stage == ApplicationInfo.SideStage) {
77− applications = ApplicationManager.sideStageApplications;
122+ sideStageModel.move(from, to);
78 } else {
123 } else {
79− applications = ApplicationManager.mainStageApplications;
124+ mainStageModel.move(from, to);
80 }
125 }
81− // FIXME: applications.move(0, 0) crashes
82− if (from !== to && from >= 0 && to >= 0) applications.move(from, to);
83 }
126 }
84
127
85 function getApplicationFromDesktopFile(desktopFile, stage) {
128 function getApplicationFromDesktopFile(desktopFile, stage) {
86− var foundSideStageApp, foundMainStageApp;
129+ var appId;
87
130
88− foundMainStageApp = __find(desktopFile, ApplicationManager.mainStageApplications)
131+ // HACK: Applications identified sometimes with with appId, but mostly with desktopFile.
89− if (stage == ApplicationInfo.MainStage) {
132+ // TODO: convert entire shell to use appId only.
90− return foundMainStageApp;
133+ if (desktopFile.indexOf(".desktop") >= 0) {
91− }
134+ appId = desktopFileToAppId(desktopFile);
92− foundSideStageApp = __find(desktopFile, ApplicationManager.sideStageApplications)
135+ } else {
93− if (stage == ApplicationInfo.SideStage) {
136+ appId = desktopFile;
94− return foundSideStageApp;
95 }
137 }
96
138
97− // if stage not specified, return whichever app running on either stage
139+ for (var i = 0, len = ApplicationManager.count; i < len; i++ ) {
98− return (foundMainStageApp) ? foundMainStageApp : foundSideStageApp;
140+ var app = ApplicationManager.get(i);
99−
100
141
101− function __find(desktopFile, applications) {
142+ // if stage not specified, return whichever app running on either stage
102− for (var i = 0; i < applications.count; i++ ) {
143+ if (app.appId == appId && (stage == undefined || app.stage == stage)) {
103− var application = applications.get(i);
104− if (application.desktopFile == desktopFile) {
105− return application;
144+ return app;
106− }
107 }
145 }
108− return null;
109 }
146 }
110 }
147 }
111
148
149+ function desktopFileToAppId(desktopFile) {
150+ var right = desktopFile.lastIndexOf(".desktop");
151+ var left = desktopFile.lastIndexOf("/");
152+ if (left == -1 || right == -1 || left == right) {
153+ console.log("ApplicationManagerWrapper: unable to extract appId from '" + desktopFile + "'");
154+ return "";
155+ }
156+ return desktopFile.substring(left+1, right);
157+ }
158+
112 Connections {
159 Connections {
113 target: ApplicationManager
160 target: ApplicationManager
114 onFocusRequested: {
161 onFocusRequested: {
Components/ApplicationScreenshot.qml+2−2
@@ -16,7 +16,7 @@
16
16
17import QtQuick 2.0
17import QtQuick 2.0
18import Ubuntu.Components 0.1
18import Ubuntu.Components 0.1
19−import Ubuntu.Application 0.1
19+import Unity.Application 0.1
20
20
21Item {
21Item {
22 id: applicationScreenshot
22 id: applicationScreenshot
@@ -56,6 +56,6 @@ Item {
56 width: applicationScreenshot.application ? parent.width : 0
56 width: applicationScreenshot.application ? parent.width : 0
57 height: applicationScreenshot.application ? parent.height : 0
57 height: applicationScreenshot.application ? parent.height : 0
58 visible: applicationScreenshot.application != null && ready
58 visible: applicationScreenshot.application != null && ready
59− source: applicationScreenshot.application
59+ source: ApplicationManager.findApplication((application) ? application.appId : "")
60 }
60 }
61}
61}
Components/ApplicationsModelStageFiltered.qmlnew file+49
@@ -0,0 +1,49 @@
1+/*
2+ * Copyright (C) 2013 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+
17+import QtQuick 2.0
18+import Utils 0.1
19+import Unity.Application 0.1
20+
21+SortFilterProxyModel {
22+ id: root
23+ property int stage
24+
25+ function get(index) {
26+ return model.get(mapRowToSource(index));
27+ }
28+
29+ function move(from, to) {
30+ var realFrom = mapRowToSource(from);
31+ if (realFrom == -1) {
32+ console.log("ERROR; invalid from=" + from + " index in move operation");
33+ return;
34+ }
35+ var realTo = mapRowToSource(to);
36+ if (realTo == -1) {
37+ // assuming wanting to move to end of list
38+ realTo = model.count - 1;
39+ }
40+
41+ if (realFrom == realTo) return;
42+ model.move(realFrom, realTo);
43+ }
44+
45+ model: ApplicationManager
46+ dynamicSortFilter: true
47+ filterRole: ApplicationManager.RoleStage
48+ filterRegExp: RegExp(stage)
49+}
Components/EdgeDemoOverlay.qml+1−1
@@ -17,7 +17,7 @@
17import Powerd 0.1
17import Powerd 0.1
18import QtQuick 2.0
18import QtQuick 2.0
19import QtGraphicalEffects 1.0
19import QtGraphicalEffects 1.0
20−import Ubuntu.Application 0.1
20+import Unity.Application 0.1
21import Ubuntu.Components 0.1
21import Ubuntu.Components 0.1
22
22
23Showable {
23Showable {
Components/Stage.qml+1−1
@@ -15,7 +15,7 @@
15 */
15 */
16
16
17import QtQuick 2.0
17import QtQuick 2.0
18−import Ubuntu.Application 0.1
18+import Unity.Application 0.1
19import Ubuntu.Components 0.1
19import Ubuntu.Components 0.1
20import Ubuntu.Gestures 0.1
20import Ubuntu.Gestures 0.1
21
21
Dash/Apps/RunningApplicationTile.qml+2−3
@@ -16,7 +16,7 @@
16
16
17import QtQuick 2.0
17import QtQuick 2.0
18import Ubuntu.Components 0.1
18import Ubuntu.Components 0.1
19−import Ubuntu.Application 0.1
19+import Unity.Application 0.1
20import "../../Components/"
20import "../../Components/"
21import "../../Components/ListItems"
21import "../../Components/ListItems"
22
22
@@ -76,10 +76,9 @@ AbstractButton {
76
76
77 ApplicationImage {
77 ApplicationImage {
78 id: applicationImage
78 id: applicationImage
79− source: application
79+ source: ApplicationManager.findApplication((application) ? application.appId : "")
80 width: shapedApplicationImage.width
80 width: shapedApplicationImage.width
81 height: shapedApplicationImage.height
81 height: shapedApplicationImage.height
82− fillMode: ApplicationImage.PreserveAspectCrop
83 }
82 }
84
83
85 UbuntuShape {
84 UbuntuShape {
Dash/Apps/RunningApplicationsGrid.qml+4−4
@@ -52,22 +52,22 @@ ResponsiveFlowView {
52
52
53 RunningApplicationTile {
53 RunningApplicationTile {
54 id: runningAppTile
54 id: runningAppTile
55− objectName: "runningAppTile " + model.application.name
55+ objectName: "runningAppTile " + model.name
56 anchors {
56 anchors {
57 top: parent.top
57 top: parent.top
58 horizontalCenter: parent.horizontalCenter
58 horizontalCenter: parent.horizontalCenter
59 }
59 }
60− application: model.application
60+ application: model
61 onRequestedActivationMode: { root.terminationModeEnabled = false }
61 onRequestedActivationMode: { root.terminationModeEnabled = false }
62 onRequestedTerminationMode: {
62 onRequestedTerminationMode: {
63 if (canEnableTerminationMode)
63 if (canEnableTerminationMode)
64 root.terminationModeEnabled = true
64 root.terminationModeEnabled = true
65 }
65 }
66 onRequestedApplicationTermination: {
66 onRequestedApplicationTermination: {
67− shell.applicationManager.stopProcess(application)
67+ shell.applicationManager.stopApplication(model.appId)
68 }
68 }
69 onRequestedApplicationActivation: {
69 onRequestedApplicationActivation: {
70− shell.activateApplication(application.desktopFile)
70+ shell.activateApplication(model.appId)
71 }
71 }
72
72
73 terminationModeEnabled: root.terminationModeEnabled
73 terminationModeEnabled: root.terminationModeEnabled
Panel/Indicators/DefaultIndicatorWidget.qml+1−1
@@ -75,7 +75,7 @@ Indicators.IndicatorWidget {
75 }
75 }
76
76
77 label = action.state[Indicators.ActionState.Label];
77 label = action.state[Indicators.ActionState.Label];
78− iconSource = "image://gicon/" + action.state[Indicators.ActionState.IconSource];
78+ iconSource = "image://theme/" + action.state[Indicators.ActionState.IconSource];
79 enabled = action.state[Indicators.ActionState.Visible];
79 enabled = action.state[Indicators.ActionState.Visible];
80 }
80 }
81}
81}
Panel/Indicators/MessagingIndicatorWidget.qml+1−1
@@ -21,5 +21,5 @@ import QtQuick 2.0
21
21
22DefaultIndicatorWidget {
22DefaultIndicatorWidget {
23 // default the icon so we have something to show when we don't have the bus.
23 // default the icon so we have something to show when we don't have the bus.
24− iconSource: "image://gicon/indicator-messages"
24+ iconSource: "image://theme/indicator-messages"
25}
25}
Panel/Indicators/NetworkIndicatorWidget.qml+6−6
@@ -97,16 +97,16 @@ Indicators.IndicatorWidget {
97 function get_icon_for_signal(con_state, value) {
97 function get_icon_for_signal(con_state, value) {
98 if (con_state >= Indicators.NetworkConnection.Activating && con_state <= Indicators.NetworkConnection.Deactivating) {
98 if (con_state >= Indicators.NetworkConnection.Activating && con_state <= Indicators.NetworkConnection.Deactivating) {
99 if (value == 0) {
99 if (value == 0) {
100− return "image://gicon/nm-signal-00";
100+ return "image://theme/nm-signal-00";
101 } else if (value <= 25) {
101 } else if (value <= 25) {
102− return "image://gicon/nm-signal-25";
102+ return "image://theme/nm-signal-25";
103 } else if (value <= 50) {
103 } else if (value <= 50) {
104− return "image://gicon/nm-signal-50";
104+ return "image://theme/nm-signal-50";
105 } else if (value <= 75) {
105 } else if (value <= 75) {
106− return "image://gicon/nm-signal-75";
106+ return "image://theme/nm-signal-75";
107 }
107 }
108− return "image://gicon/nm-signal-100";
108+ return "image://theme/nm-signal-100";
109 }
109 }
110− return "image://gicon/wifi-none";
110+ return "image://theme/wifi-none";
111 }
111 }
112}
112}
Panel/Indicators/SoundIndicatorWidget.qml+1−1
@@ -21,6 +21,6 @@ import QtQuick 2.0
21
21
22DefaultIndicatorWidget {
22DefaultIndicatorWidget {
23 // default the icon so we have something to show when we don't have the bus.
23 // default the icon so we have something to show when we don't have the bus.
24− iconSource: "image://gicon/audio-volume-high"
24+ iconSource: "image://theme/audio-volume-high"
25 enabled: true
25 enabled: true
26}
26}
Shell.qml+20−15
@@ -17,7 +17,7 @@
17import QtQuick 2.0
17import QtQuick 2.0
18import AccountsService 0.1
18import AccountsService 0.1
19import GSettings 1.0
19import GSettings 1.0
20−import Ubuntu.Application 0.1
20+import Unity.Application 0.1
21import Ubuntu.Components 0.1
21import Ubuntu.Components 0.1
22import Ubuntu.Gestures 0.1
22import Ubuntu.Gestures 0.1
23import Unity.Launcher 0.1
23import Unity.Launcher 0.1
@@ -75,6 +75,9 @@ FocusScope {
75 applicationManager.unfocusCurrentApplication();
75 applicationManager.unfocusCurrentApplication();
76 }
76 }
77
77
78+ readonly property bool applicationFocused: !!applicationManager.mainStageFocusedApplication
79+ || !!applicationManager.sideStageFocusedApplication
80+
78 readonly property bool fullscreenMode: {
81 readonly property bool fullscreenMode: {
79 if (greeter.shown || lockscreen.shown) {
82 if (greeter.shown || lockscreen.shown) {
80 return false;
83 return false;
@@ -157,6 +160,10 @@ FocusScope {
157 }
160 }
158 }
161 }
159
162
163+ OSKController {
164+ anchors.fill: parent // as needs to know the geometry of the shell
165+ }
166+
160 VolumeControl {
167 VolumeControl {
161 id: volumeControl
168 id: volumeControl
162 }
169 }
@@ -492,7 +499,8 @@ FocusScope {
492
499
493 InputFilterArea {
500 InputFilterArea {
494 anchors.fill: parent
501 anchors.fill: parent
495− blockInput: greeter.shown || lockscreen.shown
502+ blockInput: !applicationFocused || greeter.shown || lockscreen.shown || launcher.shown
503+ || panel.indicators.shown || hud.shown
496 }
504 }
497
505
498 Connections {
506 Connections {
@@ -504,10 +512,8 @@ FocusScope {
504
512
505 function setFocused(focused) {
513 function setFocused(focused) {
506 if (!focused) {
514 if (!focused) {
507− // FIXME: *FocusedApplication are not updated when unfocused, hence the need to check whether
508− // the stage was actually shown
509− if (mainStage.fullyShown) powerConnection.previousMainApp = applicationManager.mainStageFocusedApplication;
515+ powerConnection.previousMainApp = applicationManager.mainStageFocusedApplication;
510− if (sideStage.fullyShown) powerConnection.previousSideApp = applicationManager.sideStageFocusedApplication;
516+ powerConnection.previousSideApp = applicationManager.sideStageFocusedApplication;
511 applicationManager.unfocusCurrentApplication();
517 applicationManager.unfocusCurrentApplication();
512 } else {
518 } else {
513 if (powerConnection.previousMainApp) {
519 if (powerConnection.previousMainApp) {
@@ -558,8 +564,13 @@ FocusScope {
558 searchVisible: !greeter.shown && !lockscreen.shown
564 searchVisible: !greeter.shown && !lockscreen.shown
559
565
560 InputFilterArea {
566 InputFilterArea {
561− anchors.fill: parent
567+ anchors {
568+ top: parent.top
569+ left: parent.left
570+ right: parent.right
571+ }
572+ height: (panel.fullscreenMode) ? shell.edgeSize : panel.panelHeight
562− blockInput: panel.indicators.shown
573+ blockInput: true
563 }
574 }
564 }
575 }
565
576
@@ -579,11 +590,6 @@ FocusScope {
579 onMainStageFocusedApplicationChanged: hud.hide()
590 onMainStageFocusedApplicationChanged: hud.hide()
580 onSideStageFocusedApplicationChanged: hud.hide()
591 onSideStageFocusedApplicationChanged: hud.hide()
581 }
592 }
582−
583− InputFilterArea {
584− anchors.fill: parent
585− blockInput: hud.shown
586− }
587 }
593 }
588
594
589 Revealer {
595 Revealer {
@@ -606,8 +612,7 @@ FocusScope {
606 theHud: hud
612 theHud: hud
607 anchors.fill: parent
613 anchors.fill: parent
608 enabled: !panel.indicators.shown
614 enabled: !panel.indicators.shown
609− applicationIsOnForeground: applicationManager.mainStageFocusedApplication
615+ applicationIsOnForeground: applicationFocused
610− || applicationManager.sideStageFocusedApplication
611 }
616 }
612
617
613 InputFilterArea {
618 InputFilterArea {
SideStage/SideStage.qml+1−1
@@ -15,7 +15,7 @@
15 */
15 */
16
16
17import QtQuick 2.0
17import QtQuick 2.0
18−import Ubuntu.Application 0.1
18+import Unity.Application 0.1
19import Ubuntu.Components 0.1
19import Ubuntu.Components 0.1
20import "../Components"
20import "../Components"
21
21
debian/changelog+68
@@ -1,3 +1,71 @@
1+unity8 (7.81.3+13.10.20130911.1-0ubuntu1) saucy; urgency=low
2+
3+ [ Michael Terry ]
4+ * Switch from deprecated image://gicon/ to new image://theme/.
5+
6+ [ Gerry Boland ]
7+ * Add OSKController so shell can control OSK correctly on Mir.
8+ * Remove InputFilterArea for bottom edge swipes, as applications also
9+ listen for such swipes for Toolbar reveal.
10+
11+ [ Ricardo Mendoza ]
12+ * Select the backend to use dynamically on runtime according to the
13+ QPA selected by the system.
14+
15+ [ Ubuntu daily release ]
16+ * Automatic snapshot from revision 311
17+
18+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Wed, 11 Sep 2013 16:22:55 +0000
19+
20+unity8 (7.81.3+13.10.20130911-0ubuntu1) saucy; urgency=low
21+
22+ [ Michal Hruby ]
23+ * Hide all gicon strings from the shell and use the image://theme icon
24+ provider that was recently added to the SDK.
25+
26+ [ Gerry Boland ]
27+ * Convert to new ApplicationManager API.
28+
29+ [ Nick Dedekind ]
30+ * Updated access point design as per spec.
31+ * Indicator visibility based on connection with backend service.
32+
33+ [ Albert Astals ]
34+ * Dash: Make assignments bindings This way if the model changes the
35+ item value also changes.
36+
37+ [ Michael Zanetti ]
38+ * adds support for highlighting the currently focused application in
39+ the launcher, adds tests.
40+ * include ~/.local/share/applications in launcher's .desktop file
41+ search path.
42+ * shrink size of area for revealing the HUD button and make it
43+ disappear on release again. fixes 1219035. (LP: #1219035)
44+ * revert revision 304 as it makes the Shell crash.
45+
46+ [ Michael Terry ]
47+ * Allow testers to set custom password or pin in demo mode, rather
48+ than hardcoding them.
49+ * Have the greeter use AccountsService to determine its background.
50+ (LP: #1218402)
51+ * Listen to changes in the "show edge demo" AccountsService setting.
52+
53+ [ Daniel d'Andrada ]
54+ * Update fake/mock plugins so that "./run --fake" works well again -
55+ You can now see the thumbnails of the fake running applications once
56+ again. - You no longer get hundreds of warnings due to icons not
57+ found.
58+ * Reset apps scope when returning from app to dash (LP #1193419) If an
59+ app is on foreground and you perform a long left-edge swipe to
60+ minimize it, and therefore return to the dash, the dash should be in
61+ the Applications scope and showing the running/recents applications.
62+ (LP: #1193419)
63+
64+ [ Ubuntu daily release ]
65+ * Automatic snapshot from revision 306
66+
67+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Wed, 11 Sep 2013 00:54:31 +0000
68+
1unity8 (7.81.3+13.10.20130905.2-0ubuntu1) saucy; urgency=low
69unity8 (7.81.3+13.10.20130905.2-0ubuntu1) saucy; urgency=low
2
70
3 [ Michael Zanetti ]
71 [ Michael Zanetti ]
debian/control+4−2
@@ -23,6 +23,7 @@ Build-Depends: cmake,
23 libunity-api-dev (>= 7.80.3),
23 libunity-api-dev (>= 7.80.3),
24 libunity-core-6.0-dev (<< 7.80),
24 libunity-core-6.0-dev (<< 7.80),
25 libunity-dev (>= 7.0.12),
25 libunity-dev (>= 7.0.12),
26+ libunity-mir-dev,
26 libunity-scopes-json-def-phone,
27 libunity-scopes-json-def-phone,
27 libupstart-dev,
28 libupstart-dev,
28 libusermetricsoutput1-dev,
29 libusermetricsoutput1-dev,
@@ -54,7 +55,7 @@ Vcs-Browser: https://bazaar.launchpad.net/~unity-team/unity8/trunk
54Package: indicators-client
55Package: indicators-client
55Architecture: amd64 armhf i386
56Architecture: amd64 armhf i386
56Depends: qmenumodel-qml (>= 0.2.7),
57Depends: qmenumodel-qml (>= 0.2.7),
57− qtdeclarative5-ubuntu-ui-toolkit-plugin | qt-components-ubuntu,
58+ qtdeclarative5-ubuntu-ui-toolkit-plugin (>= 0.1.46+13.10.20130829.1-0ubuntu1),
58 unity8 (= ${binary:Version}),
59 unity8 (= ${binary:Version}),
59 ${misc:Depends},
60 ${misc:Depends},
60 ${shlibs:Depends},
61 ${shlibs:Depends},
@@ -65,10 +66,11 @@ Package: unity8
65Architecture: any
66Architecture: any
66Provides: indicator-renderer,
67Provides: indicator-renderer,
67Depends: gsettings-desktop-schemas,
68Depends: gsettings-desktop-schemas,
69+ libunity-mir1,
68 qmenumodel-qml (>= 0.2.7),
70 qmenumodel-qml (>= 0.2.7),
69 qtdeclarative5-dee-plugin,
71 qtdeclarative5-dee-plugin,
70 qtdeclarative5-gsettings1.0,
72 qtdeclarative5-gsettings1.0,
71− qtdeclarative5-ubuntu-ui-toolkit-plugin,
73+ qtdeclarative5-ubuntu-ui-toolkit-plugin (>= 0.1.46+13.10.20130829.1-0ubuntu1),
72 qtdeclarative5-unity-notifications-plugin | unity-notifications-impl,
74 qtdeclarative5-unity-notifications-plugin | unity-notifications-impl,
73 qtdeclarative5-xmllistmodel-plugin,
75 qtdeclarative5-xmllistmodel-plugin,
74 unity-launcher-impl-2,
76 unity-launcher-impl-2,
main.cpp+73−6
@@ -25,13 +25,17 @@
25#include <QtQml/QQmlContext>
25#include <QtQml/QQmlContext>
26#include <qpa/qplatformnativeinterface.h>
26#include <qpa/qplatformnativeinterface.h>
27#include <QLibrary>
27#include <QLibrary>
28+#include <QDebug>
28#include <libintl.h>
29#include <libintl.h>
30+#include <dlfcn.h>
29
31
30// local
32// local
31#include "paths.h"
33#include "paths.h"
32#include "MouseTouchAdaptor.h"
34#include "MouseTouchAdaptor.h"
33#include "ApplicationArguments.h"
35#include "ApplicationArguments.h"
34
36
37+#include <unity-mir/qmirserver.h>
38+
35namespace {
39namespace {
36
40
37void prependImportPaths(QQmlEngine *engine, const QStringList &paths)
41void prependImportPaths(QQmlEngine *engine, const QStringList &paths)
@@ -72,7 +76,7 @@ void resolveIconTheme() {
72}
76}
73} // namespace {
77} // namespace {
74
78
75−int main(int argc, char** argv)
79+int startShell(int argc, const char** argv, void* server)
76{
80{
77 /* Workaround Qt platform integration plugin not advertising itself
81 /* Workaround Qt platform integration plugin not advertising itself
78 as having the following capabilities:
82 as having the following capabilities:
@@ -82,12 +86,29 @@ int main(int argc, char** argv)
82 setenv("QML_FORCE_THREADED_RENDERER", "1", 1);
86 setenv("QML_FORCE_THREADED_RENDERER", "1", 1);
83 setenv("QML_FIXED_ANIMATION_STEP", "1", 1);
87 setenv("QML_FIXED_ANIMATION_STEP", "1", 1);
84
88
89+ const bool isUbuntuMirServer = qgetenv("QT_QPA_PLATFORM") == "ubuntumirserver";
90+
85 QGuiApplication::setApplicationName("Unity 8");
91 QGuiApplication::setApplicationName("Unity 8");
86− QGuiApplication application(argc, argv);
92+ QGuiApplication *application;
93+ if (isUbuntuMirServer) {
94+ QLibrary unityMir("unity-mir");
95+ unityMir.load();
96+
97+ typedef QGuiApplication* (*createServerApplication_t)(int&, const char **, void*);
98+ createServerApplication_t createQMirServerApplication = (createServerApplication_t) unityMir.resolve("createQMirServerApplication");
99+ if (!createQMirServerApplication) {
100+ qDebug() << "unable to resolve symbol: createQMirServerApplication";
101+ return 4;
102+ }
103+
104+ application = createQMirServerApplication(argc, argv, server);
105+ } else {
106+ application = new QGuiApplication(argc, (char**)argv);
107+ }
87
108
88 resolveIconTheme();
109 resolveIconTheme();
89
110
90− QStringList args = application.arguments();
111+ QStringList args = application->arguments();
91 ApplicationArguments qmlArgs(args);
112 ApplicationArguments qmlArgs(args);
92
113
93 // The testability driver is only loaded by QApplication but not by QGuiApplication.
114 // The testability driver is only loaded by QApplication but not by QGuiApplication.
@@ -124,7 +145,7 @@ int main(int argc, char** argv)
124 if (args.contains(QLatin1String("-mousetouch"))) {
145 if (args.contains(QLatin1String("-mousetouch"))) {
125 mouseTouchAdaptor = new MouseTouchAdaptor;
146 mouseTouchAdaptor = new MouseTouchAdaptor;
126 mouseTouchAdaptor->setTargetWindow(view);
147 mouseTouchAdaptor->setTargetWindow(view);
127− application.installNativeEventFilter(mouseTouchAdaptor);
148+ application->installNativeEventFilter(mouseTouchAdaptor);
128 }
149 }
129
150
130 QPlatformNativeInterface* nativeInterface = QGuiApplication::platformNativeInterface();
151 QPlatformNativeInterface* nativeInterface = QGuiApplication::platformNativeInterface();
@@ -139,18 +160,64 @@ int main(int argc, char** argv)
139 QUrl source("Shell.qml");
160 QUrl source("Shell.qml");
140 prependImportPaths(view->engine(), ::overrideImportPaths());
161 prependImportPaths(view->engine(), ::overrideImportPaths());
141 appendImportPaths(view->engine(), ::fallbackImportPaths());
162 appendImportPaths(view->engine(), ::fallbackImportPaths());
163+
164+ QStringList importPath = view->engine()->importPathList().filter("qt5/imports");
165+ if (isUbuntuMirServer) {
166+ importPath.first().append("/Unity-Mir");
167+ view->engine()->addImportPath(importPath.first());
168+ }
169+
142 view->setSource(source);
170 view->setSource(source);
143 view->setColor("transparent");
171 view->setColor("transparent");
144
172
145− if (qgetenv("QT_QPA_PLATFORM") == "ubuntu" || args.contains(QLatin1String("-fullscreen"))) {
173+ if (qgetenv("QT_QPA_PLATFORM") == "ubuntu" || isUbuntuMirServer || args.contains(QLatin1String("-fullscreen"))) {
146 view->showFullScreen();
174 view->showFullScreen();
147 } else {
175 } else {
148 view->show();
176 view->show();
149 }
177 }
150
178
151− int result = application.exec();
179+ int result = application->exec();
152
180
153 delete mouseTouchAdaptor;
181 delete mouseTouchAdaptor;
182+ delete application;
154
183
155 return result;
184 return result;
156}
185}
186+
187+int main(int argc, const char *argv[])
188+{
189+ // For ubuntumirserver/ubuntumirclient
190+ if (qgetenv("QT_QPA_PLATFORM").startsWith("ubuntumir")) {
191+ setenv("QT_QPA_PLATFORM", "ubuntumirserver", 1);
192+
193+ // If we use unity-mir directly, we automatically link to the Mir-server
194+ // platform-api bindings, which result in unexpected behaviour when
195+ // running the non-Mir scenario.
196+ QLibrary unityMir("unity-mir");
197+ unityMir.load();
198+ if (!unityMir.isLoaded()) {
199+ qDebug() << "Library unity-mir not found/loaded";
200+ return 1;
201+ }
202+
203+ typedef QMirServer* (*createServer_t)(int, const char **);
204+ createServer_t createQMirServer = (createServer_t) unityMir.resolve("createQMirServer");
205+ if (!createQMirServer) {
206+ qDebug() << "unable to resolve symbol: createQMirServer";
207+ return 2;
208+ }
209+
210+ QMirServer* mirServer = createQMirServer(argc, argv);
211+
212+ typedef int (*runWithClient_t)(QMirServer*, std::function<int(int, const char**, void*)>);
213+ runWithClient_t runWithClient = (runWithClient_t) unityMir.resolve("runQMirServerWithClient");
214+ if (!runWithClient) {
215+ qDebug() << "unable to resolve symbol: runWithClient";
216+ return 3;
217+ }
218+
219+ return runWithClient(mirServer, startShell);
220+ } else {
221+ return startShell(argc, argv, nullptr);
222+ }
223+}
plugins/Unity/Indicators/rootactionstate.cpp+8−8
@@ -148,15 +148,15 @@ static QString iconUri(GIcon *icon)
148 QString uri;
148 QString uri;
149
149
150 if (G_IS_THEMED_ICON (icon)) {
150 if (G_IS_THEMED_ICON (icon)) {
151−
152 const gchar* const* iconNames = g_themed_icon_get_names (G_THEMED_ICON (icon));
151 const gchar* const* iconNames = g_themed_icon_get_names (G_THEMED_ICON (icon));
153− guint index = 0;
152+
153+ QStringList iconNameList;
154− while(iconNames[index] != NULL) {
154+ for (uint index = 0; iconNames[index] != NULL; index++) {
155− if (QIcon::hasThemeIcon(iconNames[index])) {
155+ iconNameList << iconNames[index];
156+ }
157+
158+ if (!iconNameList.empty()) {
156− uri = QString("image://theme/%1").arg(iconNames[index]);
159+ uri = QString("image://theme/%1").arg(iconNameList.join(","));
157− break;
158− }
159− index++;
160 }
160 }
161 }
161 }
162 else if (G_IS_FILE_ICON (icon)) {
162 else if (G_IS_FILE_ICON (icon)) {
plugins/Unity/IndicatorsLegacy/Messaging/qml/GroupedMessage.qml+1−1
@@ -44,7 +44,7 @@ Indicators.BasicMenuItem {
44 height: units.gu(6)
44 height: units.gu(6)
45 width: units.gu(6)
45 width: units.gu(6)
46 image: Image {
46 image: Image {
47− source: menu && (menu.extra.canonical_icon.length > 0) ? "image://gicon/" + encodeURI(menu.extra.canonical_icon) : "qrc:/indicators/artwork/messaging/default_app.svg"
47+ source: menu && (menu.extra.canonical_icon.length > 0) ? "image://theme/" + encodeURI(menu.extra.canonical_icon) : "qrc:/indicators/artwork/messaging/default_app.svg"
48 fillMode: Image.PreserveAspectFit
48 fillMode: Image.PreserveAspectFit
49 }
49 }
50 }
50 }
plugins/Unity/IndicatorsLegacy/Messaging/qml/HeroMessage.qml+2−2
@@ -48,8 +48,8 @@ Indicators.BasicMenuItem {
48 anchors.left: parent.left
48 anchors.left: parent.left
49 anchors.right: parent.right
49 anchors.right: parent.right
50
50
51− avatar: menu && (menu.extra.canonical_icon.length > 0) ? "image://gicon/" + encodeURI(menu.extra.canonical_icon) : "qrc:/indicators/artwork/messaging/default_contact.png"
51+ avatar: menu && (menu.extra.canonical_icon.length > 0) ? "image://theme/" + encodeURI(menu.extra.canonical_icon) : "qrc:/indicators/artwork/messaging/default_contact.png"
52− icon: menu && (menu.extra.canonical_app_icon.length > 0) ? "image://gicon/" + encodeURI(menu.extra.canonical_app_icon) : ""
52+ icon: menu && (menu.extra.canonical_app_icon.length > 0) ? "image://theme/" + encodeURI(menu.extra.canonical_app_icon) : ""
53 appIcon: icon
53 appIcon: icon
54
54
55 state: heroMessage.state
55 state: heroMessage.state
plugins/Unity/IndicatorsLegacy/Network/qml/AccessPoint.qml+2−2
@@ -47,10 +47,10 @@ Indicators.MenuItem {
47 imageName += "-secure";
47 imageName += "-secure";
48 }
48 }
49
49
50− return "image://gicon/" + imageName;
50+ return "image://theme/" + imageName;
51 }
51 }
52
52
53− icon: menu && wifiApStrength ? getNetworkIcon(menu) : "image://gicon/wifi-none"
53+ icon: menu && wifiApStrength ? getNetworkIcon(menu) : "image://theme/wifi-none"
54 iconFrame: false
54 iconFrame: false
55 control: CheckBox {
55 control: CheckBox {
56 id: checkBoxActive
56 id: checkBoxActive
plugins/Unity/Launcher/backend/launcherbackend.cpp+6−1
@@ -300,7 +300,12 @@ LauncherBackendItem* LauncherBackend::parseDesktopFile(const QString &desktopFil
300 LauncherBackendItem* item = new LauncherBackendItem();
300 LauncherBackendItem* item = new LauncherBackendItem();
301 item->desktopFile = desktopFile;
301 item->desktopFile = desktopFile;
302 item->displayName = settings.value("Desktop Entry/Name").toString();
302 item->displayName = settings.value("Desktop Entry/Name").toString();
303+
304+ if (settings.contains("Desktop Entry/Path")) {
303− item->icon = settings.value("Desktop Entry/Icon").toString();
305+ item->icon = settings.value("Desktop Entry/Path").toString() + "/" + settings.value("Desktop Entry/Icon").toString();
306+ } else {
307+ item->icon = settings.value("Desktop Entry/Icon").toString();
308+ }
304 item->pinned = false;
309 item->pinned = false;
305 return item;
310 return item;
306}
311}
plugins/Utils/qsortfilterproxymodelqml.cpp+13−1
@@ -29,6 +29,17 @@ QSortFilterProxyModelQML::QSortFilterProxyModelQML(QObject *parent)
29 connect(this, SIGNAL(rowsRemoved(QModelIndex,int,int)), SIGNAL(countChanged()));
29 connect(this, SIGNAL(rowsRemoved(QModelIndex,int,int)), SIGNAL(countChanged()));
30}
30}
31
31
32+/*
33+ * Enter row index of filtered/sorted model, returns row index of source model
34+ */
35+int QSortFilterProxyModelQML::mapRowToSource(int row)
36+{
37+ if (sourceModel() == NULL)
38+ return -1;
39+
40+ return QSortFilterProxyModel::mapToSource(index(row, 0)).row();
41+}
42+
32QHash<int, QByteArray> QSortFilterProxyModelQML::roleNames() const
43QHash<int, QByteArray> QSortFilterProxyModelQML::roleNames() const
33{
44{
34 return sourceModel() ? sourceModel()->roleNames() : QHash<int, QByteArray>();
45 return sourceModel() ? sourceModel()->roleNames() : QHash<int, QByteArray>();
@@ -51,6 +62,7 @@ QSortFilterProxyModelQML::setModel(QAbstractItemModel *itemModel)
51 connect(itemModel, SIGNAL(modelReset()), SIGNAL(totalCountChanged()));
62 connect(itemModel, SIGNAL(modelReset()), SIGNAL(totalCountChanged()));
52 connect(itemModel, SIGNAL(rowsInserted(QModelIndex,int,int)), SIGNAL(totalCountChanged()));
63 connect(itemModel, SIGNAL(rowsInserted(QModelIndex,int,int)), SIGNAL(totalCountChanged()));
53 connect(itemModel, SIGNAL(rowsRemoved(QModelIndex,int,int)), SIGNAL(totalCountChanged()));
64 connect(itemModel, SIGNAL(rowsRemoved(QModelIndex,int,int)), SIGNAL(totalCountChanged()));
65+
54 Q_EMIT totalCountChanged();
66 Q_EMIT totalCountChanged();
55 Q_EMIT modelChanged();
67 Q_EMIT modelChanged();
56 }
68 }
@@ -140,4 +152,4 @@ QSortFilterProxyModelQML::mapToSource(int row)
140 } else {
152 } else {
141 return -1;
153 return -1;
142 }
154 }
143−}
155+}
plugins/Utils/qsortfilterproxymodelqml.h+1
@@ -34,6 +34,7 @@ public:
34 Q_INVOKABLE QVariant data(int row, int role);
34 Q_INVOKABLE QVariant data(int row, int role);
35 Q_INVOKABLE int count();
35 Q_INVOKABLE int count();
36 Q_INVOKABLE int findFirst(int role, const QVariant& value) const;
36 Q_INVOKABLE int findFirst(int role, const QVariant& value) const;
37+ Q_INVOKABLE int mapRowToSource(int row);
37 virtual bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const;
38 virtual bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const;
38
39
39 /* getters */
40 /* getters */
tests/mocks/Ubuntu/Application/CMakeLists.txtdeleted−29
@@ -1,29 +0,0 @@
1−set(FakeUbuntuApplicationQml_SOURCES
2− plugin.cpp
3− ApplicationInfo.cpp
4− ApplicationImage.cpp
5− ApplicationListModel.cpp
6− ApplicationManager.cpp
7−)
8−
9−add_library(FakeUbuntuApplicationQml MODULE ${FakeUbuntuApplicationQml_SOURCES})
10−
11−qt5_use_modules(FakeUbuntuApplicationQml Core Quick)
12−
13−# copy files into build directory for shadow builds
14−add_custom_target(UbuntuAppQmlDirFile ALL
15− COMMAND cp "${CMAKE_CURRENT_SOURCE_DIR}/qmldir" ${CMAKE_CURRENT_BINARY_DIR}
16− DEPENDS qmldir
17−)
18−add_custom_target(InputFilterAreaQmlFile ALL
19− COMMAND cp "${CMAKE_CURRENT_SOURCE_DIR}/InputFilterArea.qml" ${CMAKE_CURRENT_BINARY_DIR}
20− DEPENDS InputFilterArea.qml
21−)
22−
23−install(TARGETS FakeUbuntuApplicationQml
24− DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/mocks/Ubuntu/Application
25− )
26−
27−install(FILES qmldir InputFilterArea.qml
28− DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/mocks/Ubuntu/Application
29− )
tests/mocks/Ubuntu/Application/qmldirdeleted−3
@@ -1,3 +0,0 @@
1−module Ubuntu.Application
2−plugin FakeUbuntuApplicationQml
3−InputFilterArea 0.1 InputFilterArea.qml
tests/mocks/Ubuntu/CMakeLists.txt−1
@@ -1,2 +1 @@
1−add_subdirectory(Application)
2add_subdirectory(DownloadDaemonListener)
1add_subdirectory(DownloadDaemonListener)
tests/mocks/Ubuntu/Application/ApplicationImage.cpp → tests/mocks/Unity/Application/ApplicationImage.cpprenamed

The content is the same.

tests/mocks/Ubuntu/Application/ApplicationImage.h → tests/mocks/Unity/Application/ApplicationImage.hrenamed

The content is the same.

tests/mocks/Ubuntu/Application/ApplicationInfo.cpp → tests/mocks/Unity/Application/ApplicationInfo.cpprenamed+15−2
@@ -21,11 +21,24 @@
21#include <QQuickView>
21#include <QQuickView>
22#include <QQmlComponent>
22#include <QQmlComponent>
23
23
24+ApplicationInfo::ApplicationInfo(const QString &appId, QObject *parent)
25+ : ApplicationInfoInterface(appId, parent)
26+ ,m_appId(appId)
27+ ,m_stage(MainStage)
28+ ,m_state(Starting)
29+ ,m_focused(false)
30+ ,m_fullscreen(false)
31+ ,m_windowItem(0)
32+ ,m_windowComponent(0)
33+ ,m_parentItem(0)
34+{
35+}
36+
24ApplicationInfo::ApplicationInfo(QObject *parent)
37ApplicationInfo::ApplicationInfo(QObject *parent)
25− : QObject(parent)
38+ : ApplicationInfoInterface(QString(), parent)
26− ,m_handle(0)
27 ,m_stage(MainStage)
39 ,m_stage(MainStage)
28 ,m_state(Starting)
40 ,m_state(Starting)
41+ ,m_focused(false)
29 ,m_fullscreen(false)
42 ,m_fullscreen(false)
30 ,m_windowItem(0)
43 ,m_windowItem(0)
31 ,m_windowComponent(0)
44 ,m_windowComponent(0)
tests/mocks/Ubuntu/Application/ApplicationInfo.h → tests/mocks/Unity/Application/ApplicationInfo.hrenamed+12−18
@@ -22,21 +22,18 @@
22
22
23class QQuickItem;
23class QQuickItem;
24
24
25+// unity-api
26+#include <unity/shell/application/ApplicationInfoInterface.h>
27+
25// A pretty dumb file. Just a container for properties.
28// A pretty dumb file. Just a container for properties.
26// Implemented in C++ instead of QML just because of the enumerations
29// Implemented in C++ instead of QML just because of the enumerations
27// See QTBUG-14861
30// See QTBUG-14861
31+
32+using namespace unity::shell::application;
33+
28−class ApplicationInfo : public QObject {
34+class ApplicationInfo : public ApplicationInfoInterface {
29 Q_OBJECT
35 Q_OBJECT
30− Q_ENUMS(Stage)
36+
31− Q_ENUMS(State)
32− Q_PROPERTY(QString desktopFile READ desktopFile WRITE setDesktopFile NOTIFY desktopFileChanged)
33− Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
34− Q_PROPERTY(QString comment READ comment WRITE setComment NOTIFY commentChanged)
35− Q_PROPERTY(QString icon READ icon WRITE setIcon NOTIFY iconChanged)
36− Q_PROPERTY(QString exec READ exec WRITE setExec NOTIFY execChanged)
37− Q_PROPERTY(qint64 handle READ handle WRITE setHandle NOTIFY handleChanged)
38− Q_PROPERTY(Stage stage READ stage WRITE setStage NOTIFY stageChanged)
39− Q_PROPERTY(State state READ state WRITE setState NOTIFY stateChanged)
40 Q_PROPERTY(bool fullscreen READ fullscreen WRITE setFullscreen NOTIFY fullscreenChanged)
37 Q_PROPERTY(bool fullscreen READ fullscreen WRITE setFullscreen NOTIFY fullscreenChanged)
41
38
42 // Only exists in this fake implementation
39 // Only exists in this fake implementation
@@ -48,10 +45,8 @@ class ApplicationInfo : public QObject {
48 Q_PROPERTY(QString windowQml READ windowQml WRITE setWindowQml NOTIFY windowQmlChanged)
45 Q_PROPERTY(QString windowQml READ windowQml WRITE setWindowQml NOTIFY windowQmlChanged)
49
46
50 public:
47 public:
51− enum Stage { MainStage, SideStage };
52− enum State { Starting, Running };
53−
54 ApplicationInfo(QObject *parent = NULL);
48 ApplicationInfo(QObject *parent = NULL);
49+ ApplicationInfo(const QString &appId, QObject *parent = NULL);
55
50
56 #define IMPLEMENT_PROPERTY(name, Name, type) \
51 #define IMPLEMENT_PROPERTY(name, Name, type) \
57 public: \
52 public: \
@@ -68,14 +63,13 @@ class ApplicationInfo : public QObject {
68 private: \
63 private: \
69 type m_##name;
64 type m_##name;
70
65
71− IMPLEMENT_PROPERTY(desktopFile, DesktopFile, QString)
66+ IMPLEMENT_PROPERTY(appId, AppId, QString)
72 IMPLEMENT_PROPERTY(name, Name, QString)
67 IMPLEMENT_PROPERTY(name, Name, QString)
73 IMPLEMENT_PROPERTY(comment, Comment, QString)
68 IMPLEMENT_PROPERTY(comment, Comment, QString)
74− IMPLEMENT_PROPERTY(icon, Icon, QString)
69+ IMPLEMENT_PROPERTY(icon, Icon, QUrl)
75− IMPLEMENT_PROPERTY(exec, Exec, QString)
76− IMPLEMENT_PROPERTY(handle, Handle, qint64)
77 IMPLEMENT_PROPERTY(stage, Stage, Stage)
70 IMPLEMENT_PROPERTY(stage, Stage, Stage)
78 IMPLEMENT_PROPERTY(state, State, State)
71 IMPLEMENT_PROPERTY(state, State, State)
72+ IMPLEMENT_PROPERTY(focused, Focused, bool)
79 IMPLEMENT_PROPERTY(fullscreen, Fullscreen, bool)
73 IMPLEMENT_PROPERTY(fullscreen, Fullscreen, bool)
80 IMPLEMENT_PROPERTY(imageQml, ImageQml, QString)
74 IMPLEMENT_PROPERTY(imageQml, ImageQml, QString)
81 IMPLEMENT_PROPERTY(windowQml, WindowQml, QString)
75 IMPLEMENT_PROPERTY(windowQml, WindowQml, QString)
tests/mocks/Ubuntu/Application/ApplicationListModel.cpp → tests/mocks/Unity/Application/ApplicationListModel.cpprenamed

The content is the same.

tests/mocks/Ubuntu/Application/ApplicationListModel.h → tests/mocks/Unity/Application/ApplicationListModel.hrenamed

The content is the same.

tests/mocks/Ubuntu/Application/ApplicationManager.cpp → tests/mocks/Unity/Application/ApplicationManager.cpprenamed+185−153
@@ -16,7 +16,6 @@
16
16
17#include "ApplicationManager.h"
17#include "ApplicationManager.h"
18#include "ApplicationInfo.h"
18#include "ApplicationInfo.h"
19−#include "ApplicationListModel.h"
20#include "paths.h"
19#include "paths.h"
21
20
22#include <QDir>
21#include <QDir>
@@ -26,11 +25,7 @@
26#include <QQmlComponent>
25#include <QQmlComponent>
27
26
28ApplicationManager::ApplicationManager(QObject *parent)
27ApplicationManager::ApplicationManager(QObject *parent)
29− : QObject(parent)
28+ : ApplicationManagerInterface(parent)
30− , m_mainStageApplications(new ApplicationListModel())
31− , m_sideStageApplications(new ApplicationListModel())
32− , m_mainStageFocusedApplication(0)
33− , m_sideStageFocusedApplication(0)
34 , m_mainStageComponent(0)
29 , m_mainStageComponent(0)
35 , m_mainStage(0)
30 , m_mainStage(0)
36 , m_sideStageComponent(0)
31 , m_sideStageComponent(0)
@@ -41,8 +36,84 @@ ApplicationManager::ApplicationManager(QObject *parent)
41
36
42ApplicationManager::~ApplicationManager()
37ApplicationManager::~ApplicationManager()
43{
38{
44− delete m_mainStageApplications;
39+}
45− delete m_sideStageApplications;
40+
41+int ApplicationManager::rowCount(const QModelIndex& parent) const {
42+ return !parent.isValid() ? m_runningApplications.size() : 0;
43+}
44+
45+QVariant ApplicationManager::data(const QModelIndex& index, int role) const {
46+ if (index.row() < 0 || index.row() >= m_runningApplications.size())
47+ return QVariant();
48+
49+ auto app = m_runningApplications.at(index.row());
50+ switch(role) {
51+ case RoleAppId:
52+ return app->appId();
53+ case RoleName:
54+ return app->name();
55+ case RoleComment:
56+ return app->comment();
57+ case RoleIcon:
58+ return app->icon();
59+ case RoleStage:
60+ return app->stage();
61+ case RoleState:
62+ return app->state();
63+ case RoleFocused:
64+ return app->focused();
65+ default:
66+ return QVariant();
67+ }
68+}
69+
70+ApplicationInfo *ApplicationManager::get(int row) const {
71+ if (row < 0 || row >= m_runningApplications.size())
72+ return nullptr;
73+ return m_runningApplications.at(row);
74+}
75+
76+ApplicationInfo *ApplicationManager::findApplication(const QString &appId) const {
77+ for (ApplicationInfo *app : m_runningApplications) {
78+ if (app->appId() == appId) {
79+ return app;
80+ }
81+ }
82+ return nullptr;
83+}
84+
85+void ApplicationManager::add(ApplicationInfo *application) {
86+ if (!application)
87+ return;
88+
89+ beginInsertRows(QModelIndex(), m_runningApplications.size(), m_runningApplications.size());
90+ m_runningApplications.append(application);
91+ endInsertRows();
92+ Q_EMIT countChanged();
93+}
94+
95+void ApplicationManager::remove(ApplicationInfo *application) {
96+ int i = m_runningApplications.indexOf(application);
97+ if (i != -1) {
98+ beginRemoveRows(QModelIndex(), i, i);
99+ m_runningApplications.removeAt(i);
100+ endRemoveRows();
101+ Q_EMIT countChanged();
102+ }
103+}
104+
105+void ApplicationManager::move(int from, int to) {
106+ if (from == to) return;
107+
108+ if (from >= 0 && from < m_runningApplications.size() && to >= 0 && to < m_runningApplications.size()) {
109+ QModelIndex parent;
110+ /* When moving an item down, the destination index needs to be incremented
111+ * by one, as explained in the documentation:
112+ * http://qt-project.org/doc/qt-5.0/qtcore/qabstractitemmodel.html#beginMoveRows */
113+ beginMoveRows(parent, from, from, parent, to + (to > from ? 1 : 0));
114+ m_runningApplications.move(from, to);
115+ endMoveRows();
116+ }
46}
117}
47
118
48int ApplicationManager::keyboardHeight() const
119int ApplicationManager::keyboardHeight() const
@@ -70,36 +141,21 @@ ApplicationManager::FormFactorHint ApplicationManager::formFactorHint() const
70 return PhoneFormFactor;
141 return PhoneFormFactor;
71}
142}
72
143
73−ApplicationListModel* ApplicationManager::mainStageApplications() const
144+ApplicationInfo* ApplicationManager::startApplication(const QString &appId,
74−{
145+ const QStringList &arguments)
75− return m_mainStageApplications;
76−}
77−
78−ApplicationListModel* ApplicationManager::sideStageApplications() const
79{
146{
80− return m_sideStageApplications;
147+ return startApplication(appId, NoFlag, arguments);
81}
148}
82
149
83−ApplicationInfo* ApplicationManager::mainStageFocusedApplication() const
150+ApplicationInfo* ApplicationManager::startApplication(const QString &appId,
84−{
85− return m_mainStageFocusedApplication;
86−}
87−
88−ApplicationInfo* ApplicationManager::sideStageFocusedApplication() const
89−{
90− return m_sideStageFocusedApplication;
91−}
92−
93−ApplicationInfo* ApplicationManager::startProcess(QString desktopFile,
94 ExecFlags flags,
151 ExecFlags flags,
95− QStringList arguments)
152+ const QStringList &arguments)
96{
153{
97 Q_UNUSED(arguments)
154 Q_UNUSED(arguments)
98 ApplicationInfo *application = 0;
155 ApplicationInfo *application = 0;
99
156
100− for (int i = 0; i < m_availableApplications.count(); ++i) {
101− ApplicationInfo *availableApp = m_availableApplications[i];
157+ for (ApplicationInfo *availableApp : m_availableApplications) {
102− if (availableApp->desktopFile() == desktopFile) {
158+ if (availableApp->appId() == appId) {
103 application = availableApp;
159 application = availableApp;
104 break;
160 break;
105 }
161 }
@@ -109,86 +165,91 @@ ApplicationInfo* ApplicationManager::startProcess(QString desktopFile,
109 return 0;
165 return 0;
110
166
111 if (flags.testFlag(ApplicationManager::ForceMainStage)
167 if (flags.testFlag(ApplicationManager::ForceMainStage)
112− || application->stage() == ApplicationInfo::MainStage) {
168+ && application->stage() == ApplicationInfo::SideStage) {
113− m_mainStageApplications->add(application);
169+ application->setStage(ApplicationInfo::MainStage);
114− } else {
115− m_sideStageApplications->add(application);
116 }
170 }
171+ add(application);
117
172
118 return application;
173 return application;
119}
174}
120
175
121−void ApplicationManager::stopProcess(ApplicationInfo* application)
176+bool ApplicationManager::stopApplication(const QString &appId)
122{
177{
178+ ApplicationInfo *application = findApplication(appId);
123− if (m_mainStageApplications->contains(application)) {
179+ if (application == nullptr)
124− m_mainStageApplications->remove(application);
180+ return false;
125
181
126− if (m_mainStageFocusedApplication == application) {
182+ remove(application);
127− m_mainStageFocusedApplication = 0;
183+ Q_EMIT focusedApplicationIdChanged();
128− Q_EMIT mainStageFocusedApplicationChanged();
184+ return true;
129− }
185+}
130− } else if (m_sideStageApplications->contains(application)){
131− m_sideStageApplications->remove(application);
132
186
133− if (m_sideStageFocusedApplication == application) {
187+QString ApplicationManager::focusedApplicationId() const {
134− m_sideStageFocusedApplication = 0;
188+ for (ApplicationInfo *app : m_runningApplications) {
135− Q_EMIT sideStageFocusedApplicationChanged();
189+ if (app->focused()) {
190+ return app->appId();
136 }
191 }
137 }
192 }
193+ return QString();
138}
194}
139
195
140−void ApplicationManager::focusApplication(int handle)
196+bool ApplicationManager::focusApplication(const QString &appId)
141{
197{
142− for (int i = 0; i < m_mainStageApplications->m_applications.count(); ++i) {
198+ ApplicationInfo *application = findApplication(appId);
143− ApplicationInfo *application = m_mainStageApplications->m_applications[i];
199+ if (application == nullptr)
144− if (application->handle() == handle) {
200+ return false;
145− if (m_mainStageFocusedApplication)
201+
146− m_mainStageFocusedApplication->hideWindow();
202+ if (application->stage() == ApplicationInfo::MainStage) {
147− m_mainStageFocusedApplication = application;
203+ // unfocus currently focused mainstage app
148− if (!m_mainStage)
204+ for (ApplicationInfo *app : m_runningApplications) {
149− createMainStage();
205+ if (app->focused() && app->stage() == ApplicationInfo::MainStage) {
150− application->showWindow(m_mainStage);
206+ app->setFocused(false);
151− m_mainStage->setZ(-1000);
207+ app->hideWindow();
152− if (m_sideStage)
208+ }
153− m_sideStage->setZ(-2000);
154− Q_EMIT mainStageFocusedApplicationChanged();
155− return;
156 }
209 }
157− }
158
210
159− for (int i = 0; i < m_sideStageApplications->m_applications.count(); ++i) {
211+ // focus this app
160− ApplicationInfo *application = m_sideStageApplications->m_applications[i];
212+ application->setFocused(true);
161− if (application->handle() == handle) {
213+ if (!m_mainStage)
162− if (m_sideStageFocusedApplication)
214+ createMainStage();
163− m_sideStageFocusedApplication->hideWindow();
215+ application->showWindow(m_mainStage);
164− m_sideStageFocusedApplication = application;
216+ m_mainStage->setZ(-1000);
165− if (!m_sideStage)
217+ if (m_sideStage)
166− createSideStage();
218+ m_sideStage->setZ(-2000);
167− application->showWindow(m_sideStage);
219+ } else if (application->stage() == ApplicationInfo::SideStage) {
168− m_sideStage->setZ(-1000);
220+ // unfocus currently focused sidestage app
169− if (m_mainStage)
221+ for (ApplicationInfo *app : m_runningApplications) {
170− m_mainStage->setZ(-2000);
222+ if (app->focused() && app->stage() == ApplicationInfo::SideStage) {
171− Q_EMIT sideStageFocusedApplicationChanged();
223+ app->setFocused(false);
172− return;
224+ app->hideWindow();
225+ }
173 }
226 }
227+
228+ // focus this app
229+ application->setFocused(true);
230+ if (!m_sideStage)
231+ createSideStage();
232+ application->showWindow(m_sideStage);
233+ m_sideStage->setZ(-1000);
234+ if (m_mainStage)
235+ m_mainStage->setZ(-2000);
174 }
236 }
237+
238+ // move app to top of stack
239+ move(m_runningApplications.indexOf(application), 0);
240+ Q_EMIT focusedApplicationIdChanged();
241+ return true;
175}
242}
176
243
177−void ApplicationManager::unfocusCurrentApplication(StageHint stageHint)
244+void ApplicationManager::unfocusCurrentApplication()
178{
245{
179− if (stageHint == SideStage) {
246+ for (ApplicationInfo *app : m_runningApplications) {
180− if (m_sideStageFocusedApplication) {
247+ if (app->focused()) {
181− m_sideStageFocusedApplication->hideWindow();
248+ app->hideWindow();
182− m_sideStageFocusedApplication = 0;
249+ app->setFocused(false);
183− Q_EMIT sideStageFocusedApplicationChanged();
184− }
185− } else {
186− if (m_mainStageFocusedApplication) {
187− m_mainStageFocusedApplication->hideWindow();
188− m_mainStageFocusedApplication = 0;
189− Q_EMIT mainStageFocusedApplicationChanged();
190 }
250 }
191 }
251 }
252+ Q_EMIT focusedApplicationIdChanged();
192}
253}
193
254
194void ApplicationManager::generateQmlStrings(ApplicationInfo *application)
255void ApplicationManager::generateQmlStrings(ApplicationInfo *application)
@@ -213,7 +274,7 @@ void ApplicationManager::generateQmlStrings(ApplicationInfo *application)
213 " fillMode: Image.PreserveAspectCrop\n"
274 " fillMode: Image.PreserveAspectCrop\n"
214 "}").arg(topMargin)
275 "}").arg(topMargin)
215 .arg(shellAppDirectory())
276 .arg(shellAppDirectory())
216− .arg(application->icon());
277+ .arg(application->icon().toString());
217 application->setWindowQml(windowQml);
278 application->setWindowQml(windowQml);
218
279
219 QString imageQml = QString(
280 QString imageQml = QString(
@@ -224,159 +285,130 @@ void ApplicationManager::generateQmlStrings(ApplicationInfo *application)
224 " smooth: true\n"
285 " smooth: true\n"
225 " fillMode: Image.PreserveAspectCrop\n"
286 " fillMode: Image.PreserveAspectCrop\n"
226 "}").arg(shellAppDirectory())
287 "}").arg(shellAppDirectory())
227− .arg(application->icon());
288+ .arg(application->icon().toString());
228 application->setImageQml(imageQml);
289 application->setImageQml(imageQml);
229}
290}
230
291
231void ApplicationManager::buildListOfAvailableApplications()
292void ApplicationManager::buildListOfAvailableApplications()
232{
293{
233 ApplicationInfo *application;
294 ApplicationInfo *application;
234− qint64 nextHandle = 1;
235
295
236 application = new ApplicationInfo(this);
296 application = new ApplicationInfo(this);
237− application->setDesktopFile("/usr/share/applications/phone-app.desktop");
297+ application->setAppId("phone-app");
238 application->setName("Phone");
298 application->setName("Phone");
239− application->setIcon("phone");
299+ application->setIcon(QUrl("phone"));
240− application->setExec("/usr/bin/phone-app");
241 application->setStage(ApplicationInfo::SideStage);
300 application->setStage(ApplicationInfo::SideStage);
242− application->setHandle(nextHandle++);
243 generateQmlStrings(application);
301 generateQmlStrings(application);
244 m_availableApplications.append(application);
302 m_availableApplications.append(application);
245
303
246 application = new ApplicationInfo(this);
304 application = new ApplicationInfo(this);
247− application->setDesktopFile("/usr/share/applications/camera-app.desktop");
305+ application->setAppId("camera-app");
248 application->setName("Camera");
306 application->setName("Camera");
249− application->setIcon("camera");
307+ application->setIcon(QUrl("camera"));
250 application->setFullscreen(true);
308 application->setFullscreen(true);
251− application->setExec("/usr/bin/camera-app --fullscreen");
252− application->setHandle(nextHandle++);
253 generateQmlStrings(application);
309 generateQmlStrings(application);
254 m_availableApplications.append(application);
310 m_availableApplications.append(application);
255
311
256 application = new ApplicationInfo(this);
312 application = new ApplicationInfo(this);
257− application->setDesktopFile("/usr/share/applications/gallery-app.desktop");
313+ application->setAppId("gallery-app");
258 application->setName("Gallery");
314 application->setName("Gallery");
259− application->setIcon("gallery");
315+ application->setIcon(QUrl("gallery"));
260− application->setExec("/usr/bin/gallery-app");
261− application->setHandle(nextHandle++);
262 generateQmlStrings(application);
316 generateQmlStrings(application);
263 m_availableApplications.append(application);
317 m_availableApplications.append(application);
264
318
265 application = new ApplicationInfo(this);
319 application = new ApplicationInfo(this);
266− application->setDesktopFile("/usr/share/applications/facebook-webapp.desktop");
320+ application->setAppId("facebook-webapp");
267 application->setName("Facebook");
321 application->setName("Facebook");
268− application->setIcon("facebook");
322+ application->setIcon(QUrl("facebook"));
269− application->setExec("/usr/bin/webbrowser-app --chromeless http://m.facebook.com");
270 application->setStage(ApplicationInfo::SideStage);
323 application->setStage(ApplicationInfo::SideStage);
271− application->setHandle(nextHandle++);
272 generateQmlStrings(application);
324 generateQmlStrings(application);
273 m_availableApplications.append(application);
325 m_availableApplications.append(application);
274
326
275 application = new ApplicationInfo(this);
327 application = new ApplicationInfo(this);
276− application->setDesktopFile("/usr/share/applications/webbrowser-app.desktop");
328+ application->setAppId("webbrowser-app");
277 application->setName("Browser");
329 application->setName("Browser");
278− application->setIcon("browser");
330+ application->setIcon(QUrl("browser"));
279− application->setExec("/usr/bin/webbrowser-app");
280− application->setHandle(nextHandle++);
281 generateQmlStrings(application);
331 generateQmlStrings(application);
282 m_availableApplications.append(application);
332 m_availableApplications.append(application);
283
333
284 application = new ApplicationInfo(this);
334 application = new ApplicationInfo(this);
285− application->setDesktopFile("/usr/share/applications/twitter-webapp.desktop");
335+ application->setAppId("twitter-webapp");
286 application->setName("Twitter");
336 application->setName("Twitter");
287− application->setIcon("twitter");
337+ application->setIcon(QUrl("twitter"));
288− application->setExec("/usr/bin/webbrowser-app --chromeless http://www.twitter.com");
289 application->setStage(ApplicationInfo::SideStage);
338 application->setStage(ApplicationInfo::SideStage);
290− application->setHandle(nextHandle++);
291 generateQmlStrings(application);
339 generateQmlStrings(application);
292 m_availableApplications.append(application);
340 m_availableApplications.append(application);
293
341
294 application = new ApplicationInfo(this);
342 application = new ApplicationInfo(this);
295− application->setDesktopFile("/usr/share/applications/gmail-webapp.desktop");
343+ application->setAppId("gmail-webapp");
296 application->setName("GMail");
344 application->setName("GMail");
297− application->setIcon("gmail");
345+ application->setIcon(QUrl("gmail"));
298− application->setExec("/usr/bin/webbrowser-app --chromeless http://m.gmail.com");
299− application->setHandle(nextHandle++);
300 m_availableApplications.append(application);
346 m_availableApplications.append(application);
301
347
302 application = new ApplicationInfo(this);
348 application = new ApplicationInfo(this);
303− application->setDesktopFile("/usr/share/applications/ubuntu-weather-app.desktop");
349+ application->setAppId("ubuntu-weather-app");
304 application->setName("Weather");
350 application->setName("Weather");
305− application->setIcon("weather");
351+ application->setIcon(QUrl("weather"));
306− application->setExec("/usr/bin/qmlscene /usr/share/ubuntu-weather-app/ubuntu-weather-app.qml");
307 application->setStage(ApplicationInfo::SideStage);
352 application->setStage(ApplicationInfo::SideStage);
308− application->setHandle(nextHandle++);
309 generateQmlStrings(application);
353 generateQmlStrings(application);
310 m_availableApplications.append(application);
354 m_availableApplications.append(application);
311
355
312 application = new ApplicationInfo(this);
356 application = new ApplicationInfo(this);
313− application->setDesktopFile("/usr/share/applications/notes-app.desktop");
357+ application->setAppId("notes-app");
314 application->setName("Notepad");
358 application->setName("Notepad");
315− application->setIcon("notepad");
359+ application->setIcon(QUrl("notepad"));
316− application->setExec("/usr/bin/qmlscene /usr/share/notes-app/NotesApp.qml");
317 application->setStage(ApplicationInfo::SideStage);
360 application->setStage(ApplicationInfo::SideStage);
318− application->setHandle(nextHandle++);
319 m_availableApplications.append(application);
361 m_availableApplications.append(application);
320
362
321 application = new ApplicationInfo(this);
363 application = new ApplicationInfo(this);
322− application->setDesktopFile("/usr/share/applications/calendar-app.desktop");
364+ application->setAppId("calendar-app");
323 application->setName("Calendar");
365 application->setName("Calendar");
324− application->setIcon("calendar");
366+ application->setIcon(QUrl("calendar"));
325− application->setExec("/usr/bin/qmlscene /usr/share/calendar-app/calendar.qml");
326 application->setStage(ApplicationInfo::SideStage);
367 application->setStage(ApplicationInfo::SideStage);
327− application->setHandle(nextHandle++);
328 m_availableApplications.append(application);
368 m_availableApplications.append(application);
329
369
330 application = new ApplicationInfo(this);
370 application = new ApplicationInfo(this);
331− application->setDesktopFile("/usr/share/applications/mediaplayer-app.desktop");
371+ application->setAppId("mediaplayer-app");
332 application->setName("Media Player");
372 application->setName("Media Player");
333− application->setIcon("mediaplayer-app");
373+ application->setIcon(QUrl("mediaplayer-app"));
334 application->setFullscreen(true);
374 application->setFullscreen(true);
335− application->setExec("/usr/bin/mediaplayer-app");
336− application->setHandle(nextHandle++);
337 m_availableApplications.append(application);
375 m_availableApplications.append(application);
338
376
339 application = new ApplicationInfo(this);
377 application = new ApplicationInfo(this);
340− application->setDesktopFile("/usr/share/applications/evernote.desktop");
378+ application->setAppId("evernote");
341 application->setName("Evernote");
379 application->setName("Evernote");
342− application->setIcon("evernote");
380+ application->setIcon(QUrl("evernote"));
343− application->setHandle(nextHandle++);
344 m_availableApplications.append(application);
381 m_availableApplications.append(application);
345
382
346 application = new ApplicationInfo(this);
383 application = new ApplicationInfo(this);
347− application->setDesktopFile("/usr/share/applications/map.desktop");
384+ application->setAppId("map");
348 application->setName("Map");
385 application->setName("Map");
349− application->setIcon("map");
386+ application->setIcon(QUrl("map"));
350− application->setHandle(nextHandle++);
351 generateQmlStrings(application);
387 generateQmlStrings(application);
352 m_availableApplications.append(application);
388 m_availableApplications.append(application);
353
389
354 application = new ApplicationInfo(this);
390 application = new ApplicationInfo(this);
355− application->setDesktopFile("/usr/share/applications/pinterest.desktop");
391+ application->setAppId("pinterest");
356 application->setName("Pinterest");
392 application->setName("Pinterest");
357− application->setIcon("pinterest");
393+ application->setIcon(QUrl("pinterest"));
358− application->setHandle(nextHandle++);
359 m_availableApplications.append(application);
394 m_availableApplications.append(application);
360
395
361 application = new ApplicationInfo(this);
396 application = new ApplicationInfo(this);
362− application->setDesktopFile("/usr/share/applications/soundcloud.desktop");
397+ application->setAppId("soundcloud");
363 application->setName("SoundCloud");
398 application->setName("SoundCloud");
364− application->setIcon("soundcloud");
399+ application->setIcon(QUrl("soundcloud"));
365− application->setHandle(nextHandle++);
366 m_availableApplications.append(application);
400 m_availableApplications.append(application);
367
401
368 application = new ApplicationInfo(this);
402 application = new ApplicationInfo(this);
369− application->setDesktopFile("/usr/share/applications/wikipedia.desktop");
403+ application->setAppId("wikipedia");
370 application->setName("Wikipedia");
404 application->setName("Wikipedia");
371− application->setIcon("wikipedia");
405+ application->setIcon(QUrl("wikipedia"));
372− application->setHandle(nextHandle++);
373 m_availableApplications.append(application);
406 m_availableApplications.append(application);
374
407
375 application = new ApplicationInfo(this);
408 application = new ApplicationInfo(this);
376− application->setDesktopFile("/usr/share/applications/youtube.desktop");
409+ application->setAppId("youtube");
377 application->setName("YouTube");
410 application->setName("YouTube");
378− application->setIcon("youtube");
411+ application->setIcon(QUrl("youtube"));
379− application->setHandle(nextHandle++);
380 m_availableApplications.append(application);
412 m_availableApplications.append(application);
381}
413}
382
414
tests/mocks/Ubuntu/Application/ApplicationManager.h → tests/mocks/Unity/Application/ApplicationManager.hrenamed+26−26
@@ -20,12 +20,15 @@
20#include <QObject>
20#include <QObject>
21#include <QList>
21#include <QList>
22#include <QStringList>
22#include <QStringList>
23−#include "ApplicationListModel.h"
24#include "ApplicationInfo.h"
23#include "ApplicationInfo.h"
25
24
25+// unity-api
26+#include <unity/shell/application/ApplicationManagerInterface.h>
27+
26class QQuickItem;
28class QQuickItem;
29+using namespace unity::shell::application;
27
30
28−class ApplicationManager : public QObject {
31+class ApplicationManager : public ApplicationManagerInterface {
29 Q_OBJECT
32 Q_OBJECT
30 Q_ENUMS(Role)
33 Q_ENUMS(Role)
31 Q_ENUMS(StageHint)
34 Q_ENUMS(StageHint)
@@ -39,12 +42,6 @@ class ApplicationManager : public QObject {
39 Q_PROPERTY(int sideStageWidth READ sideStageWidth)
42 Q_PROPERTY(int sideStageWidth READ sideStageWidth)
40 Q_PROPERTY(StageHint stageHint READ stageHint)
43 Q_PROPERTY(StageHint stageHint READ stageHint)
41 Q_PROPERTY(FormFactorHint formFactorHint READ formFactorHint)
44 Q_PROPERTY(FormFactorHint formFactorHint READ formFactorHint)
42− Q_PROPERTY(ApplicationListModel* mainStageApplications READ mainStageApplications)
43− Q_PROPERTY(ApplicationListModel* sideStageApplications READ sideStageApplications)
44− Q_PROPERTY(ApplicationInfo* mainStageFocusedApplication READ mainStageFocusedApplication
45− NOTIFY mainStageFocusedApplicationChanged)
46− Q_PROPERTY(ApplicationInfo* sideStageFocusedApplication READ sideStageFocusedApplication
47− NOTIFY sideStageFocusedApplicationChanged)
48
45
49 Q_PROPERTY(bool fake READ fake CONSTANT)
46 Q_PROPERTY(bool fake READ fake CONSTANT)
50
47
@@ -64,7 +61,8 @@ class ApplicationManager : public QObject {
64 DesktopFormFactor, PhoneFormFactor, TabletFormFactor
61 DesktopFormFactor, PhoneFormFactor, TabletFormFactor
65 };
62 };
66 enum FavoriteApplication {
63 enum FavoriteApplication {
67− CameraApplication, GalleryApplication, BrowserApplication, ShareApplication
64+ CameraApplication, GalleryApplication, BrowserApplication, ShareApplication,
65+ PhoneApplication, DialerApplication, MessagingApplication, AddressbookApplication
68 };
66 };
69 enum Flag {
67 enum Flag {
70 NoFlag = 0x0,
68 NoFlag = 0x0,
@@ -77,29 +75,34 @@ class ApplicationManager : public QObject {
77 int sideStageWidth() const;
75 int sideStageWidth() const;
78 StageHint stageHint() const;
76 StageHint stageHint() const;
79 FormFactorHint formFactorHint() const;
77 FormFactorHint formFactorHint() const;
80− ApplicationListModel* mainStageApplications() const;
81− ApplicationListModel* sideStageApplications() const;
82− ApplicationInfo* mainStageFocusedApplication() const;
83− ApplicationInfo* sideStageFocusedApplication() const;
84
78
85 bool fake() { return true; }
79 bool fake() { return true; }
86
80
87− Q_INVOKABLE void focusApplication(int handle);
81+ // QAbstractItemModel methods.
82+ int rowCount(const QModelIndex& parent = QModelIndex()) const override;
83+ QVariant data(const QModelIndex& index, int role) const override;
84+ Q_INVOKABLE ApplicationInfo *get(int index) const override;
85+ Q_INVOKABLE ApplicationInfo *findApplication(const QString &appId) const override;
86+
87+ Q_INVOKABLE void move(int from, int to);
88+
89+ // Application control methods
90+ Q_INVOKABLE bool focusApplication(const QString &appId) override;
88− Q_INVOKABLE void unfocusCurrentApplication(StageHint stageHint);
91+ Q_INVOKABLE void unfocusCurrentApplication() override;
89− Q_INVOKABLE ApplicationInfo* startProcess(QString desktopFile,
92+ Q_INVOKABLE ApplicationInfo *startApplication(const QString &appId, const QStringList &arguments = QStringList()) override;
90− ExecFlags flags,
91− QStringList arguments = QStringList());
93+ Q_INVOKABLE ApplicationInfo *startApplication(const QString &appId, ExecFlags flags, const QStringList &arguments = QStringList());
92− Q_INVOKABLE void stopProcess(ApplicationInfo* application);
94+ Q_INVOKABLE bool stopApplication(const QString &appId) override;
93− Q_INVOKABLE void startWatcher() {}
95+
96+ QString focusedApplicationId() const override;
94
97
95 Q_SIGNALS:
98 Q_SIGNALS:
96 void keyboardHeightChanged();
99 void keyboardHeightChanged();
97 void keyboardVisibleChanged();
100 void keyboardVisibleChanged();
98− void mainStageFocusedApplicationChanged();
99− void sideStageFocusedApplicationChanged();
100 void focusRequested(FavoriteApplication favoriteApplication);
101 void focusRequested(FavoriteApplication favoriteApplication);
101
102
102 private:
103 private:
104+ void add(ApplicationInfo *application);
105+ void remove(ApplicationInfo* application);
103 void showApplicationWindow(ApplicationInfo *application);
106 void showApplicationWindow(ApplicationInfo *application);
104 void buildListOfAvailableApplications();
107 void buildListOfAvailableApplications();
105 void generateQmlStrings(ApplicationInfo *application);
108 void generateQmlStrings(ApplicationInfo *application);
@@ -109,10 +112,7 @@ class ApplicationManager : public QObject {
109 void createSideStage();
112 void createSideStage();
110 int m_keyboardHeight;
113 int m_keyboardHeight;
111 bool m_keyboardVisible;
114 bool m_keyboardVisible;
112− ApplicationListModel* m_mainStageApplications;
115+ QList<ApplicationInfo*> m_runningApplications;
113− ApplicationListModel* m_sideStageApplications;
114− ApplicationInfo* m_mainStageFocusedApplication;
115− ApplicationInfo* m_sideStageFocusedApplication;
116 QList<ApplicationInfo*> m_availableApplications;
116 QList<ApplicationInfo*> m_availableApplications;
117 QQmlComponent *m_mainStageComponent;
117 QQmlComponent *m_mainStageComponent;
118 QQuickItem *m_mainStage;
118 QQuickItem *m_mainStage;
tests/mocks/Unity/Application/CMakeLists.txtnew file+37
@@ -0,0 +1,37 @@
1+include(FindPkgConfig)
2+pkg_check_modules(APPLICATION_API REQUIRED unity-shell-application)
3+
4+set(FakeUnityApplicationQml_SOURCES
5+ plugin.cpp
6+ ApplicationInfo.cpp
7+ ApplicationImage.cpp
8+ ApplicationManager.cpp
9+ ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/ApplicationInfoInterface.h
10+ ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/ApplicationManagerInterface.h
11+)
12+
13+add_library(FakeUnityApplicationQml MODULE ${FakeUnityApplicationQml_SOURCES})
14+
15+qt5_use_modules(FakeUnityApplicationQml Core Quick)
16+
17+# copy files into build directory for shadow builds
18+add_custom_target(UnityAppQmlDirFile ALL
19+ COMMAND cp "${CMAKE_CURRENT_SOURCE_DIR}/qmldir" ${CMAKE_CURRENT_BINARY_DIR}
20+ DEPENDS qmldir
21+)
22+add_custom_target(InputFilterAreaQmlFile ALL
23+ COMMAND cp "${CMAKE_CURRENT_SOURCE_DIR}/InputFilterArea.qml" ${CMAKE_CURRENT_BINARY_DIR}
24+ DEPENDS InputFilterArea.qml
25+)
26+add_custom_target(OSKControllerQmlFile ALL
27+ COMMAND cp "${CMAKE_CURRENT_SOURCE_DIR}/OSKController.qml" ${CMAKE_CURRENT_BINARY_DIR}
28+ DEPENDS OSKController.qml
29+)
30+
31+install(TARGETS FakeUnityApplicationQml
32+ DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/mocks/Unity/Application
33+ )
34+
35+install(FILES qmldir InputFilterArea.qml OSKController.qml
36+ DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/mocks/Unity/Application
37+ )
tests/mocks/Ubuntu/Application/InputFilterArea.qml → tests/mocks/Unity/Application/InputFilterArea.qmlrenamed

The content is the same.

tests/mocks/Unity/Application/OSKController.qmlnew file+20
@@ -0,0 +1,20 @@
1+/*
2+ * Copyright (C) 2013 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+
17+import QtQuick 2.0;
18+
19+Item {
20+}
tests/mocks/Ubuntu/Application/plugin.cpp → tests/mocks/Unity/Application/plugin.cpprenamed+1−3
@@ -17,7 +17,6 @@
17#include "plugin.h"
17#include "plugin.h"
18#include "ApplicationInfo.h"
18#include "ApplicationInfo.h"
19#include "ApplicationImage.h"
19#include "ApplicationImage.h"
20−#include "ApplicationListModel.h"
21#include "ApplicationManager.h"
20#include "ApplicationManager.h"
22
21
23#include <qqml.h>
22#include <qqml.h>
@@ -28,11 +27,10 @@ static QObject* applicationManagerSingleton(QQmlEngine* engine, QJSEngine* scrip
28 return new ApplicationManager();
27 return new ApplicationManager();
29}
28}
30
29
31−void FakeUbuntuApplicationQmlPlugin::registerTypes(const char *uri)
30+void FakeUnityApplicationQmlPlugin::registerTypes(const char *uri)
32{
31{
33 qmlRegisterSingletonType<ApplicationManager>(
32 qmlRegisterSingletonType<ApplicationManager>(
34 uri, 0, 1, "ApplicationManager", applicationManagerSingleton);
33 uri, 0, 1, "ApplicationManager", applicationManagerSingleton);
35 qmlRegisterType<ApplicationInfo>(uri, 0, 1, "ApplicationInfo");
34 qmlRegisterType<ApplicationInfo>(uri, 0, 1, "ApplicationInfo");
36 qmlRegisterType<ApplicationImage>(uri, 0, 1, "ApplicationImage");
35 qmlRegisterType<ApplicationImage>(uri, 0, 1, "ApplicationImage");
37− qmlRegisterType<ApplicationListModel>(uri, 0, 1, "ApplicationListModel");
38}
36}
tests/mocks/Ubuntu/Application/plugin.h → tests/mocks/Unity/Application/plugin.hrenamed+1−1
@@ -19,7 +19,7 @@
19
19
20#include <QQmlExtensionPlugin>
20#include <QQmlExtensionPlugin>
21
21
22−class FakeUbuntuApplicationQmlPlugin : public QQmlExtensionPlugin
22+class FakeUnityApplicationQmlPlugin : public QQmlExtensionPlugin
23{
23{
24 Q_OBJECT
24 Q_OBJECT
25 Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
25 Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
tests/mocks/Unity/Application/qmldirnew file+4
@@ -0,0 +1,4 @@
1+module Unity.Application
2+plugin FakeUnityApplicationQml
3+InputFilterArea 0.1 InputFilterArea.qml
4+OSKController 0.1 OSKController.qml
tests/mocks/Unity/CMakeLists.txt+1
@@ -1,3 +1,4 @@
1+add_subdirectory(Application)
1add_subdirectory(Indicators)
2add_subdirectory(Indicators)
2
3
3pkg_search_module(DEE dee-1.0 REQUIRED)
4pkg_search_module(DEE dee-1.0 REQUIRED)
tests/plugins/Unity/Launcher/CMakeLists.txt+9
@@ -57,3 +57,12 @@ foreach(DESKTOP_FILE ${DESKTOP_FILES})
57 DESTINATION ${CMAKE_CURRENT_BINARY_DIR}
57 DESTINATION ${CMAKE_CURRENT_BINARY_DIR}
58 )
58 )
59endforeach()
59endforeach()
60+
61+# copy .svg files into build directory for shadow builds
62+file(GLOB DESKTOP_FILES *.svg)
63+
64+foreach(DESKTOP_FILE ${DESKTOP_FILES})
65+ file(COPY "${DESKTOP_FILE}"
66+ DESTINATION ${CMAKE_CURRENT_BINARY_DIR}
67+ )
68+endforeach()
tests/plugins/Unity/Launcher/click-icon.desktopnew file+4
@@ -0,0 +1,4 @@
1+[Desktop Entry]
2+Name=Click Package Icon
3+Icon=click-icon.svg
4+Path=/path/to/some/click/app
tests/plugins/Unity/Launcher/launcherbackendtest.cpp+25
@@ -54,6 +54,31 @@ private Q_SLOTS:
54 QCOMPARE(backend.isPinned("rel-icon"), true);
54 QCOMPARE(backend.isPinned("rel-icon"), true);
55 QCOMPARE(backend.isPinned("no-name"), false); // doesn't exist anymore!
55 QCOMPARE(backend.isPinned("no-name"), false); // doesn't exist anymore!
56 }
56 }
57+
58+ void testIcon_data() {
59+ QTest::addColumn<QString>("appId");
60+ QTest::addColumn<QString>("expectedIcon");
61+
62+ // Needs to expand a relative icon to the absolute path
63+ QTest::newRow("relative icon path") << "rel-icon" << QDir::currentPath() + "/rel-icon.svg";
64+
65+ // In case an icon is not found on disk, it needs to fallback on image://theme/ for it
66+ QTest::newRow("fallback on theme") << "abs-icon" << "image://theme//path/to/icon.png";
67+
68+ // Click packages have a relative icon path but an absolute path as a separate entry
69+ // As we don't want to rely on a click app being installed for the test, accept it with the image://theme fallback
70+ QTest::newRow("click package icon") << "click-icon" << "image://theme//path/to/some/click/app/click-icon.svg";
71+ }
72+
73+ void testIcon() {
74+ QFETCH(QString, appId);
75+ QFETCH(QString, expectedIcon);
76+
77+ LauncherBackend backend(false);
78+ backend.setStoredApplications(QStringList() << appId);
79+
80+ QCOMPARE(backend.icon(appId), expectedIcon);
81+ }
57};
82};
58
83
59QTEST_GUILESS_MAIN(LauncherBackendTest)
84QTEST_GUILESS_MAIN(LauncherBackendTest)
tests/plugins/Unity/Launcher/rel-icon.desktop+1−1
@@ -1,3 +1,3 @@
1[Desktop Entry]
1[Desktop Entry]
2Name=Relative Icon
2Name=Relative Icon
3−Icon=rel-icon
3+Icon=rel-icon.svg
tests/plugins/Unity/Launcher/rel-icon.svgnew file

No changes to the content.

tests/qmltests/Components/tst_Stage.qml+1−1
@@ -18,7 +18,7 @@ import QtQuick 2.0
18import QtTest 1.0
18import QtTest 1.0
19import ".."
19import ".."
20import "../../../Components"
20import "../../../Components"
21−import Ubuntu.Application 0.1
21+import Unity.Application 0.1
22import Ubuntu.Components 0.1
22import Ubuntu.Components 0.1
23import Unity.Test 0.1 as UT
23import Unity.Test 0.1 as UT
24import "tst_Stage"
24import "tst_Stage"
tests/qmltests/Dash/Apps/tst_RunningApplicationsGrid.qml+55−37
@@ -16,7 +16,6 @@
16
16
17import QtQuick 2.0
17import QtQuick 2.0
18import QtTest 1.0
18import QtTest 1.0
19−import Ubuntu.Application 0.1
20import "../../../../Dash/Apps"
19import "../../../../Dash/Apps"
21import Unity.Test 0.1 as UT
20import Unity.Test 0.1 as UT
22
21
@@ -29,8 +28,12 @@ Item {
29
28
30 property bool sideStageEnabled: false
29 property bool sideStageEnabled: false
31
30
32− function stopProcess(application) {
31+ function stopApplication(appId) {
32+ for (var i=0, len=fakeRunningAppsModel.count; i<len; i++) {
33+ if (appId == fakeRunningAppsModel.get(i).appId) {
33− fakeRunningAppsModel.remove(application)
34+ fakeRunningAppsModel.remove(i)
35+ }
36+ }
34 }
37 }
35 }
38 }
36
39
@@ -40,47 +43,62 @@ Item {
40 property bool stageScreenshotsReady: false
43 property bool stageScreenshotsReady: false
41 property var applicationManager: fakeApplicationManager
44 property var applicationManager: fakeApplicationManager
42
45
43− function activateApplication(desktopFile) {
46+ function activateApplication(appId) {
44 }
47 }
45 }
48 }
46
49
50+ ListModel {
47− ApplicationListModel { id: fakeRunningAppsModel }
51+ id: fakeRunningAppsModel
48−
52+
49− ApplicationInfo {
53+ function contains(appId) {
50− id: phoneApp
54+ for (var i=0, len=fakeRunningAppsModel.count; i<len; i++) {
51− name: "Phone"
55+ if (appId == fakeRunningAppsModel.get(i).appId) {
52− icon: "phone-app"
56+ return true;
53− exec: "/usr/bin/phone-app"
57+ }
54− stage: ApplicationInfo.MainStage
58+ }
55− desktopFile: "phone.desktop"
59+ return false;
56− imageQml: "import QtQuick 2.0\n" +
60+ }
57− "Rectangle { \n" +
61+
58− " anchors.fill:parent \n" +
62+ function rePopulate() {
59− " color:'darkgreen' \n" +
63+ for (var i=0, len=availableAppsModel.count; i<len; i++) {
60− " Text { anchors.centerIn: parent; text: 'PHONE' } \n" +
64+ fakeRunningAppsModel.append(availableAppsModel.get(i));
65+ }
61− "}"
66+ }
62 }
67 }
63
68
64− ApplicationInfo {
69+ ListModel {
65− id: calendarApp
70+ id: availableAppsModel
71+ ListElement {
72+ name: "Phone"
73+ icon: "phone-app"
74+ exec: "/usr/bin/phone-app"
75+ appId: "phone"
76+ imageQml: "import QtQuick 2.0\n \
77+ Rectangle { \n \
78+ anchors.fill:parent \n \
79+ color:'darkgreen' \n \
80+ Text { anchors.centerIn: parent; text: 'PHONE' } \n \
81+ }"
82+ }
83+
84+ ListElement {
66− name: "Calendar"
85+ name: "Calendar"
67− icon: "calendar-app"
86+ icon: "calendar-app"
68− exec: "/usr/bin/calendar-app"
87+ exec: "/usr/bin/calendar-app"
69− stage: ApplicationInfo.MainStage
70− desktopFile: "calendar.desktop"
88+ appId: "calendar"
71− imageQml: "import QtQuick 2.0\n" +
89+ imageQml: "import QtQuick 2.0\n \
72− "Rectangle { \n" +
90+ Rectangle { \n \
73− " anchors.fill:parent \n" +
91+ anchors.fill:parent \n \
74− " color:'darkblue' \n" +
92+ color:'darkblue' \n \
75− " Text { anchors.centerIn: parent; text: 'CALENDAR'\n" +
93+ Text { anchors.centerIn: parent; text: 'CALENDAR'\n \
76− " color:'white'} \n" +
94+ color:'white'} \n \
77− "}"
95+ }"
96+ }
78 }
97 }
79
98
80 function resetRunningApplications() {
99 function resetRunningApplications() {
81 fakeRunningAppsModel.clear()
100 fakeRunningAppsModel.clear()
82− fakeRunningAppsModel.add(phoneApp)
101+ fakeRunningAppsModel.rePopulate()
83− fakeRunningAppsModel.add(calendarApp)
84 }
102 }
85
103
86 Component.onCompleted: {
104 Component.onCompleted: {
@@ -185,11 +203,11 @@ Item {
185 var calendarTile = findChild(runningApplicationsGrid, "runningAppTile Calendar")
203 var calendarTile = findChild(runningApplicationsGrid, "runningAppTile Calendar")
186 verify(calendarTile != undefined)
204 verify(calendarTile != undefined)
187
205
188− verify(fakeRunningAppsModel.contains(calendarApp))
206+ verify(fakeRunningAppsModel.contains("calendar"))
189
207
190 mouseClick(calendarTile, calendarTile.width/2, calendarTile.height/2)
208 mouseClick(calendarTile, calendarTile.width/2, calendarTile.height/2)
191
209
192− verify(!fakeRunningAppsModel.contains(calendarApp))
210+ verify(!fakeRunningAppsModel.contains("calendar"))
193
211
194 // The tile for the Calendar app should eventually vanish since the
212 // The tile for the Calendar app should eventually vanish since the
195 // application has been terminated
213 // application has been terminated
tests/qmltests/tst_Shell.qml+8−8
@@ -20,7 +20,7 @@
20import QtQuick 2.0
20import QtQuick 2.0
21import QtTest 1.0
21import QtTest 1.0
22import GSettings 1.0
22import GSettings 1.0
23−import Ubuntu.Application 0.1
23+import Unity.Application 0.1
24import Unity.Test 0.1 as UT
24import Unity.Test 0.1 as UT
25import Powerd 0.1
25import Powerd 0.1
26
26
@@ -66,16 +66,16 @@ Item {
66 }
66 }
67
67
68 // kill all (fake) running apps
68 // kill all (fake) running apps
69− killApps(ApplicationManager.mainStageApplications);
69+ killApps(ApplicationManager);
70− killApps(ApplicationManager.sideStageApplications);
71
70
72 var dashHome = findChild(shell, "DashHome");
71 var dashHome = findChild(shell, "DashHome");
73 swipeUntilScopeViewIsReached(dashHome);
72 swipeUntilScopeViewIsReached(dashHome);
74 }
73 }
75
74
76 function killApps(apps) {
75 function killApps(apps) {
76+ if (!apps) return;
77 while (apps.count > 0) {
77 while (apps.count > 0) {
78− ApplicationManager.stopProcess(apps.get(0));
78+ ApplicationManager.stopApplication(apps.get(0).appId);
79 }
79 }
80 }
80 }
81
81
@@ -122,8 +122,8 @@ Item {
122 tapOnAppIconInLauncher();
122 tapOnAppIconInLauncher();
123 waitUntilApplicationWindowIsFullyVisible();
123 waitUntilApplicationWindowIsFullyVisible();
124
124
125− var mainApp = ApplicationManager.mainStageFocusedApplication;
125+ var mainApp = ApplicationManager.focusedApplicationId;
126− tryCompareFunction(function() { return mainApp != null; }, true);
126+ tryCompareFunction(function() { return mainApp != ""; }, true);
127
127
128 // Try to suspend while proximity is engaged...
128 // Try to suspend while proximity is engaged...
129 Powerd.displayPowerStateChange(Powerd.Off, Powerd.UseProximity);
129 Powerd.displayPowerStateChange(Powerd.Off, Powerd.UseProximity);
@@ -132,11 +132,11 @@ Item {
132 // Now really suspend
132 // Now really suspend
133 Powerd.displayPowerStateChange(Powerd.Off, 0);
133 Powerd.displayPowerStateChange(Powerd.Off, 0);
134 tryCompare(greeter, "showProgress", 1);
134 tryCompare(greeter, "showProgress", 1);
135− tryCompare(ApplicationManager, "mainStageFocusedApplication", null);
135+ tryCompare(ApplicationManager, "focusedApplicationId", "");
136
136
137 // And wake up
137 // And wake up
138 Powerd.displayPowerStateChange(Powerd.On, 0);
138 Powerd.displayPowerStateChange(Powerd.On, 0);
139− tryCompare(ApplicationManager, "mainStageFocusedApplication", mainApp);
139+ tryCompare(ApplicationManager, "focusedApplicationId", mainApp);
140 tryCompare(greeter, "showProgress", 1);
140 tryCompare(greeter, "showProgress", 1);
141 }
141 }
142
142