on xenial help sign in
Separate greeter from shell; use real system liblightdm; add SessionManager plugin
608f933Michael Terry
CMakeLists.txt+25−1
@@ -95,6 +95,7 @@ declare_autopilot_test(shell unity8.shell ${CMAKE_SOURCE_DIR}/tests/autopilot/)
95declare_autopilot_test(indicators_client unity8.indicators_client ${CMAKE_SOURCE_DIR}/tests/autopilot/)
95declare_autopilot_test(indicators_client unity8.indicators_client ${CMAKE_SOURCE_DIR}/tests/autopilot/)
96
96
97set(SHELL_APP unity8)
97set(SHELL_APP unity8)
98+set(GREETER_APP unity8-greeter)
98
99
99set(shell_app_HDRS
100set(shell_app_HDRS
100 )
101 )
@@ -105,8 +106,22 @@ add_executable(${SHELL_APP}
105 main.cpp
106 main.cpp
106 MouseTouchAdaptor.cpp
107 MouseTouchAdaptor.cpp
107 )
108 )
109+add_executable(${GREETER_APP}
110+ ${greeterapplication_MOC_SRCS}
111+ ApplicationArguments.h
112+ main.cpp
113+ MouseTouchAdaptor.cpp
114+ )
115+
116+set_target_properties(${SHELL_APP} PROPERTIES
117+ COMPILE_DEFINITIONS "APP_NAME=\"Unity 8\";QML_FILE=\"Shell.qml\""
118+ )
119+set_target_properties(${GREETER_APP} PROPERTIES
120+ COMPILE_DEFINITIONS "APP_NAME=\"Unity 8 Greeter\";QML_FILE=\"GreeterShell.qml\""
121+ )
108
122
109qt5_use_modules(${SHELL_APP} Qml Quick Test)
123qt5_use_modules(${SHELL_APP} Qml Quick Test)
124+qt5_use_modules(${GREETER_APP} Qml Quick Test)
110pkg_check_modules(XCB REQUIRED xcb)
125pkg_check_modules(XCB REQUIRED xcb)
111
126
112if (NOT "${XCB_INCLUDE_DIRS}" STREQUAL "")
127if (NOT "${XCB_INCLUDE_DIRS}" STREQUAL "")
@@ -118,9 +133,14 @@ target_link_libraries(${SHELL_APP}
118 ${Qt5Quick_LIBRARIES}
133 ${Qt5Quick_LIBRARIES}
119 ${XCB_LDFLAGS}
134 ${XCB_LDFLAGS}
120 )
135 )
136+target_link_libraries(${GREETER_APP}
137+ ${Qt5Qml_LIBRARIES}
138+ ${Qt5Quick_LIBRARIES}
139+ ${XCB_LDFLAGS}
140+ )
121
141
122# install binaries
142# install binaries
123−install(TARGETS ${SHELL_APP}
143+install(TARGETS ${SHELL_APP} ${GREETER_APP}
124 RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
144 RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
125 )
145 )
126
146
@@ -157,11 +177,15 @@ install(DIRECTORY ${QML_DIRS}
157
177
158# generate desktop file
178# generate desktop file
159configure_file(${SHELL_APP}.desktop.in ${CMAKE_CURRENT_BINARY_DIR}/${SHELL_APP}.desktop @ONLY)
179configure_file(${SHELL_APP}.desktop.in ${CMAKE_CURRENT_BINARY_DIR}/${SHELL_APP}.desktop @ONLY)
180+configure_file(${GREETER_APP}.desktop.in ${CMAKE_CURRENT_BINARY_DIR}/${GREETER_APP}.desktop @ONLY)
160
181
161# install desktop file
182# install desktop file
162install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${SHELL_APP}.desktop
183install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${SHELL_APP}.desktop
163 DESTINATION ${CMAKE_INSTALL_DATADIR}/applications
184 DESTINATION ${CMAKE_INSTALL_DATADIR}/applications
164 )
185 )
186+install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${GREETER_APP}.desktop
187+ DESTINATION ${CMAKE_INSTALL_DATADIR}/xgreeters
188+ )
165
189
166#
190#
167# Translation
191# Translation
Components/BasicShell.qmlnew file+42
@@ -0,0 +1,42 @@
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 Ubuntu.Components 0.1
19+import "../Components"
20+import "../Components/Math.js" as MathLocal
21+
22+FocusScope {
23+ id: shell
24+
25+ // this is only here to select the width / height of the window if not running fullscreen
26+ property bool tablet: false
27+ width: tablet ? units.gu(160) : applicationArguments.hasGeometry() ? applicationArguments.width() : units.gu(40)
28+ height: tablet ? units.gu(100) : applicationArguments.hasGeometry() ? applicationArguments.height() : units.gu(71)
29+
30+ property real edgeSize: units.gu(2)
31+ property url default_background: shell.width >= units.gu(60) ? "../graphics/tablet_background.jpg" : "../graphics/phone_background.jpg"
32+ property url background: default_background
33+
34+ VolumeControl {
35+ id: volumeControl
36+ }
37+
38+ Keys.onVolumeUpPressed: volumeControl.volumeUp()
39+ Keys.onVolumeDownPressed: volumeControl.volumeDown()
40+
41+ focus: true
42+}
Components/PageHeader.qml+3−2
@@ -18,6 +18,7 @@ import QtQuick 2.0
18import Ubuntu.Components 0.1
18import Ubuntu.Components 0.1
19import Ubuntu.Components.Popups 0.1
19import Ubuntu.Components.Popups 0.1
20import Ubuntu.Components.ListItems 0.1 as ListItem
20import Ubuntu.Components.ListItems 0.1 as ListItem
21+import SessionManager 0.1
21
22
22Item {
23Item {
23 /*!
24 /*!
@@ -47,8 +48,8 @@ Item {
47 }
48 }
48
49
49 Connections {
50 Connections {
50− target: greeter
51+ target: SessionManager
51− onShownChanged: if (shown) resetSearch()
52+ onActiveChanged: if (!SessionManager.active) resetSearch()
52 }
53 }
53
54
54 Flickable {
55 Flickable {
Greeter/Greeter.qml+2−1
@@ -34,7 +34,8 @@ Showable {
34
34
35 property alias dragHandleWidth: dragHandle.width
35 property alias dragHandleWidth: dragHandle.width
36 property alias model: greeterContentLoader.model
36 property alias model: greeterContentLoader.model
37+ property alias promptless: greeterContentLoader.promptless
37− property bool locked: shown && multiUser && !greeterContentLoader.promptless
38+ property bool locked: shown && multiUser && !promptless
38
39
39 readonly property bool narrowMode: !multiUser && width <= units.gu(60)
40 readonly property bool narrowMode: !multiUser && width <= units.gu(60)
40 readonly property bool multiUser: LightDM.Users.count > 1
41 readonly property bool multiUser: LightDM.Users.count > 1
GreeterShell.qmlnew file+170
@@ -0,0 +1,170 @@
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 Ubuntu.Application 0.1
19+import LightDM 0.1 as LightDM
20+import "Greeter"
21+import "Launcher"
22+import "Panel"
23+import "Components"
24+import "Components/Math.js" as MathLocal
25+
26+BasicShell {
27+ id: shell
28+
29+ function activateApplication(desktopFile, argument) {
30+ greeter.login()
31+ // TODO: support opening the app once inside user's session
32+ }
33+
34+ Lockscreen {
35+ id: lockscreen
36+ hides: [launcher, panel.indicators]
37+ shown: false
38+ enabled: true
39+ showAnimation: StandardAnimation { property: "opacity"; to: 1 }
40+ hideAnimation: StandardAnimation { property: "opacity"; to: 0 }
41+ y: panel.panelHeight
42+ x: required ? 0 : - width
43+ width: parent.width
44+ height: parent.height - panel.panelHeight
45+ background: shell.background
46+
47+ onUnlocked: lockscreen.hide()
48+ onCancel: greeter.show()
49+
50+ Component.onCompleted: {
51+ if (LightDM.Users.count == 1) {
52+ LightDM.Greeter.authenticate(LightDM.Users.data(0, LightDM.UserRoles.NameRole))
53+ }
54+ }
55+ }
56+
57+ Connections {
58+ target: LightDM.Greeter
59+
60+ onShowPrompt: {
61+ if (LightDM.Users.count == 1) {
62+ // TODO: There's no better way for now to determine if its a PIN or a passphrase.
63+ if (text == "PIN") {
64+ lockscreen.alphaNumeric = false
65+ } else {
66+ lockscreen.alphaNumeric = true
67+ }
68+ lockscreen.placeholderText = i18n.tr("Please enter %1").arg(text);
69+ lockscreen.show();
70+ }
71+ }
72+ }
73+
74+ Greeter {
75+ id: greeter
76+
77+ available: true
78+ hides: [launcher, panel.indicators]
79+ shown: true
80+
81+ y: panel.panelHeight
82+ width: parent.width
83+ height: parent.height - panel.panelHeight
84+
85+ dragHandleWidth: shell.edgeSize
86+
87+ function login() {
88+ enabled = false;
89+ LightDM.Greeter.startSessionSync();
90+ }
91+
92+ onUnlocked: login()
93+ onShownChanged: {
94+ if (shown) {
95+ lockscreen.reset();
96+ // If there is only one user, we start authenticating with that one here.
97+ // If there are more users, the Greeter will handle that
98+ if (LightDM.Users.count == 1) {
99+ LightDM.Greeter.authenticate(LightDM.Users.data(0, LightDM.UserRoles.NameRole));
100+ }
101+ greeter.forceActiveFocus();
102+ }
103+ else if (promptless)
104+ login();
105+ }
106+ onSelected: {
107+ var bgPath = greeter.model.data(uid, LightDM.UserRoles.BackgroundPathRole)
108+ shell.background = bgPath ? bgPath : default_background
109+ }
110+
111+ onLeftTeaserPressedChanged: {
112+ if (leftTeaserPressed) {
113+ launcher.tease();
114+ }
115+ }
116+ }
117+
118+ InputFilterArea {
119+ anchors.fill: parent
120+ blockInput: true
121+ }
122+
123+ Revealer {
124+ id: greeterRevealer
125+ objectName: "greeterRevealer"
126+
127+ property real animatedProgress: MathLocal.clamp(-dragPosition / closedValue, 0, 1)
128+ target: greeter
129+ width: greeter.width
130+ height: greeter.height
131+ handleSize: shell.edgeSize
132+ orientation: Qt.Horizontal
133+ enabled: !greeter.locked
134+ }
135+
136+ Item {
137+ id: overlay
138+
139+ anchors.fill: parent
140+
141+ Panel {
142+ id: panel
143+ anchors.fill: parent //because this draws indicator menus
144+ indicatorsMenuWidth: parent.width > units.gu(60) ? units.gu(40) : parent.width
145+ indicators {
146+ hides: [launcher]
147+ }
148+ fullscreenMode: false
149+ searchVisible: false
150+ }
151+
152+ Launcher {
153+ id: launcher
154+
155+ anchors.top: parent.top
156+ anchors.bottom: parent.bottom
157+ width: parent.width
158+ dragAreaWidth: shell.edgeSize
159+ available: !greeter.locked
160+ onLauncherApplicationSelected: {
161+ shell.activateApplication(name)
162+ }
163+ onShownChanged: {
164+ if (shown) {
165+ panel.indicators.hide()
166+ }
167+ }
168+ }
169+ }
170+}
Hud/Hud.qml+1−4
@@ -227,10 +227,7 @@ Item {
227 width: parent.width
227 width: parent.width
228
228
229 onYChanged: {
229 onYChanged: {
230− if (greeter.shown) {
231− showAnimation.duration = 0
232− hideAnimation.duration = 0
233− } else if (!showAnimation.running && !hideAnimation.running) {
230+ if (!showAnimation.running && !hideAnimation.running) {
234 if (parent.height > 0) {
231 if (parent.height > 0) {
235 showAnimation.duration = Math.min(showableAnimationDuration * (1 - (parent.height - y) / parent.height), showableAnimationDuration)
232 showAnimation.duration = Math.min(showableAnimationDuration * (1 - (parent.height - y) / parent.height), showableAnimationDuration)
236 hideAnimation.duration = showableAnimationDuration - showAnimation.duration
233 hideAnimation.duration = showableAnimationDuration - showAnimation.duration
Shell.qml+9−152
@@ -18,9 +18,8 @@ import QtQuick 2.0
18import Ubuntu.Application 0.1
18import Ubuntu.Application 0.1
19import Ubuntu.Components 0.1
19import Ubuntu.Components 0.1
20import Ubuntu.Gestures 0.1
20import Ubuntu.Gestures 0.1
21−import LightDM 0.1 as LightDM
21+import SessionManager 0.1
22import "Dash"
22import "Dash"
23−import "Greeter"
24import "Launcher"
23import "Launcher"
25import "Panel"
24import "Panel"
26import "Hud"
25import "Hud"
@@ -31,17 +30,9 @@ import "SideStage"
31import "Notifications"
30import "Notifications"
32import Unity.Notifications 1.0 as NotificationBackend
31import Unity.Notifications 1.0 as NotificationBackend
33
32
34−FocusScope {
33+BasicShell {
35 id: shell
34 id: shell
36
35
37− // this is only here to select the width / height of the window if not running fullscreen
38− property bool tablet: false
39− width: tablet ? units.gu(160) : applicationArguments.hasGeometry() ? applicationArguments.width() : units.gu(40)
40− height: tablet ? units.gu(100) : applicationArguments.hasGeometry() ? applicationArguments.height() : units.gu(71)
41−
42− property real edgeSize: units.gu(2)
43− property url default_background: shell.width >= units.gu(60) ? "graphics/tablet_background.jpg" : "graphics/phone_background.jpg"
44− property url background: default_background
45 readonly property real panelHeight: panel.panelHeight
36 readonly property real panelHeight: panel.panelHeight
46
37
47 property bool dashShown: dash.shown
38 property bool dashShown: dash.shown
@@ -72,9 +63,7 @@ FocusScope {
72 }
63 }
73
64
74 readonly property bool fullscreenMode: {
65 readonly property bool fullscreenMode: {
75− if (greeter.shown || lockscreen.shown) {
76− return false;
77− } else if (mainStage.usingScreenshots) { // Window Manager animating so want to re-evaluate fullscreen mode
66+ if (mainStage.usingScreenshots) { // Window Manager animating so want to re-evaluate fullscreen mode
78 return mainStage.switchingFromFullscreenToFullscreen;
67 return mainStage.switchingFromFullscreenToFullscreen;
79 } else if (applicationManager.mainStageFocusedApplication) {
68 } else if (applicationManager.mainStageFocusedApplication) {
80 return applicationManager.mainStageFocusedApplication.fullscreen;
69 return applicationManager.mainStageFocusedApplication.fullscreen;
@@ -87,9 +76,6 @@ FocusScope {
87 target: applicationManager
76 target: applicationManager
88 ignoreUnknownSignals: true
77 ignoreUnknownSignals: true
89 onFocusRequested: {
78 onFocusRequested: {
90− // TODO: this should be protected to only unlock for certain applications / certain usecases
91− // potentially only in connection with a notification
92− greeter.hide();
93 shell.activateApplication(desktopFile);
79 shell.activateApplication(desktopFile);
94 }
80 }
95 }
81 }
@@ -114,16 +100,9 @@ FocusScope {
114 }
100 }
115 }
101 }
116
102
117− VolumeControl {
118− id: volumeControl
119− }
120−
121− Keys.onVolumeUpPressed: volumeControl.volumeUp()
122− Keys.onVolumeDownPressed: volumeControl.volumeDown()
123−
124 Keys.onReleased: {
103 Keys.onReleased: {
125 if (event.key == Qt.Key_PowerOff) {
104 if (event.key == Qt.Key_PowerOff) {
126− greeter.show()
105+ SessionManager.lock()
127 }
106 }
128 }
107 }
129
108
@@ -162,7 +141,6 @@ FocusScope {
162 id: dash
141 id: dash
163 objectName: "dash"
142 objectName: "dash"
164
143
165− available: !greeter.shown && !lockscreen.shown
166 hides: [stages, launcher, panel.indicators]
144 hides: [stages, launcher, panel.indicators]
167 shown: disappearingAnimationProgress !== 1.0
145 shown: disappearingAnimationProgress !== 1.0
168 enabled: disappearingAnimationProgress === 0.0
146 enabled: disappearingAnimationProgress === 0.0
@@ -180,16 +158,10 @@ FocusScope {
180
158
181 contentScale: 1.0 - 0.2 * disappearingAnimationProgress
159 contentScale: 1.0 - 0.2 * disappearingAnimationProgress
182 opacity: 1.0 - disappearingAnimationProgress
160 opacity: 1.0 - disappearingAnimationProgress
183− property real disappearingAnimationProgress: {
161+ property real disappearingAnimationProgress: stagesOuterContainer.showProgress
184− if (greeter.shown) {
185− return greeter.showProgress;
186− } else {
187− return stagesOuterContainer.showProgress;
188− }
189− }
190
162
191− // FIXME: only necessary because stagesOuterContainer.showProgress and
163+ // FIXME: only necessary because stagesOuterContainer.showProgress
192− // greeterRevealer.animatedProgress are not animated
164+ // is not animated
193 Behavior on disappearingAnimationProgress { SmoothedAnimation { velocity: 5 }}
165 Behavior on disappearingAnimationProgress { SmoothedAnimation { velocity: 5 }}
194 }
166 }
195 }
167 }
@@ -214,7 +186,6 @@ FocusScope {
214
186
215 property bool fullyShown: shown && x == 0 && parent.x == 0
187 property bool fullyShown: shown && x == 0 && parent.x == 0
216 property bool fullyHidden: !shown && x == width
188 property bool fullyHidden: !shown && x == width
217− available: !greeter.shown
218 hides: [launcher, panel.indicators]
189 hides: [launcher, panel.indicators]
219 shown: false
190 shown: false
220 opacity: 1.0
191 opacity: 1.0
@@ -317,7 +288,7 @@ FocusScope {
317 && sideStage[sideStageRevealer.boundProperty] == sideStageRevealer.openedValue
288 && sideStage[sideStageRevealer.boundProperty] == sideStageRevealer.openedValue
318 shouldUseScreenshots: !fullyShown || mainStage.usingScreenshots || sideStageRevealer.pressed
289 shouldUseScreenshots: !fullyShown || mainStage.usingScreenshots || sideStageRevealer.pressed
319
290
320− available: !greeter.shown && !lockscreen.shown && enabled
291+ available: enabled
321 hides: [launcher, panel.indicators]
292 hides: [launcher, panel.indicators]
322 shown: false
293 shown: false
323 showAnimation: StandardAnimation { property: "x"; duration: 350; to: sideStageRevealer.openedValue; easing.type: Easing.OutQuint }
294 showAnimation: StandardAnimation { property: "x"; duration: 350; to: sideStageRevealer.openedValue; easing.type: Easing.OutQuint }
@@ -367,106 +338,6 @@ FocusScope {
367 }
338 }
368 }
339 }
369
340
370− Lockscreen {
371− id: lockscreen
372− hides: [launcher, panel.indicators, hud]
373− shown: false
374− enabled: true
375− showAnimation: StandardAnimation { property: "opacity"; to: 1 }
376− hideAnimation: StandardAnimation { property: "opacity"; to: 0 }
377− y: panel.panelHeight
378− x: required ? 0 : - width
379− width: parent.width
380− height: parent.height - panel.panelHeight
381− background: shell.background
382−
383− onUnlocked: lockscreen.hide()
384− onCancel: greeter.show()
385−
386− Component.onCompleted: {
387− if (LightDM.Users.count == 1) {
388− LightDM.Greeter.authenticate(LightDM.Users.data(0, LightDM.UserRoles.NameRole))
389− }
390− }
391− }
392−
393− Connections {
394− target: LightDM.Greeter
395−
396− onShowPrompt: {
397− if (LightDM.Users.count == 1) {
398− // TODO: There's no better way for now to determine if its a PIN or a passphrase.
399− if (text == "PIN") {
400− lockscreen.alphaNumeric = false
401− } else {
402− lockscreen.alphaNumeric = true
403− }
404− lockscreen.placeholderText = i18n.tr("Please enter %1").arg(text);
405− lockscreen.show();
406− }
407− }
408− }
409−
410− Greeter {
411− id: greeter
412−
413− available: true
414− hides: [launcher, panel.indicators, hud]
415− shown: true
416−
417− y: panel.panelHeight
418− width: parent.width
419− height: parent.height - panel.panelHeight
420−
421− dragHandleWidth: shell.edgeSize
422−
423− property var previousMainApp: null
424− property var previousSideApp: null
425−
426− onShownChanged: {
427− if (shown) {
428− lockscreen.reset();
429− // If there is only one user, we start authenticating with that one here.
430− // If there are more users, the Greeter will handle that
431− if (LightDM.Users.count == 1) {
432− LightDM.Greeter.authenticate(LightDM.Users.data(0, LightDM.UserRoles.NameRole));
433− }
434− greeter.forceActiveFocus();
435− // FIXME: *FocusedApplication are not updated when unfocused, hence the need to check whether
436− // the stage was actually shown
437− if (mainStage.fullyShown) greeter.previousMainApp = applicationManager.mainStageFocusedApplication;
438− if (sideStage.fullyShown) greeter.previousSideApp = applicationManager.sideStageFocusedApplication;
439− applicationManager.unfocusCurrentApplication();
440− } else {
441− if (greeter.previousMainApp) {
442− applicationManager.focusApplication(greeter.previousMainApp);
443− greeter.previousMainApp = null;
444− }
445− if (greeter.previousSideApp) {
446− applicationManager.focusApplication(greeter.previousSideApp);
447− greeter.previousSideApp = null;
448− }
449− }
450− }
451−
452− onUnlocked: greeter.hide()
453− onSelected: {
454− var bgPath = greeter.model.data(uid, LightDM.UserRoles.BackgroundPathRole)
455− shell.background = bgPath ? bgPath : default_background
456− }
457−
458− onLeftTeaserPressedChanged: {
459− if (leftTeaserPressed) {
460− launcher.tease();
461− }
462− }
463− }
464−
465− InputFilterArea {
466− anchors.fill: parent
467− blockInput: greeter.shown || lockscreen.shown
468− }
469−
470 Item {
341 Item {
471 id: overlay
342 id: overlay
472
343
@@ -480,7 +351,6 @@ FocusScope {
480 hides: [launcher]
351 hides: [launcher]
481 }
352 }
482 fullscreenMode: shell.fullscreenMode
353 fullscreenMode: shell.fullscreenMode
483− searchVisible: !greeter.shown && !lockscreen.shown
484
354
485 InputFilterArea {
355 InputFilterArea {
486 anchors.fill: parent
356 anchors.fill: parent
@@ -494,7 +364,7 @@ FocusScope {
494 width: parent.width > units.gu(60) ? units.gu(40) : parent.width
364 width: parent.width > units.gu(60) ? units.gu(40) : parent.width
495 height: parent.height
365 height: parent.height
496
366
497− available: !greeter.shown && !panel.indicators.shown && !lockscreen.shown
367+ available: !panel.indicators.shown
498 shown: false
368 shown: false
499 showAnimation: StandardAnimation { property: "y"; duration: hud.showableAnimationDuration; to: 0; easing.type: Easing.Linear }
369 showAnimation: StandardAnimation { property: "y"; duration: hud.showableAnimationDuration; to: 0; easing.type: Easing.Linear }
500 hideAnimation: StandardAnimation { property: "y"; duration: hud.showableAnimationDuration; to: hudRevealer.closedValue; easing.type: Easing.Linear }
370 hideAnimation: StandardAnimation { property: "y"; duration: hud.showableAnimationDuration; to: hudRevealer.closedValue; easing.type: Easing.Linear }
@@ -552,9 +422,7 @@ FocusScope {
552 anchors.bottom: parent.bottom
422 anchors.bottom: parent.bottom
553 width: parent.width
423 width: parent.width
554 dragAreaWidth: shell.edgeSize
424 dragAreaWidth: shell.edgeSize
555− available: !greeter.locked
556 onDashItemSelected: {
425 onDashItemSelected: {
557− greeter.hide()
558 // Animate if moving between application and dash
426 // Animate if moving between application and dash
559 if (!stages.shown) {
427 if (!stages.shown) {
560 dash.setCurrentScope("home.scope", true, false)
428 dash.setCurrentScope("home.scope", true, false)
@@ -571,7 +439,6 @@ FocusScope {
571 }
439 }
572 }
440 }
573 onLauncherApplicationSelected:{
441 onLauncherApplicationSelected:{
574− greeter.hide()
575 shell.activateApplication(desktopFile)
442 shell.activateApplication(desktopFile)
576 }
443 }
577 onShownChanged: {
444 onShownChanged: {
@@ -622,16 +489,6 @@ FocusScope {
622 blockInput: true
489 blockInput: true
623 }
490 }
624
491
625− InputFilterArea {
626− anchors {
627− top: parent.top
628− bottom: parent.bottom
629− right: parent.right
630− }
631− width: shell.edgeSize
632− blockInput: true
633− }
634−
635 Binding {
492 Binding {
636 target: i18n
493 target: i18n
637 property: "domain"
494 property: "domain"
debian/control+13
@@ -3,6 +3,7 @@ Section: x11
3Priority: optional
3Priority: optional
4Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
4Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
5Build-Depends: cmake,
5Build-Depends: cmake,
6+ dbus-test-runner,
6 debhelper (>= 9),
7 debhelper (>= 9),
7 libdee-qt5-dev (>= 3.0),
8 libdee-qt5-dev (>= 3.0),
8 libgl1-mesa-dev[!armhf] | libgl-dev[!armhf],
9 libgl1-mesa-dev[!armhf] | libgl-dev[!armhf],
@@ -12,6 +13,7 @@ Build-Depends: cmake,
12 libjson-perl,
13 libjson-perl,
13 libnm-glib-dev,
14 libnm-glib-dev,
14 libnm-util-dev,
15 libnm-util-dev,
16+ liblightdm-qt5-3-dev,
15 libpulse-dev,
17 libpulse-dev,
16 libqmenumodel-dev,
18 libqmenumodel-dev,
17 libqt5v8-5-private-dev,
19 libqt5v8-5-private-dev,
@@ -27,6 +29,7 @@ Build-Depends: cmake,
27 python3,
29 python3,
28 qt5-default,
30 qt5-default,
29 qtbase5-dev,
31 qtbase5-dev,
32+ qtbase5-dev-tools,
30 qtbase5-private-dev,
33 qtbase5-private-dev,
31 qtdeclarative5-dev,
34 qtdeclarative5-dev,
32 qtdeclarative5-dev-tools,
35 qtdeclarative5-dev-tools,
@@ -75,6 +78,15 @@ Recommends: indicator-battery,
75Description: Unity 8 shell
78Description: Unity 8 shell
76 The Unity 8 shell is the primary user interface for Ubuntu devices.
79 The Unity 8 shell is the primary user interface for Ubuntu devices.
77
80
81+Package: unity8-greeter
82+Architecture: any
83+Depends: ubuntu-touch-session,
84+ unity8 (>= ${source:Version}),
85+ ${misc:Depends},
86+ ${shlibs:Depends},
87+Description: Ubuntu QML greeter
88+ The Ubuntu QML greeter is the primary greeter for Ubuntu devices.
89+
78Package: unity8-autopilot
90Package: unity8-autopilot
79Architecture: all
91Architecture: all
80Depends: indicators-client (>= ${source:Version}),
92Depends: indicators-client (>= ${source:Version}),
@@ -84,6 +96,7 @@ Depends: indicators-client (>= ${source:Version}),
84 python-evdev,
96 python-evdev,
85 unity8 (>= ${source:Version}),
97 unity8 (>= ${source:Version}),
86 unity8-fake-env (>= ${source:Version}),
98 unity8-fake-env (>= ${source:Version}),
99+ unity8-greeter (>= ${source:Version}),
87 ${misc:Depends},
100 ${misc:Depends},
88 ${python:Depends},
101 ${python:Depends},
89 ${shlibs:Depends},
102 ${shlibs:Depends},
debian/copyright+1−1
@@ -22,7 +22,7 @@ License: GPL-3
22 On Debian systems, the full text of the GNU General Public License
22 On Debian systems, the full text of the GNU General Public License
23 version 3 can be found in the file /usr/share/common-licenses/GPL-3.
23 version 3 can be found in the file /usr/share/common-licenses/GPL-3.
24
24
25−Files: tests/mocks/LightDM/UsersModel.h tests/mocks/LightDM/Greeter.h
25+Files: tests/mocks/liblightdm/UsersModel.h tests/mocks/liblightdm/Greeter.h
26Copyright: 2013 Canonical Ltd.
26Copyright: 2013 Canonical Ltd.
27 2010-2011 David Edmundson
27 2010-2011 David Edmundson
28 2010-2011 Robert Ancell
28 2010-2011 Robert Ancell
debian/rules+2−5
@@ -8,7 +8,8 @@ export NO_PNG_PKG_MANGLE=1
8
8
9SCOPES_RECOMMENDS := $(shell perl debian/scopes-recommends-generator /usr/share/unity/client-scopes.json)
9SCOPES_RECOMMENDS := $(shell perl debian/scopes-recommends-generator /usr/share/unity/client-scopes.json)
10
10
11+.PHONY: build
11−%:
12+build %:
12 dh $@ --parallel --fail-missing --with python2
13 dh $@ --parallel --fail-missing --with python2
13
14
14override_dh_auto_clean:
15override_dh_auto_clean:
@@ -28,9 +29,5 @@ override_dh_install:
28override_dh_makeshlibs:
29override_dh_makeshlibs:
29 dh_makeshlibs -Nunity8-private -Nunity8-fake-env
30 dh_makeshlibs -Nunity8-private -Nunity8-fake-env
30
31
31−# libMockLightDM-qml.so links against liblightdm-qt5-2.so which doesn't exist
32−override_dh_shlibdeps:
33− dh_shlibdeps -XlibMockLightDM-qml.so
34−
35override_dh_gencontrol:
32override_dh_gencontrol:
36 dh_gencontrol -- -Vunity-default-masterscopes="$(SCOPES_RECOMMENDS)"
33 dh_gencontrol -- -Vunity-default-masterscopes="$(SCOPES_RECOMMENDS)"
debian/unity8-greeter.installnew file+4
@@ -0,0 +1,4 @@
1+usr/bin/unity8-greeter
2+usr/share/xgreeters/unity8-greeter.desktop
3+usr/share/unity8/GreeterShell.qml
4+usr/share/unity8/Greeter
debian/unity8-greeter.postinstnew file+12
@@ -0,0 +1,12 @@
1+#!/bin/sh
2+set -e
3+
4+case "$1" in
5+configure|upgrade|reconfigure)
6+ if [ -x /usr/lib/lightdm/lightdm-set-defaults ] ; then
7+ /usr/lib/lightdm/lightdm-set-defaults --keep-old --greeter=unity8-greeter --session=ubuntu-touch || true
8+ fi
9+ ;;
10+esac
11+
12+#DEBHELPER#
debian/unity8-greeter.prermnew file+12
@@ -0,0 +1,12 @@
1+#!/bin/sh
2+set -e
3+
4+case "$1" in
5+remove|purge)
6+ if [ -x /usr/lib/lightdm/lightdm-set-defaults ] ; then
7+ /usr/lib/lightdm/lightdm-set-defaults --remove --greeter=unity8-greeter --session=ubuntu-touch || true
8+ fi
9+ ;;
10+esac
11+
12+#DEBHELPER#
debian/unity8-private.install+1
@@ -1,6 +1,7 @@
1usr/lib/*/unity8/qml/HudClient
1usr/lib/*/unity8/qml/HudClient
2usr/lib/*/unity8/qml/LightDM
2usr/lib/*/unity8/qml/LightDM
3usr/lib/*/unity8/qml/ListViewWithPageHeader
3usr/lib/*/unity8/qml/ListViewWithPageHeader
4+usr/lib/*/unity8/qml/SessionManager
4usr/lib/*/unity8/qml/Ubuntu
5usr/lib/*/unity8/qml/Ubuntu
5usr/lib/*/unity8/qml/Unity
6usr/lib/*/unity8/qml/Unity
6usr/lib/*/unity8/qml/Utils
7usr/lib/*/unity8/qml/Utils
debian/unity8.install−1
@@ -5,7 +5,6 @@ usr/share/unity8/Applications
5usr/share/unity8/Bottombar
5usr/share/unity8/Bottombar
6usr/share/unity8/Components
6usr/share/unity8/Components
7usr/share/unity8/Dash
7usr/share/unity8/Dash
8−usr/share/unity8/Greeter
9usr/share/unity8/Hud
8usr/share/unity8/Hud
10usr/share/unity8/Launcher
9usr/share/unity8/Launcher
11usr/share/unity8/Notifications
10usr/share/unity8/Notifications
main.cpp+8−3
@@ -22,6 +22,7 @@
22#include <QtQuick/QQuickView>
22#include <QtQuick/QQuickView>
23#include <QtGui/QIcon>
23#include <QtGui/QIcon>
24#include <QtGui/QGuiApplication>
24#include <QtGui/QGuiApplication>
25+#include <QtGui/QScreen>
25#include <QtQml/QQmlEngine>
26#include <QtQml/QQmlEngine>
26#include <QtQml/QQmlContext>
27#include <QtQml/QQmlContext>
27#include <qpa/qplatformnativeinterface.h>
28#include <qpa/qplatformnativeinterface.h>
@@ -82,7 +83,7 @@ int main(int argc, char** argv)
82 setenv("QML_FORCE_THREADED_RENDERER", "1", 1);
83 setenv("QML_FORCE_THREADED_RENDERER", "1", 1);
83 setenv("QML_FIXED_ANIMATION_STEP", "1", 1);
84 setenv("QML_FIXED_ANIMATION_STEP", "1", 1);
84
85
85− QGuiApplication::setApplicationName("Unity 8");
86+ QGuiApplication::setApplicationName(APP_NAME);
86 QGuiApplication application(argc, argv);
87 QGuiApplication application(argc, argv);
87
88
88 resolveIconTheme();
89 resolveIconTheme();
@@ -111,7 +112,7 @@ int main(int argc, char** argv)
111
112
112 QQuickView* view = new QQuickView();
113 QQuickView* view = new QQuickView();
113 view->setResizeMode(QQuickView::SizeRootObjectToView);
114 view->setResizeMode(QQuickView::SizeRootObjectToView);
114− view->setTitle("Qml Phone Shell");
115+ view->setTitle(APP_NAME);
115 view->engine()->setBaseUrl(QUrl::fromLocalFile(::shellAppDirectory()));
116 view->engine()->setBaseUrl(QUrl::fromLocalFile(::shellAppDirectory()));
116 view->rootContext()->setContextProperty("applicationArguments", &qmlArgs);
117 view->rootContext()->setContextProperty("applicationArguments", &qmlArgs);
117 if (args.contains(QLatin1String("-frameless"))) {
118 if (args.contains(QLatin1String("-frameless"))) {
@@ -136,13 +137,17 @@ int main(int argc, char** argv)
136 nativeInterface->setProperty("ubuntuSessionType", 1);
137 nativeInterface->setProperty("ubuntuSessionType", 1);
137 view->setProperty("role", 2); // INDICATOR_ACTOR_ROLE
138 view->setProperty("role", 2); // INDICATOR_ACTOR_ROLE
138
139
139− QUrl source("Shell.qml");
140+ QUrl source(QML_FILE);
140 prependImportPaths(view->engine(), ::overrideImportPaths());
141 prependImportPaths(view->engine(), ::overrideImportPaths());
141 appendImportPaths(view->engine(), ::fallbackImportPaths());
142 appendImportPaths(view->engine(), ::fallbackImportPaths());
142 view->setSource(source);
143 view->setSource(source);
143 view->setColor("transparent");
144 view->setColor("transparent");
144
145
145 if (qgetenv("QT_QPA_PLATFORM") == "ubuntu" || args.contains(QLatin1String("-fullscreen"))) {
146 if (qgetenv("QT_QPA_PLATFORM") == "ubuntu" || args.contains(QLatin1String("-fullscreen"))) {
147+ // First, size window equal to screen (fake a real WM fullscreen mode).
148+ // Then, in case we are actually running inside a windowing system,
149+ // nicely set actual WM fullscreen hint for its benefit.
150+ view->resize(view->screen()->size());
146 view->showFullScreen();
151 view->showFullScreen();
147 } else {
152 } else {
148 view->show();
153 view->show();
plugins/CMakeLists.txt+1
@@ -4,3 +4,4 @@ add_subdirectory(Unity)
4add_subdirectory(HudClient)
4add_subdirectory(HudClient)
5add_subdirectory(LightDM)
5add_subdirectory(LightDM)
6add_subdirectory(ListViewWithPageHeader)
6add_subdirectory(ListViewWithPageHeader)
7+add_subdirectory(SessionManager)
plugins/LightDM/CMakeLists.txt+5−9
@@ -3,20 +3,18 @@ include(Plugins)
3
3
4# Dependencies
4# Dependencies
5include(FindPkgConfig)
5include(FindPkgConfig)
6+pkg_check_modules(LIBLIGHTDM REQUIRED liblightdm-qt5-3)
6pkg_check_modules(LIBUSERMETRICSOUTPUT REQUIRED libusermetricsoutput-1)
7pkg_check_modules(LIBUSERMETRICSOUTPUT REQUIRED libusermetricsoutput-1)
7−# TODO: Once we split out a separate greeter process, uncomment these lines
8−#pkg_check_modules(LIBLIGHTDM REQUIRED liblightdm-qt5-2)
9
8
10include_directories(
9include_directories(
11 ${CMAKE_CURRENT_SOURCE_DIR}
10 ${CMAKE_CURRENT_SOURCE_DIR}
12 ${CMAKE_CURRENT_BINARY_DIR}
11 ${CMAKE_CURRENT_BINARY_DIR}
13− ${CMAKE_SOURCE_DIR}/tests/mocks/LightDM
14− #${LIBLIGHTDM_INCLUDE_DIRS}
12+ ${LIBLIGHTDM_INCLUDE_DIRS}
15 ${LIBUSERMETRICSOUTPUT_INCLUDE_DIRS}
13 ${LIBUSERMETRICSOUTPUT_INCLUDE_DIRS}
16)
14)
17
15
18set(QMLPLUGIN_SRC
16set(QMLPLUGIN_SRC
19− ../Utils/qsortfilterproxymodelqml.cpp # FIXME evaluate a more generic approach for using other plugins
17+ ${CMAKE_SOURCE_DIR}/plugins/Utils/qsortfilterproxymodelqml.cpp # FIXME evaluate a more generic approach for using other plugins
20 Greeter.cpp
18 Greeter.cpp
21 plugin.cpp
19 plugin.cpp
22 UsersModel.cpp
20 UsersModel.cpp
@@ -27,13 +25,11 @@ add_library(LightDM-qml MODULE
27 )
25 )
28
26
29target_link_libraries(LightDM-qml
27target_link_libraries(LightDM-qml
30− MockLightDM-demo
31−# TODO: Once we split out a separate greeter process, uncomment these lines
32−# ${LIBLIGHTDM_LDFLAGS}
28+ ${LIBLIGHTDM_LDFLAGS}
33 ${LIBUSERMETRICSOUTPUT_LDFLAGS}
29 ${LIBUSERMETRICSOUTPUT_LDFLAGS}
34 )
30 )
35
31
36−qt5_use_modules(LightDM-qml Gui Qml)
32+qt5_use_modules(LightDM-qml Qml)
37
33
38# export the qmldir qmltypes and plugin files
34# export the qmldir qmltypes and plugin files
39export_qmlfiles(LightDM LightDM)
35export_qmlfiles(LightDM LightDM)
plugins/SessionManager/CMakeLists.txtnew file+27
@@ -0,0 +1,27 @@
1+# export_qmlplugin macro
2+include(Plugins)
3+
4+set(QMLPLUGIN_SRC
5+ plugin.cpp
6+ SessionManager.cpp
7+ )
8+
9+include_directories(
10+ ${Qt5DBus_INCLUDE_DIRS}
11+ )
12+
13+add_definitions(-DSM_BUSNAME=systemBus)
14+
15+add_library(SessionManager-qml MODULE
16+ ${QMLPLUGIN_SRC}
17+ )
18+
19+target_link_libraries(SessionManager-qml
20+ ${Qt5DBus_LIBRARIES}
21+ )
22+
23+qt5_use_modules(SessionManager-qml Qml)
24+
25+# export the qmldir qmltypes and plugin files
26+export_qmlfiles(SessionManager SessionManager)
27+export_qmlplugin(SessionManager 0.1 SessionManager TARGETS SessionManager-qml)
plugins/SessionManager/SessionManager.cppnew file+105
@@ -0,0 +1,105 @@
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+ * Author: Michael Terry <michael.terry@canonical.com>
17+ */
18+
19+#include "SessionManager.h"
20+#include <QtCore/QEvent>
21+#include <QtDBus/QDBusPendingReply>
22+
23+SessionManager::SessionManager(QObject* parent)
24+ : QObject(parent),
25+ l1_manager(NULL),
26+ l1_session(NULL),
27+ ldm_session(NULL),
28+ is_active(true) // assume we're active w/o logind
29+{
30+ l1_manager = new QDBusInterface("org.freedesktop.login1",
31+ "/org/freedesktop/login1",
32+ "org.freedesktop.login1.Manager",
33+ QDBusConnection::SM_BUSNAME(), this);
34+ if (l1_manager->isValid()) {
35+ QDBusPendingCall pcall = l1_manager->asyncCall("GetSession", QString(qgetenv("XDG_SESSION_ID")));
36+ QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pcall, this);
37+ QObject::connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
38+ this, SLOT(getSessionSlot(QDBusPendingCallWatcher*)));
39+ }
40+
41+ ldm_session = new QDBusInterface("org.freedesktop.DisplayManager",
42+ QString(qgetenv("XDG_SESSION_PATH")),
43+ "org.freedesktop.DisplayManager.Session",
44+ QDBusConnection::SM_BUSNAME(), this);
45+}
46+
47+bool SessionManager::active() const
48+{
49+ // We cache this value for performance reasons, as QDBusInterface does not
50+ // cache for us.
51+ return is_active;
52+}
53+
54+void SessionManager::lock()
55+{
56+ // We use ldm_session to handle locking rather than l1_session, because
57+ // l1_session doesn't have permissions to lock from the user session, but
58+ // ldm_session does. This is what the rest of Ubuntu uses to lock.
59+ if (ldm_session != NULL && ldm_session->isValid())
60+ ldm_session->asyncCall("Lock");
61+}
62+
63+void SessionManager::getSessionSlot(QDBusPendingCallWatcher *watcher)
64+{
65+ QDBusPendingReply<QDBusObjectPath> reply = *watcher;
66+ if (!reply.isError()) {
67+ QDBusObjectPath path = reply.argumentAt<0>();
68+ l1_session = new QDBusInterface("org.freedesktop.login1",
69+ path.path(),
70+ "org.freedesktop.login1.Session",
71+ l1_manager->connection(), this);
72+
73+ l1_manager->connection().connect("org.freedesktop.login1",
74+ path.path(),
75+ "org.freedesktop.DBus.Properties",
76+ "PropertiesChanged",
77+ this,
78+ SLOT(propertiesChanged(QString, QVariantMap, QStringList)));
79+
80+ propertiesChanged("", QVariantMap(), QStringList() << "Active");
81+ }
82+ watcher->deleteLater();
83+}
84+
85+void SessionManager::propertiesChanged(const QString &interface, const QVariantMap &changed, const QStringList &invalid)
86+{
87+ Q_UNUSED(interface)
88+
89+ QVariant value = changed.value("Active");
90+
91+ // If Active isn't in changed, check if we were at least notified about it
92+ // changing on the server. Also check if IdleHint was modified, because
93+ // sometimes logind does not emit a changed signal for Active becoming
94+ // false, but will emit for IdleHint when that does happen.
95+ if (!value.isValid() && (invalid.contains("Active") || invalid.contains("IdleHint") || changed.contains("IdleHint")) && l1_session->isValid()) {
96+ value = l1_session->property("Active");
97+ if (!value.isValid())
98+ value = QVariant(false);
99+ }
100+
101+ if (value.isValid() && value.toBool() != is_active) {
102+ is_active = value.toBool();
103+ Q_EMIT activeChanged();
104+ }
105+}
plugins/SessionManager/SessionManager.hnew file+58
@@ -0,0 +1,58 @@
1+/*
2+ * Copyright (C) 2012,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+ * Authors: Gerry Boland <gerry.boland@canonical.com>
17+ * Michael Terry <michael.terry@canonical.com>
18+ */
19+
20+#ifndef UNITY_SESSIONMANAGER_H
21+#define UNITY_SESSIONMANAGER_H
22+
23+#include <QtCore/QObject>
24+#include <QtCore/QString>
25+#include <QtCore/QStringList>
26+#include <QtCore/QVariantMap>
27+#include <QtDBus/QDBusInterface>
28+#include <QtDBus/QDBusPendingCallWatcher>
29+
30+class SessionManager: public QObject
31+{
32+ Q_OBJECT
33+
34+ Q_PROPERTY(bool active READ active NOTIFY activeChanged FINAL)
35+
36+public:
37+ explicit SessionManager(QObject *parent = 0);
38+
39+ bool active() const;
40+
41+public Q_SLOTS:
42+ void lock();
43+
44+Q_SIGNALS:
45+ void activeChanged();
46+
47+private Q_SLOTS:
48+ void getSessionSlot(QDBusPendingCallWatcher *watcher);
49+ void propertiesChanged(const QString &interface, const QVariantMap &changed, const QStringList &invalid);
50+
51+private:
52+ QDBusInterface *l1_manager;
53+ QDBusInterface *l1_session;
54+ QDBusInterface *ldm_session;
55+ bool is_active;
56+};
57+
58+#endif
plugins/SessionManager/plugin.cppnew file+35
@@ -0,0 +1,35 @@
1+/*
2+ * Copyright (C) 2012,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+ * Authors: Gerry Boland <gerry.boland@canonical.com>
17+ * Michael Terry <michael.terry@canonical.com>
18+ */
19+
20+#include "plugin.h"
21+#include "SessionManager.h"
22+#include <QtQml>
23+
24+static QObject *sessionmanager_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
25+{
26+ Q_UNUSED(engine)
27+ Q_UNUSED(scriptEngine)
28+ return new SessionManager();
29+}
30+
31+void SessionManagerPlugin::registerTypes(const char *uri)
32+{
33+ Q_ASSERT(uri == QLatin1String("SessionManager"));
34+ qmlRegisterSingletonType<SessionManager>(uri, 0, 1, "SessionManager", sessionmanager_provider);
35+}
plugins/SessionManager/plugin.hnew file+35
@@ -0,0 +1,35 @@
1+/*
2+ * Copyright (C) 2012,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+ * Authors: Gerry Boland <gerry.boland@canonical.com>
17+ * Michael Terry <michael.terry@canonical.com>
18+ */
19+
20+#ifndef SESSIONMANAGER_PLUGIN_H
21+#define SESSIONMANAGER_PLUGIN_H
22+
23+#include <QtQml/QQmlEngine>
24+#include <QtQml/QQmlExtensionPlugin>
25+
26+class SessionManagerPlugin : public QQmlExtensionPlugin
27+{
28+ Q_OBJECT
29+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
30+
31+public:
32+ void registerTypes(const char *uri);
33+};
34+
35+#endif
plugins/SessionManager/qmldirnew file+2
@@ -0,0 +1,2 @@
1+module SessionManager
2+plugin SessionManager-qml
run+6−4
@@ -15,13 +15,14 @@ usage() {
15 echo " -p, --pinlock Use a pin protected user." >&2
15 echo " -p, --pinlock Use a pin protected user." >&2
16 echo " -k, --keylock Use a passphrase protected user." >&2
16 echo " -k, --keylock Use a passphrase protected user." >&2
17 echo " -g, --gdb Run through gdb." >&2
17 echo " -g, --gdb Run through gdb." >&2
18+ echo " -G, --greeter Run the greeter instead of the shell." >&2
18 echo " -h, --help Show this help." >&2
19 echo " -h, --help Show this help." >&2
19 echo " -m, --nomousetouch Run without -mousetouch argument." >&2
20 echo " -m, --nomousetouch Run without -mousetouch argument." >&2
20 echo >&2
21 echo >&2
21 exit 1
22 exit 1
22}
23}
23
24
24−ARGS=`getopt -n$0 -u -a --longoptions="fake,pinlock,keylock,gdb,help,nomousetouch" -o "fpkghm" -- "$@"`
25+ARGS=`getopt -n$0 -u -a --longoptions="fake,pinlock,keylock,gdb,greeter,help,nomousetouch" -o "fpkgGhm" -- "$@"`
25[ $? -ne 0 ] && usage
26[ $? -ne 0 ] && usage
26eval set -- "$ARGS"
27eval set -- "$ARGS"
27
28
@@ -32,6 +33,7 @@ do
32 -p|--pinlock) PINLOCK=true;;
33 -p|--pinlock) PINLOCK=true;;
33 -k|--keylock) KEYLOCK=true;;
34 -k|--keylock) KEYLOCK=true;;
34 -g|--gdb) GDB=true;;
35 -g|--gdb) GDB=true;;
36+ -G|--greeter) QML_PHONE_SHELL_PATH=./builddir/unity8-greeter;;
35 -h|--help) usage;;
37 -h|--help) usage;;
36 -m|--nomousetouch) MOUSE_TOUCH=false;;
38 -m|--nomousetouch) MOUSE_TOUCH=false;;
37 --) shift;break;;
39 --) shift;break;;
@@ -41,17 +43,17 @@ done
41
43
42if $FAKE; then
44if $FAKE; then
43 export QML2_IMPORT_PATH=$PWD/builddir/tests/mocks:$PWD/builddir/plugins:$PWD/builddir/modules
45 export QML2_IMPORT_PATH=$PWD/builddir/tests/mocks:$PWD/builddir/plugins:$PWD/builddir/modules
44− export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PWD/builddir/tests/mocks/libusermetrics:$PWD/builddir/tests/mocks/LightDM/single
46+ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PWD/builddir/tests/mocks/libusermetrics:$PWD/builddir/tests/mocks/liblightdm/single
45fi
47fi
46
48
47if $PINLOCK; then
49if $PINLOCK; then
48 export QML2_IMPORT_PATH=$PWD/builddir/tests/mocks:$PWD/builddir/plugins:$PWD/builddir/modules
50 export QML2_IMPORT_PATH=$PWD/builddir/tests/mocks:$PWD/builddir/plugins:$PWD/builddir/modules
49− export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PWD/builddir/tests/mocks/libusermetrics:$PWD/builddir/tests/mocks/LightDM/single-pin
51+ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PWD/builddir/tests/mocks/libusermetrics:$PWD/builddir/tests/mocks/liblightdm/single-pin
50fi
52fi
51
53
52if $KEYLOCK; then
54if $KEYLOCK; then
53 export QML2_IMPORT_PATH=$PWD/builddir/tests/mocks:$PWD/builddir/plugins:$PWD/builddir/modules
55 export QML2_IMPORT_PATH=$PWD/builddir/tests/mocks:$PWD/builddir/plugins:$PWD/builddir/modules
54− export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PWD/builddir/tests/mocks/libusermetrics:$PWD/builddir/tests/mocks/LightDM/single-passphrase
56+ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PWD/builddir/tests/mocks/libusermetrics:$PWD/builddir/tests/mocks/liblightdm/single-passphrase
55fi
57fi
56
58
57# Force icon theme if running on the desktop, otherwise gnome theme (if running
59# Force icon theme if running on the desktop, otherwise gnome theme (if running
tests/autopilot/unity8/shell/tests/__init__.py+22−5
@@ -41,6 +41,7 @@ from unity8 import (
41)
41)
42from unity8.shell.emulators import UnityEmulatorBase
42from unity8.shell.emulators import UnityEmulatorBase
43from unity8.shell.emulators.dash import Dash
43from unity8.shell.emulators.dash import Dash
44+from unity8.shell.emulators.greeter import Greeter
44from unity8.shell.emulators.main_window import MainWindow
45from unity8.shell.emulators.main_window import MainWindow
45
46
46
47
@@ -148,9 +149,8 @@ class UnityTestCase(AutopilotTestCase):
148 divisor = divisor * 2
149 divisor = divisor * 2
149 return divisor
150 return divisor
150
151
151− def launch_unity(self):
152+ def _launch(self, executable, ready_func):
152− """Launch the unity shell, return a proxy object for it."""
153− binary_path = get_binary_path()
153+ binary_path = get_binary_path(executable)
154 lib_path = get_lib_path()
154 lib_path = get_lib_path()
155
155
156 logger.info(
156 logger.info(
@@ -173,11 +173,19 @@ class UnityTestCase(AutopilotTestCase):
173
173
174 # Ensure that the dash is visible before we return:
174 # Ensure that the dash is visible before we return:
175 logger.debug("Unity started, waiting for it to be ready.")
175 logger.debug("Unity started, waiting for it to be ready.")
176− self.assertUnityReady()
176+ ready_func()
177 logger.debug("Unity loaded and ready.")
177 logger.debug("Unity loaded and ready.")
178
178
179 return app_proxy
179 return app_proxy
180
180
181+ def launch_unity(self):
182+ """Launch the unity shell, return a proxy object for it."""
183+ return self._launch("unity8", self.assertUnityReady)
184+
185+ def launch_greeter(self):
186+ """Launch the unity shell, return a proxy object for it."""
187+ return self._launch("unity8-greeter", self.assertGreeterReady)
188+
181 def patch_lightdm_mock(self, mock_type='single'):
189 def patch_lightdm_mock(self, mock_type='single'):
182 self._lightdm_mock_type = mock_type
190 self._lightdm_mock_type = mock_type
183 logger.info("Setting up LightDM mock type '%s'", mock_type)
191 logger.info("Setting up LightDM mock type '%s'", mock_type)
@@ -192,7 +200,7 @@ class UnityTestCase(AutopilotTestCase):
192 def _get_lightdm_mock_path(self, mock_type):
200 def _get_lightdm_mock_path(self, mock_type):
193 lib_path = get_mocks_library_path()
201 lib_path = get_mocks_library_path()
194 lightdm_mock_path = os.path.abspath(
202 lightdm_mock_path = os.path.abspath(
195− os.path.join(lib_path, "LightDM", mock_type)
203+ os.path.join(lib_path, "liblightdm", mock_type)
196 )
204 )
197
205
198 if not os.path.exists(lightdm_mock_path):
206 if not os.path.exists(lightdm_mock_path):
@@ -229,11 +237,20 @@ class UnityTestCase(AutopilotTestCase):
229 )
237 )
230 self.assertThat(home_scope.isCurrent, Eventually(Equals(True)))
238 self.assertThat(home_scope.isCurrent, Eventually(Equals(True)))
231
239
240+ def assertGreeterReady(self):
241+ greeter = self.get_greeter()
242+ self.assertThat(greeter.created, Eventually(Equals(True)))
243+
232 def get_dash(self):
244 def get_dash(self):
233 dash = self._proxy.select_single(Dash)
245 dash = self._proxy.select_single(Dash)
234 self.assertThat(dash, NotEquals(None))
246 self.assertThat(dash, NotEquals(None))
235 return dash
247 return dash
236
248
249+ def get_greeter(self):
250+ greeter = self._proxy.select_single(Greeter)
251+ self.assertThat(greeter, NotEquals(None))
252+ return greeter
253+
237 @property
254 @property
238 def main_window(self):
255 def main_window(self):
239 return MainWindow(self._proxy)
256 return MainWindow(self._proxy)
tests/autopilot/unity8/shell/tests/test_hud.py−6
@@ -19,7 +19,6 @@
19
19
20from __future__ import absolute_import
20from __future__ import absolute_import
21
21
22−from unity8.shell import with_lightdm_mock
23from unity8.shell.tests import UnityTestCase, _get_device_emulation_scenarios
22from unity8.shell.tests import UnityTestCase, _get_device_emulation_scenarios
24
23
25from testtools.matchers import Equals
24from testtools.matchers import Equals
@@ -37,7 +36,6 @@ class TestHud(UnityTestCase):
37
36
38 """
37 """
39 self.launch_unity()
38 self.launch_unity()
40− self.main_window.get_greeter().unlock()
41 window = self.main_window.get_qml_view()
39 window = self.main_window.get_qml_view()
42 hud_show_button = self.main_window.get_hud_show_button()
40 hud_show_button = self.main_window.get_hud_show_button()
43 hud = self.main_window.get_hud()
41 hud = self.main_window.get_hud()
@@ -58,7 +56,6 @@ class TestHud(UnityTestCase):
58
56
59 """
57 """
60 self.launch_unity()
58 self.launch_unity()
61− self.main_window.get_greeter().unlock()
62 window = self.main_window.get_qml_view()
59 window = self.main_window.get_qml_view()
63 hud_show_button = self.main_window.get_hud_show_button()
60 hud_show_button = self.main_window.get_hud_show_button()
64 hud = self.main_window.get_hud()
61 hud = self.main_window.get_hud()
@@ -81,7 +78,6 @@ class TestHud(UnityTestCase):
81 def test_hide_hud_click(self):
78 def test_hide_hud_click(self):
82 """Tapping the close button of the Hud must dismiss it."""
79 """Tapping the close button of the Hud must dismiss it."""
83 self.launch_unity()
80 self.launch_unity()
84− self.main_window.get_greeter().unlock()
85 hud = self.main_window.get_hud()
81 hud = self.main_window.get_hud()
86
82
87 self._launch_test_app_from_app_screen()
83 self._launch_test_app_from_app_screen()
@@ -97,7 +93,6 @@ class TestHud(UnityTestCase):
97
93
98 """
94 """
99 self.launch_unity()
95 self.launch_unity()
100− self.main_window.get_greeter().unlock()
101 hud = self.main_window.get_hud()
96 hud = self.main_window.get_hud()
102 window = self.main_window.get_qml_view()
97 window = self.main_window.get_qml_view()
103
98
@@ -114,7 +109,6 @@ class TestHud(UnityTestCase):
114 def test_launcher_hides_hud(self):
109 def test_launcher_hides_hud(self):
115 """Opening the Launcher while the Hud is active must close the Hud."""
110 """Opening the Launcher while the Hud is active must close the Hud."""
116 self.launch_unity()
111 self.launch_unity()
117− self.main_window.get_greeter().unlock()
118 hud = self.main_window.get_hud()
112 hud = self.main_window.get_hud()
119 launcher = self.main_window.get_launcher()
113 launcher = self.main_window.get_launcher()
120
114
tests/autopilot/unity8/shell/tests/test_lock_screen.py+4−4
@@ -38,7 +38,7 @@ class TestLockscreen(UnityTestCase):
38 @with_lightdm_mock("single-pin")
38 @with_lightdm_mock("single-pin")
39 def test_can_unlock_pin_screen(self):
39 def test_can_unlock_pin_screen(self):
40 """Must be able to unlock the PIN entry lock screen."""
40 """Must be able to unlock the PIN entry lock screen."""
41− self.launch_unity()
41+ self.launch_greeter()
42 greeter = self.main_window.get_greeter()
42 greeter = self.main_window.get_greeter()
43 greeter.unlock()
43 greeter.unlock()
44
44
@@ -50,7 +50,7 @@ class TestLockscreen(UnityTestCase):
50 @with_lightdm_mock("single-passphrase")
50 @with_lightdm_mock("single-passphrase")
51 def test_can_unlock_passphrase_screen(self):
51 def test_can_unlock_passphrase_screen(self):
52 """Must be able to unlock the passphrase entry screen."""
52 """Must be able to unlock the passphrase entry screen."""
53− self.launch_unity()
53+ self.launch_greeter()
54 greeter = self.main_window.get_greeter()
54 greeter = self.main_window.get_greeter()
55 greeter.unlock()
55 greeter.unlock()
56
56
@@ -62,7 +62,7 @@ class TestLockscreen(UnityTestCase):
62 @with_lightdm_mock("single-pin")
62 @with_lightdm_mock("single-pin")
63 def test_pin_screen_wrong_code(self):
63 def test_pin_screen_wrong_code(self):
64 """Entering the wrong pin code must not dismiss the lock screen."""
64 """Entering the wrong pin code must not dismiss the lock screen."""
65− self.launch_unity()
65+ self.launch_greeter()
66 greeter = self.main_window.get_greeter()
66 greeter = self.main_window.get_greeter()
67 greeter.unlock()
67 greeter.unlock()
68
68
@@ -76,7 +76,7 @@ class TestLockscreen(UnityTestCase):
76 @with_lightdm_mock("single-passphrase")
76 @with_lightdm_mock("single-passphrase")
77 def test_passphrase_screen_wrong_password(self):
77 def test_passphrase_screen_wrong_password(self):
78 """Entering the wrong password must not dismiss the lock screen."""
78 """Entering the wrong password must not dismiss the lock screen."""
79− self.launch_unity()
79+ self.launch_greeter()
80 greeter = self.main_window.get_greeter()
80 greeter = self.main_window.get_greeter()
81 greeter.unlock()
81 greeter.unlock()
82
82
tests/mocks/CMakeLists.txt+1−1
@@ -1,5 +1,5 @@
1+add_subdirectory(liblightdm)
1add_subdirectory(libusermetrics)
2add_subdirectory(libusermetrics)
2−add_subdirectory(LightDM)
3add_subdirectory(QMenuModel)
3add_subdirectory(QMenuModel)
4add_subdirectory(Ubuntu)
4add_subdirectory(Ubuntu)
5add_subdirectory(Unity)
5add_subdirectory(Unity)
tests/mocks/LightDM/CMakeLists.txtdeleted−55
@@ -1,55 +0,0 @@
1−# This is a copy of the normal LightDM plugin, but instead of statically
2−# linking in the lightdm bits, this one uses shared libraries so we can swap
3−# out different sets of users for different tests. When we finally switch to
4−# actually using the system liblightdm in the normal plugin, this version can
5−# be deleted.
6−
7−add_subdirectory(demo)
8−add_subdirectory(full)
9−add_subdirectory(single)
10−add_subdirectory(single-pin)
11−add_subdirectory(single-passphrase)
12−
13−include_directories(
14− ${CMAKE_CURRENT_SOURCE_DIR}
15− ${CMAKE_CURRENT_BINARY_DIR}
16− ${CMAKE_SOURCE_DIR}/tests/mocks/libusermetrics
17−)
18−
19−set(QMLPLUGIN_SRC
20− ${CMAKE_SOURCE_DIR}/plugins/LightDM/Greeter.cpp
21− ${CMAKE_SOURCE_DIR}/plugins/LightDM/plugin.cpp
22− ${CMAKE_SOURCE_DIR}/plugins/LightDM/UsersModel.cpp
23− ${CMAKE_SOURCE_DIR}/plugins/Utils/qsortfilterproxymodelqml.cpp
24− )
25−
26−add_library(MockLightDM-qml MODULE
27− ${QMLPLUGIN_SRC}
28− )
29−
30−# We want to link to liblightdm-qt5-2, but we don't want to depend on it being
31−# installed on the system. So we make sure we link to our full fake version
32−# At run time, we can point to whichever version we happen to be using via
33−# LD_LIBRARY_PATH.
34−add_dependencies(MockLightDM-qml MockLightDM-full)
35−target_link_libraries(MockLightDM-qml
36− -L${CMAKE_CURRENT_BINARY_DIR}/full
37− -llightdm-qt5-2
38− -L${CMAKE_BINARY_DIR}/tests/mocks/libusermetrics
39− -lusermetricsoutput
40− )
41−
42−qt5_use_modules(MockLightDM-qml Gui Qml)
43−
44−# copy qmldir file into build directory for shadow builds
45−file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/qmldir"
46− DESTINATION ${CMAKE_CURRENT_BINARY_DIR}
47− )
48−
49−install(TARGETS MockLightDM-qml
50− DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/mocks/LightDM
51− )
52−
53−install(FILES qmldir
54− DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/mocks/LightDM
55− )
tests/mocks/liblightdm/CMakeLists.txtnew file+4
@@ -0,0 +1,4 @@
1+add_subdirectory(full)
2+add_subdirectory(single)
3+add_subdirectory(single-pin)
4+add_subdirectory(single-passphrase)
tests/mocks/LightDM/Greeter.cpp → tests/mocks/liblightdm/Greeter.cpprenamed

The content is the same.

tests/mocks/LightDM/Greeter.h → tests/mocks/liblightdm/Greeter.hrenamed

The content is the same.

tests/mocks/LightDM/GreeterPrivate.h → tests/mocks/liblightdm/GreeterPrivate.hrenamed

The content is the same.

tests/mocks/LightDM/QLightDM/Greeter → tests/mocks/liblightdm/QLightDM/Greeterrenamed

The content is the same.

tests/mocks/LightDM/QLightDM/InfographicModel → tests/mocks/liblightdm/QLightDM/InfographicModelrenamed

The content is the same.

tests/mocks/LightDM/QLightDM/UsersModel → tests/mocks/liblightdm/QLightDM/UsersModelrenamed

The content is the same.

tests/mocks/LightDM/UsersModel.cpp → tests/mocks/liblightdm/UsersModel.cpprenamed

The content is the same.

tests/mocks/LightDM/UsersModel.h → tests/mocks/liblightdm/UsersModel.hrenamed

The content is the same.

tests/mocks/LightDM/UsersModelPrivate.h → tests/mocks/liblightdm/UsersModelPrivate.hrenamed

The content is the same.

tests/mocks/LightDM/demo/CMakeLists.txt → tests/mocks/liblightdm/demo/CMakeLists.txtrenamed

The content is the same.

tests/mocks/LightDM/demo/GreeterPrivate.cpp → tests/mocks/liblightdm/demo/GreeterPrivate.cpprenamed

The content is the same.

tests/mocks/LightDM/demo/InfographicModelPrivate.cpp → tests/mocks/liblightdm/demo/InfographicModelPrivate.cpprenamed

The content is the same.

tests/mocks/LightDM/demo/UsersModelPrivate.cpp → tests/mocks/liblightdm/demo/UsersModelPrivate.cpprenamed

The content is the same.

tests/mocks/LightDM/full/CMakeLists.txt → tests/mocks/liblightdm/full/CMakeLists.txtrenamed+3−2
@@ -11,8 +11,9 @@ add_library(MockLightDM-full SHARED ${LibLightDM_SOURCES})
11qt5_use_modules(MockLightDM-full Gui)
11qt5_use_modules(MockLightDM-full Gui)
12
12
13set_target_properties(MockLightDM-full PROPERTIES
13set_target_properties(MockLightDM-full PROPERTIES
14− OUTPUT_NAME lightdm-qt5-2)
14+ OUTPUT_NAME lightdm-qt5-3
15+ SOVERSION 0)
15
16
16install(TARGETS MockLightDM-full
17install(TARGETS MockLightDM-full
17− DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/mocks/LightDM/full
18+ DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/mocks/liblightdm/full
18 )
19 )
tests/mocks/LightDM/full/GreeterPrivate.cpp → tests/mocks/liblightdm/full/GreeterPrivate.cpprenamed

The content is the same.

tests/mocks/LightDM/full/InfographicModelPrivate.cpp → tests/mocks/liblightdm/full/InfographicModelPrivate.cpprenamed

The content is the same.

tests/mocks/LightDM/full/UsersModelPrivate.cpp → tests/mocks/liblightdm/full/UsersModelPrivate.cpprenamed

The content is the same.

tests/mocks/LightDM/qmldir → tests/mocks/liblightdm/qmldirrenamed

The content is the same.

tests/mocks/LightDM/single-passphrase/CMakeLists.txt → tests/mocks/liblightdm/single-passphrase/CMakeLists.txtrenamed+3−2
@@ -12,8 +12,9 @@ add_library(MockLightDM-single-passphrase SHARED ${LibLightDM_SOURCES})
12qt5_use_modules(MockLightDM-single-passphrase Gui)
12qt5_use_modules(MockLightDM-single-passphrase Gui)
13
13
14set_target_properties(MockLightDM-single-passphrase PROPERTIES
14set_target_properties(MockLightDM-single-passphrase PROPERTIES
15− OUTPUT_NAME lightdm-qt5-2)
15+ OUTPUT_NAME lightdm-qt5-3
16+ SOVERSION 0)
16
17
17install(TARGETS MockLightDM-single-passphrase
18install(TARGETS MockLightDM-single-passphrase
18− DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/mocks/LightDM/single-passphrase
19+ DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/mocks/liblightdm/single-passphrase
19 )
20 )
tests/mocks/LightDM/single-passphrase/GreeterPrivate.cpp → tests/mocks/liblightdm/single-passphrase/GreeterPrivate.cpprenamed

The content is the same.

tests/mocks/LightDM/single-passphrase/InfographicModelPrivate.cpp → tests/mocks/liblightdm/single-passphrase/InfographicModelPrivate.cpprenamed

The content is the same.

tests/mocks/LightDM/single-passphrase/UsersModelPrivate.cpp → tests/mocks/liblightdm/single-passphrase/UsersModelPrivate.cpprenamed

The content is the same.

tests/mocks/LightDM/single-pin/CMakeLists.txt → tests/mocks/liblightdm/single-pin/CMakeLists.txtrenamed+3−2
@@ -12,8 +12,9 @@ add_library(MockLightDM-single-pin SHARED ${LibLightDM_SOURCES})
12qt5_use_modules(MockLightDM-single-pin Gui)
12qt5_use_modules(MockLightDM-single-pin Gui)
13
13
14set_target_properties(MockLightDM-single-pin PROPERTIES
14set_target_properties(MockLightDM-single-pin PROPERTIES
15− OUTPUT_NAME lightdm-qt5-2)
15+ OUTPUT_NAME lightdm-qt5-3
16+ SOVERSION 0)
16
17
17install(TARGETS MockLightDM-single-pin
18install(TARGETS MockLightDM-single-pin
18− DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/mocks/LightDM/single-pin
19+ DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/mocks/liblightdm/single-pin
19 )
20 )
tests/mocks/LightDM/single-pin/GreeterPrivate.cpp → tests/mocks/liblightdm/single-pin/GreeterPrivate.cpprenamed

The content is the same.

tests/mocks/LightDM/single-pin/InfographicModelPrivate.cpp → tests/mocks/liblightdm/single-pin/InfographicModelPrivate.cpprenamed

The content is the same.

tests/mocks/LightDM/single-pin/UsersModelPrivate.cpp → tests/mocks/liblightdm/single-pin/UsersModelPrivate.cpprenamed

The content is the same.

tests/mocks/LightDM/single/CMakeLists.txt → tests/mocks/liblightdm/single/CMakeLists.txtrenamed+3−2
@@ -11,8 +11,9 @@ add_library(MockLightDM-single SHARED ${LibLightDM_SOURCES})
11qt5_use_modules(MockLightDM-single Gui)
11qt5_use_modules(MockLightDM-single Gui)
12
12
13set_target_properties(MockLightDM-single PROPERTIES
13set_target_properties(MockLightDM-single PROPERTIES
14− OUTPUT_NAME lightdm-qt5-2)
14+ OUTPUT_NAME lightdm-qt5-3
15+ SOVERSION 0)
15
16
16install(TARGETS MockLightDM-single
17install(TARGETS MockLightDM-single
17− DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/mocks/LightDM/single
18+ DESTINATION ${SHELL_PRIVATE_LIBDIR}/qml/mocks/liblightdm/single
18 )
19 )
tests/mocks/LightDM/single/GreeterPrivate.cpp → tests/mocks/liblightdm/single/GreeterPrivate.cpprenamed

The content is the same.

tests/mocks/LightDM/single/InfographicModelPrivate.cpp → tests/mocks/liblightdm/single/InfographicModelPrivate.cpprenamed

The content is the same.

tests/mocks/LightDM/single/UsersModelPrivate.cpp → tests/mocks/liblightdm/single/UsersModelPrivate.cpprenamed

The content is the same.

tests/plugins/CMakeLists.txt+1
@@ -1,3 +1,4 @@
1+add_subdirectory(SessionManager)
1add_subdirectory(Utils)
2add_subdirectory(Utils)
2add_subdirectory(Ubuntu)
3add_subdirectory(Ubuntu)
3add_subdirectory(Unity)
4add_subdirectory(Unity)
tests/plugins/SessionManager/CMakeLists.txtnew file+48
@@ -0,0 +1,48 @@
1+macro(make_dbus_class PREFIX SERVICE INTERFACE)
2+ if (${CMAKE_CURRENT_SOURCE_DIR}/interfaces.xml IS_NEWER_THAN ${CMAKE_CURRENT_BINARY_DIR}/${PREFIX}${INTERFACE}Adaptor.h)
3+ execute_process(COMMAND qdbusxml2cpp -c ${PREFIX}${INTERFACE}Adaptor -a ${CMAKE_CURRENT_BINARY_DIR}/${PREFIX}${INTERFACE}Adaptor ${CMAKE_CURRENT_SOURCE_DIR}/interfaces.xml ${SERVICE}.${INTERFACE})
4+ endif ()
5+endmacro(make_dbus_class)
6+
7+make_dbus_class(LightDM org.freedesktop.DisplayManager Session)
8+make_dbus_class(Login org.freedesktop.login1 Manager)
9+make_dbus_class(Login org.freedesktop.login1 Session)
10+make_dbus_class(Login org.freedesktop.DBus Properties)
11+
12+include_directories(
13+ ${CMAKE_CURRENT_BINARY_DIR}
14+ ${CMAKE_SOURCE_DIR}/plugins/SessionManager
15+ )
16+
17+add_definitions(-DSM_BUSNAME=sessionBus)
18+
19+add_executable(mock-server
20+ ${CMAKE_CURRENT_BINARY_DIR}/LightDMSessionAdaptor.cpp
21+ ${CMAKE_CURRENT_BINARY_DIR}/LoginManagerAdaptor.cpp
22+ ${CMAKE_CURRENT_BINARY_DIR}/LoginPropertiesAdaptor.cpp
23+ ${CMAKE_CURRENT_BINARY_DIR}/LoginSessionAdaptor.cpp
24+ server.cpp
25+ LightDMSessionServer.cpp
26+ LoginManagerServer.cpp
27+ LoginSessionServer.cpp
28+ )
29+qt5_use_modules(mock-server Core DBus)
30+
31+add_executable(test-sessionmanager
32+ ${CMAKE_SOURCE_DIR}/plugins/SessionManager/SessionManager.cpp
33+ client.cpp
34+ )
35+qt5_use_modules(test-sessionmanager Core DBus Test)
36+
37+add_test(NAME test-sessionmanager
38+ COMMAND env
39+ XDG_SESSION_ID=sessionid
40+ XDG_SESSION_PATH=/mocksession/lightdm
41+ dbus-test-runner
42+ --task ${CMAKE_CURRENT_BINARY_DIR}/mock-server
43+ --task-name server
44+ --ignore-return
45+ --task ${CMAKE_CURRENT_BINARY_DIR}/test-sessionmanager
46+ --task-name client
47+ --wait-for org.freedesktop.login1
48+ )
tests/plugins/SessionManager/LightDMSessionServer.cppnew file+38
@@ -0,0 +1,38 @@
1+/*
2+ * Copyright 2013 Canonical Ltd.
3+ *
4+ * This program is free software: you can redistribute it and/or modify it
5+ * under the terms of the GNU General Public License version 3, as published
6+ * by the Free Software Foundation.
7+ *
8+ * This program is distributed in the hope that it will be useful, but
9+ * WITHOUT ANY WARRANTY; without even the implied warranties of
10+ * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
11+ * PURPOSE. See the GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * version 3 along with this program. If not, see
15+ * <http://www.gnu.org/licenses/>
16+ *
17+ * Authored by: Michael Terry <michael.terry@canonical.com>
18+ */
19+
20+#include "LightDMSessionServer.h"
21+
22+LightDMSessionServer::LightDMSessionServer(LoginSessionServer *logind, QObject *parent)
23+ : QObject(parent),
24+ logind(logind)
25+{
26+}
27+
28+void LightDMSessionServer::Lock()
29+{
30+ // As a side effect of locking, change Active state of logind.
31+ // Note that this will say Active is true while the Active property will be
32+ // false. This is intentional, as we don't want to keep any state in the
33+ // mocks. Having this signal side effect lets us test that lock() was
34+ // actually called by the plugin as well as test the changed signal itself.
35+ QVariantMap changes;
36+ changes.insert("Active", QVariant(true));
37+ Q_EMIT logind->PropertiesChanged("org.freedesktop.login1.Session", changes, QStringList());
38+}
tests/plugins/SessionManager/LightDMSessionServer.hnew file+40
@@ -0,0 +1,40 @@
1+/*
2+ * Copyright 2013 Canonical Ltd.
3+ *
4+ * This program is free software: you can redistribute it and/or modify it
5+ * under the terms of the GNU General Public License version 3, as published
6+ * by the Free Software Foundation.
7+ *
8+ * This program is distributed in the hope that it will be useful, but
9+ * WITHOUT ANY WARRANTY; without even the implied warranties of
10+ * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
11+ * PURPOSE. See the GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * version 3 along with this program. If not, see
15+ * <http://www.gnu.org/licenses/>
16+ *
17+ * Authored by: Michael Terry <michael.terry@canonical.com>
18+ */
19+
20+#ifndef UNITY_LIGHTDMSESSIONSERVER_H
21+#define UNITY_LIGHTDMSESSIONSERVER_H
22+
23+#include "LoginSessionServer.h"
24+#include <QtCore/QObject>
25+
26+class LightDMSessionServer: public QObject
27+{
28+ Q_OBJECT
29+
30+public:
31+ explicit LightDMSessionServer(LoginSessionServer *logind, QObject *parent = 0);
32+
33+public Q_SLOTS:
34+ void Lock();
35+
36+private:
37+ LoginSessionServer *logind;
38+};
39+
40+#endif
tests/plugins/SessionManager/LoginManagerServer.cppnew file+34
@@ -0,0 +1,34 @@
1+/*
2+ * Copyright 2013 Canonical Ltd.
3+ *
4+ * This program is free software: you can redistribute it and/or modify it
5+ * under the terms of the GNU General Public License version 3, as published
6+ * by the Free Software Foundation.
7+ *
8+ * This program is distributed in the hope that it will be useful, but
9+ * WITHOUT ANY WARRANTY; without even the implied warranties of
10+ * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
11+ * PURPOSE. See the GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * version 3 along with this program. If not, see
15+ * <http://www.gnu.org/licenses/>
16+ *
17+ * Authored by: Michael Terry <michael.terry@canonical.com>
18+ */
19+
20+#include "LoginManagerServer.h"
21+
22+LoginManagerServer::LoginManagerServer(QObject *parent)
23+ : QObject(parent)
24+{
25+}
26+
27+QDBusObjectPath LoginManagerServer::GetSession(const QString &id)
28+{
29+ if (id == "sessionid") {
30+ return QDBusObjectPath("/mocksession/login1");
31+ } else {
32+ return QDBusObjectPath();
33+ }
34+}
tests/plugins/SessionManager/LoginManagerServer.hnew file+37
@@ -0,0 +1,37 @@
1+/*
2+ * Copyright 2013 Canonical Ltd.
3+ *
4+ * This program is free software: you can redistribute it and/or modify it
5+ * under the terms of the GNU General Public License version 3, as published
6+ * by the Free Software Foundation.
7+ *
8+ * This program is distributed in the hope that it will be useful, but
9+ * WITHOUT ANY WARRANTY; without even the implied warranties of
10+ * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
11+ * PURPOSE. See the GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * version 3 along with this program. If not, see
15+ * <http://www.gnu.org/licenses/>
16+ *
17+ * Authored by: Michael Terry <michael.terry@canonical.com>
18+ */
19+
20+#ifndef UNITY_LOGINMANAGERSERVER_H
21+#define UNITY_LOGINMANAGERSERVER_H
22+
23+#include <QtCore/QObject>
24+#include <QtDBus/QDBusObjectPath>
25+
26+class LoginManagerServer: public QObject
27+{
28+ Q_OBJECT
29+
30+public:
31+ explicit LoginManagerServer(QObject *parent = 0);
32+
33+public Q_SLOTS:
34+ QDBusObjectPath GetSession(const QString &id);
35+};
36+
37+#endif
tests/plugins/SessionManager/LoginSessionServer.cppnew file+25
@@ -0,0 +1,25 @@
1+/*
2+ * Copyright 2013 Canonical Ltd.
3+ *
4+ * This program is free software: you can redistribute it and/or modify it
5+ * under the terms of the GNU General Public License version 3, as published
6+ * by the Free Software Foundation.
7+ *
8+ * This program is distributed in the hope that it will be useful, but
9+ * WITHOUT ANY WARRANTY; without even the implied warranties of
10+ * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
11+ * PURPOSE. See the GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * version 3 along with this program. If not, see
15+ * <http://www.gnu.org/licenses/>
16+ *
17+ * Authored by: Michael Terry <michael.terry@canonical.com>
18+ */
19+
20+#include "LoginSessionServer.h"
21+
22+LoginSessionServer::LoginSessionServer(QObject *parent)
23+ : QObject(parent)
24+{
25+}
tests/plugins/SessionManager/LoginSessionServer.hnew file+39
@@ -0,0 +1,39 @@
1+/*
2+ * Copyright 2013 Canonical Ltd.
3+ *
4+ * This program is free software: you can redistribute it and/or modify it
5+ * under the terms of the GNU General Public License version 3, as published
6+ * by the Free Software Foundation.
7+ *
8+ * This program is distributed in the hope that it will be useful, but
9+ * WITHOUT ANY WARRANTY; without even the implied warranties of
10+ * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
11+ * PURPOSE. See the GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * version 3 along with this program. If not, see
15+ * <http://www.gnu.org/licenses/>
16+ *
17+ * Authored by: Michael Terry <michael.terry@canonical.com>
18+ */
19+
20+#ifndef UNITY_LOGINSESSIONSERVER_H
21+#define UNITY_LOGINSESSIONSERVER_H
22+
23+#include <QtCore/QObject>
24+#include <QtCore/QStringList>
25+#include <QtCore/QVariant>
26+#include <QtCore/QVariantMap>
27+
28+class LoginSessionServer: public QObject
29+{
30+ Q_OBJECT
31+
32+public:
33+ explicit LoginSessionServer(QObject *parent = 0);
34+
35+Q_SIGNALS:
36+ void PropertiesChanged(const QString &interface, const QVariantMap &changed, const QStringList &invalid);
37+};
38+
39+#endif
tests/plugins/SessionManager/client.cppnew file+88
@@ -0,0 +1,88 @@
1+/*
2+ * Copyright 2013 Canonical Ltd.
3+ *
4+ * This program is free software: you can redistribute it and/or modify it
5+ * under the terms of the GNU General Public License version 3, as published
6+ * by the Free Software Foundation.
7+ *
8+ * This program is distributed in the hope that it will be useful, but
9+ * WITHOUT ANY WARRANTY; without even the implied warranties of
10+ * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
11+ * PURPOSE. See the GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * version 3 along with this program. If not, see
15+ * <http://www.gnu.org/licenses/>
16+ *
17+ * Authored by: Michael Terry <michael.terry@canonical.com>
18+ */
19+
20+#include "SessionManager.h"
21+#include <QtTest/QSignalSpy>
22+#include <QtTest/QTest>
23+
24+
25+// These tests assume the following behavior from our mock logind server:
26+// * IsActive will return false
27+// * Lock() will emit an ActiveChanged(true) signal
28+//
29+// This should lead to the following behavior from our SessionManager plugin:
30+// * Starts active
31+// * Becomes inactive once it connects to logind and sees IsActive result
32+// * Becomes active once Lock() is called (which isn't really sensible, but
33+// it's just a mock)
34+
35+class SessionManagerTest : public QObject
36+{
37+ Q_OBJECT
38+
39+private Q_SLOTS:
40+
41+ void waitForChange(SessionManager *session)
42+ {
43+ // Wait 5 seconds for initial activeChanged signal
44+ QSignalSpy spy(session, SIGNAL(activeChanged()));
45+ int i = 0;
46+ while (spy.count() == 0 && i++ < 50)
47+ QTest::qWait(100);
48+ QCOMPARE(spy.count(), 1);
49+ }
50+
51+ void testAssumeActive()
52+ {
53+ // Test that active() starts as true before we connect to service
54+ SessionManager session;
55+ QCOMPARE(session.active(), true);
56+ }
57+
58+ void testSafeLock()
59+ {
60+ // Test that lock() doesn't crash if used before we connect to service
61+ // (i.e. just test that we're not being stupid about pointers)
62+ SessionManager session;
63+ session.lock();
64+ }
65+
66+ void testInitialSignal()
67+ {
68+ // Test that we get notified of change once we connect to service
69+ SessionManager session;
70+ waitForChange(&session);
71+ QCOMPARE(session.active(), false);
72+ }
73+
74+ void testLock()
75+ {
76+ // Test that lock() gets called correctly and that we listen for
77+ // the activeChanged signal too.
78+ SessionManager session;
79+ waitForChange(&session);
80+ session.lock();
81+ waitForChange(&session);
82+ QCOMPARE(session.active(), true);
83+ }
84+};
85+
86+QTEST_MAIN(SessionManagerTest)
87+
88+#include "client.moc"
tests/plugins/SessionManager/interfaces.xmlnew file+22
@@ -0,0 +1,22 @@
1+<node>
2+ <interface name="org.freedesktop.login1.Manager">
3+ <method name="GetSession">
4+ <arg name="id" type="s" direction="in" />
5+ <arg name="path" type="o" direction="out" />
6+ </method>
7+ </interface>
8+ <interface name="org.freedesktop.login1.Session">
9+ <property name="Active" type="b" access="read"/>
10+ </interface>
11+ <interface name="org.freedesktop.DBus.Properties">
12+ <signal name="PropertiesChanged">
13+ <annotation name="org.qtproject.QtDBus.QtTypeName.In1" value="QVariantMap"/>
14+ <arg name="interface" type="s" direction="out"/>
15+ <arg name="changed" type="a{sv}" direction="out"/>
16+ <arg name="invalid" type="as" direction="out"/>
17+ </signal>
18+ </interface>
19+ <interface name="org.freedesktop.DisplayManager.Session">
20+ <method name="Lock"/>
21+ </interface>
22+</node>
tests/plugins/SessionManager/server.cppnew file+57
@@ -0,0 +1,57 @@
1+/*
2+ * Copyright 2013 Canonical Ltd.
3+ *
4+ * This program is free software: you can redistribute it and/or modify it
5+ * under the terms of the GNU General Public License version 3, as published
6+ * by the Free Software Foundation.
7+ *
8+ * This program is distributed in the hope that it will be useful, but
9+ * WITHOUT ANY WARRANTY; without even the implied warranties of
10+ * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
11+ * PURPOSE. See the GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * version 3 along with this program. If not, see
15+ * <http://www.gnu.org/licenses/>
16+ *
17+ * Authored by: Michael Terry <michael.terry@canonical.com>
18+ */
19+
20+#include "LightDMSessionAdaptor.h"
21+#include "LightDMSessionServer.h"
22+#include "LoginManagerAdaptor.h"
23+#include "LoginManagerServer.h"
24+#include "LoginPropertiesAdaptor.h"
25+#include "LoginSessionAdaptor.h"
26+#include "LoginSessionServer.h"
27+#include <QtCore/QCoreApplication>
28+
29+int main(int argc, char *argv[])
30+{
31+ QCoreApplication a(argc, argv);
32+
33+ LoginManagerServer *manager = new LoginManagerServer();
34+ new LoginManagerAdaptor(manager);
35+
36+ LoginSessionServer *l1_session = new LoginSessionServer();
37+ new LoginSessionAdaptor(l1_session);
38+ new LoginPropertiesAdaptor(l1_session);
39+
40+ LightDMSessionServer *ldm_session = new LightDMSessionServer(l1_session);
41+ new LightDMSessionAdaptor(ldm_session);
42+
43+ // We use the session bus for testing. The real plugin uses the system bus
44+ QDBusConnection connection = QDBusConnection::sessionBus();
45+ if (!connection.registerObject("/org/freedesktop/login1", manager))
46+ return 1;
47+ if (!connection.registerObject("/mocksession/login1", l1_session))
48+ return 1;
49+ if (!connection.registerObject("/mocksession/lightdm", ldm_session))
50+ return 1;
51+ if (!connection.registerService("org.freedesktop.DisplayManager"))
52+ return 1;
53+ if (!connection.registerService("org.freedesktop.login1"))
54+ return 1;
55+
56+ return a.exec();
57+}
tests/qmltests/CMakeLists.txt+20−28
@@ -4,6 +4,7 @@ include(QmlTest)
4add_subdirectory(Components)
4add_subdirectory(Components)
5
5
6set(qmltest_DEFAULT_IMPORT_PATHS
6set(qmltest_DEFAULT_IMPORT_PATHS
7+ ${CMAKE_BINARY_DIR}/plugins
7 ${CMAKE_BINARY_DIR}/tests/utils/modules
8 ${CMAKE_BINARY_DIR}/tests/utils/modules
8 ${CMAKE_BINARY_DIR}/tests/mocks
9 ${CMAKE_BINARY_DIR}/tests/mocks
9)
10)
@@ -27,45 +28,36 @@ set(qmltest_DEFAULT_NO_ADD_TEST TRUE)
27set(qmltest_DEFAULT_PROPERTIES "")
28set(qmltest_DEFAULT_PROPERTIES "")
28
29
29add_qml_test(. Shell IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS}
30add_qml_test(. Shell IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS}
30− ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/LightDM/single")
31+ ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/liblightdm/single")
31add_manual_qml_test(Components DragHandle IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins)
32add_manual_qml_test(Components DragHandle IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins)
32add_qml_test(Components DraggingArea)
33add_qml_test(Components DraggingArea)
33−add_qml_test(Components FilterGrid IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/plugins)
34+add_qml_test(Components FilterGrid)
34add_qml_test(Components ResponsiveFlowView)
35add_qml_test(Components ResponsiveFlowView)
35add_qml_test(Components ResponsiveGridView)
36add_qml_test(Components ResponsiveGridView)
36add_qml_test(Components Revealer)
37add_qml_test(Components Revealer)
37add_qml_test(Components Showable)
38add_qml_test(Components Showable)
38−add_qml_test(Components Stage IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS}
39+add_qml_test(Components Stage)
39− ${CMAKE_BINARY_DIR}/tests/mocks
40− ${CMAKE_BINARY_DIR}/plugins)
41add_qml_test(Components Tile)
40add_qml_test(Components Tile)
42add_qml_test(Components PageHeader)
41add_qml_test(Components PageHeader)
43−add_qml_test(Dash Dash IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS})
42+add_qml_test(Dash Dash)
44−add_qml_test(Dash DashBar IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${CMAKE_CURRENT_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS})
43+add_qml_test(Dash DashBar)
45−add_qml_test(Dash DashContent IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS})
44+add_qml_test(Dash DashContent)
46add_qml_test(Dash DashPreview)
45add_qml_test(Dash DashPreview)
47−add_qml_test(Dash GenericScopeView IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS})
46+add_qml_test(Dash GenericScopeView)
48−add_qml_test(Dash ScopeView IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS})
47+add_qml_test(Dash ScopeView)
49−add_qml_test(Dash FilterGrids IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/plugins ${CMAKE_CURRENT_SOURCE_DIR}/plugins
48+add_qml_test(Dash FilterGrids)
50− ${CMAKE_BINARY_DIR}/tests/mocks)
51−add_qml_test(Dash/Apps RunningApplicationsGrid IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/tests/mocks)
49+add_qml_test(Dash/Apps RunningApplicationsGrid)
52−add_qml_test(Greeter Lockscreen IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS}
53− PROPERTIES ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/libusermetrics:${CMAKE_BINARY_DIR}/tests/mocks/LightDM/full")
50+add_qml_test(Greeter Lockscreen ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/libusermetrics:${CMAKE_BINARY_DIR}/tests/mocks/liblightdm/full")
54−add_qml_test(Greeter Tablet IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS}
55− ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/libusermetrics:${CMAKE_BINARY_DIR}/tests/mocks/LightDM/full")
51+add_qml_test(Greeter Tablet ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/libusermetrics:${CMAKE_BINARY_DIR}/tests/mocks/liblightdm/full")
56−add_qml_test(Greeter Phone IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS}
57− ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/libusermetrics:${CMAKE_BINARY_DIR}/tests/mocks/LightDM/single")
52+add_qml_test(Greeter Phone ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/libusermetrics:${CMAKE_BINARY_DIR}/tests/mocks/liblightdm/single")
58−add_qml_test(Greeter Infographics IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS}
59− ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/libusermetrics:${CMAKE_BINARY_DIR}/tests/mocks/LightDM/full")
53+add_qml_test(Greeter Infographics ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/libusermetrics:${CMAKE_BINARY_DIR}/tests/mocks/liblightdm/full")
60add_qml_test(Hud Hud)
54add_qml_test(Hud Hud)
61add_qml_test(Hud Result)
55add_qml_test(Hud Result)
62−add_qml_test(Launcher Launcher IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS})
56+add_qml_test(Launcher Launcher)
63−add_qml_test(Notifications Notifications IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_SOURCE_DIR}/tests/mocks)
57+add_qml_test(Notifications Notifications)
64add_qml_test(Panel IndicatorRow)
58add_qml_test(Panel IndicatorRow)
65−add_qml_test(Panel Indicators IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS})
59+add_qml_test(Panel Indicators)
66add_qml_test(Panel MenuContent)
60add_qml_test(Panel MenuContent)
67−add_qml_test(Panel Panel IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS})
61+add_qml_test(Panel Panel)
68add_qml_test(Panel SearchIndicator)
62add_qml_test(Panel SearchIndicator)
69−add_qml_test(SideStage SideStage IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS}
63+add_qml_test(SideStage SideStage)
70− ${CMAKE_BINARY_DIR}/tests/mocks
71− ${CMAKE_BINARY_DIR}/plugins)
unity8-greeter.desktop.innew file+10
@@ -0,0 +1,10 @@
1+[Desktop Entry]
2+Type=Application
3+Name=Unity 8 Greeter
4+GenericName=unity8-greeter
5+Comment=The converged Unity greeter
6+Exec=@CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_BINDIR@/ubuntu-touch-session @CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_BINDIR@/unity8-greeter -fullscreen
7+Terminal=false
8+Icon=unity8
9+NoDisplay=true
10+X-Ubuntu-Touch=true