on xenial help sign in
Initial multi-monitor support

When an external screen appears, move the shell to it

commit391f833ef83ef188cc285b551c28b6c14c886354 authorDaniel d'Andrada <daniel.dandrada@canonical.com> dateFri 2 Oct 2015, 18:50 (11 years ago) parent7d01e2f
13 files changed+512−133
qml/Components/BackgroundResolver.qml+67 qml/SecondaryDisplay.qml+49 qml/Shell.qml+8−32 src/CMakeLists.txt+3 src/SecondaryWindow.cpp+31 src/SecondaryWindow.h+30 src/ShellApplication.cpp+166 src/ShellApplication.h+52 src/ShellView.cpp+36 src/ShellView.h+30 src/main.cpp+2−101 tests/qmltests/CMakeLists.txt+1 tests/qmltests/tst_SecondaryDisplay.qml+37
qml/Components/BackgroundResolver.qmlnew file+67
@@ -0,0 +1,67 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.4
18+import AccountsService 0.1
19+import GSettings 1.0
20+import Ubuntu.Components 1.3
21+
22+/*
23+ Defines the background URL based on several factors, such as:
24+ - default, fallback, background
25+ - Background set in AccountSettings, if any
26+ - Background set in GSettings, if any
27+ */
28+QtObject {
29+ /*
30+ Users should set their UI width here.
31+ */
32+ property real width
33+
34+ property url defaultBackground: Qt.resolvedUrl(width >= units.gu(60) ? "../graphics/tablet_background.jpg"
35+ : "../graphics/phone_background.jpg")
36+
37+ /*
38+ That's the property users of this component are going to consume.
39+ */
40+ readonly property url background: asImageTester.status == Image.Ready ? asImageTester.source
41+ : gsImageTester.status == Image.Ready ? gsImageTester.source : defaultBackground
42+
43+ // This is a dummy image to detect if the custom AS set wallpaper loads successfully.
44+ property var _asImageTester: Image {
45+ id: asImageTester
46+ source: "Adas"//AccountsService.backgroundFile != undefined && AccountsService.backgroundFile.length > 0 ? AccountsService.backgroundFile : ""
47+ height: 0
48+ width: 0
49+ sourceSize.height: 0
50+ sourceSize.width: 0
51+ }
52+
53+ // This is a dummy image to detect if the custom GSettings set wallpaper loads successfully.
54+ property var _gsImageTester: Image {
55+ id: gsImageTester
56+ source: backgroundSettings.pictureUri && backgroundSettings.pictureUri.length > 0 ? backgroundSettings.pictureUri : ""
57+ height: 0
58+ width: 0
59+ sourceSize.height: 0
60+ sourceSize.width: 0
61+ }
62+
63+ property var _gsettings: GSettings {
64+ id: backgroundSettings
65+ schema.id: "org.gnome.desktop.background"
66+ }
67+}
qml/SecondaryDisplay.qmlnew file+49
@@ -0,0 +1,49 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
19+import "Components"
20+
21+Image {
22+ id: root
23+
24+ BackgroundResolver {
25+ width: root.width
26+ id: bgResolver
27+ }
28+
29+ source: bgResolver.background
30+
31+ UbuntuShape {
32+ anchors.fill: text
33+ anchors.margins: -units.gu(2)
34+ backgroundColor: "black"
35+ opacity: 0.4
36+ }
37+
38+ Label {
39+ id: text
40+ anchors.centerIn: parent
41+ width: parent.width / 2
42+ text: i18n.tr("Your device is now connected to an external display.")
43+ color: "white"
44+ horizontalAlignment: Text.AlignHCenter
45+ verticalAlignment: Text.AlignVCenter
46+ fontSize: "x-large"
47+ wrapMode: Text.Wrap
48+ }
49+}
qml/Shell.qml+8−32
@@ -17,7 +17,6 @@
1717import QtQuick 2.0
1818import QtQuick.Window 2.0
1919import AccountsService 0.1
20−import GSettings 1.0
2120import Unity.Application 0.1
2221import Ubuntu.Components 0.1
2322import Ubuntu.Components.Popups 1.0
@@ -108,9 +107,11 @@ Item {
108107 enabled: greeter && !greeter.waiting
109108
110109 property real edgeSize: units.gu(2)
111− property url defaultBackground: Qt.resolvedUrl(shell.width >= units.gu(60) ? "graphics/tablet_background.jpg" : "graphics/phone_background.jpg")
112− property url background: asImageTester.status == Image.Ready ? asImageTester.source
113− : gsImageTester.status == Image.Ready ? gsImageTester.source : defaultBackground
110+
111+ BackgroundResolver {
112+ id: bgResolver
113+ width: shell.width
114+ }
114115
115116 readonly property alias greeter: greeterLoader.item
116117
@@ -131,31 +132,6 @@ Item {
131132 shell.activateApplication(app);
132133 }
133134
134− // This is a dummy image to detect if the custom AS set wallpaper loads successfully.
135− Image {
136− id: asImageTester
137− source: AccountsService.backgroundFile != undefined && AccountsService.backgroundFile.length > 0 ? AccountsService.backgroundFile : ""
138− height: 0
139− width: 0
140− sourceSize.height: 0
141− sourceSize.width: 0
142− }
143−
144− GSettings {
145− id: backgroundSettings
146− schema.id: "org.gnome.desktop.background"
147− }
148−
149− // This is a dummy image to detect if the custom GSettings set wallpaper loads successfully.
150− Image {
151− id: gsImageTester
152− source: backgroundSettings.pictureUri && backgroundSettings.pictureUri.length > 0 ? backgroundSettings.pictureUri : ""
153− height: 0
154− width: 0
155− sourceSize.height: 0
156− sourceSize.width: 0
157− }
158−
159135 Binding {
160136 target: LauncherModel
161137 property: "applicationManager"
@@ -323,7 +299,7 @@ Item {
323299 Binding {
324300 target: applicationsDisplayLoader.item
325301 property: "background"
326− value: shell.background
302+ value: bgResolver.background
327303 }
328304 Binding {
329305 target: applicationsDisplayLoader.item
@@ -428,7 +404,7 @@ Item {
428404 tabletMode: shell.usageScenario != "phone"
429405 launcherOffset: launcher.progress
430406 forcedUnlock: tutorial.running
431− background: shell.background
407+ background: bgResolver.background
432408
433409 // avoid overlapping with Launcher's edge drag area
434410 // FIXME: Fix TouchRegistry & friends and remove this workaround
@@ -603,7 +579,7 @@ Item {
603579 id: wizard
604580 objectName: "wizard"
605581 anchors.fill: parent
606− background: shell.background
582+ background: bgResolver.background
607583
608584 function unlockWhenDoneWithWizard() {
609585 if (!active) {
src/CMakeLists.txt+3
@@ -21,6 +21,9 @@ add_executable(${SHELL_APP}
2121 main.cpp
2222 MouseTouchAdaptor.cpp
2323 CachingNetworkManagerFactory.cpp
24+ SecondaryWindow.cpp
25+ ShellApplication.cpp
26+ ShellView.cpp
2427 UnityCommandLineParser.cpp
2528 ${QML_FILES} # This is to make qml and image files appear in the IDE's project tree
2629)
src/SecondaryWindow.cppnew file+31
@@ -0,0 +1,31 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#include "SecondaryWindow.h"
18+
19+// local
20+#include <paths.h>
21+
22+SecondaryWindow::SecondaryWindow(QQmlEngine *engine)
23+ : QQuickView(engine, nullptr)
24+{
25+ setResizeMode(QQuickView::SizeRootObjectToView);
26+ setColor("black");
27+ setTitle(QStringLiteral("Unity8 Shell - Secundary Screen"));
28+
29+ QUrl source(::qmlDirectory() + "/SecondaryDisplay.qml");
30+ setSource(source);
31+}
src/SecondaryWindow.hnew file+30
@@ -0,0 +1,30 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#ifndef UNITY_SECONDARY_WINDOW_H
18+#define UNITY_SECONDARY_WINDOW_H
19+
20+#include <QQuickView>
21+
22+class SecondaryWindow : public QQuickView
23+{
24+ Q_OBJECT
25+
26+public:
27+ SecondaryWindow(QQmlEngine *engine);
28+};
29+
30+#endif // UNITY_SECONDARY_WINDOW_H
src/ShellApplication.cppnew file+166
@@ -0,0 +1,166 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#include "ShellApplication.h"
18+
19+// Qt
20+#include <QLibrary>
21+#include <QScreen>
22+
23+#include <libintl.h>
24+
25+// libandroid-properties
26+#include <hybris/properties/properties.h>
27+
28+// local
29+#include <paths.h>
30+#include "CachingNetworkManagerFactory.h"
31+#include "MouseTouchAdaptor.h"
32+#include "UnityCommandLineParser.h"
33+
34+ShellApplication::ShellApplication(int & argc, char ** argv, bool isMirServer)
35+ : QGuiApplication(argc, argv)
36+{
37+
38+ setApplicationName(QStringLiteral("unity8"));
39+
40+ connect(this, &QGuiApplication::screenAdded, this, &ShellApplication::onScreenAdded);
41+
42+ setupQmlEngine(isMirServer);
43+
44+ UnityCommandLineParser parser(*this);
45+
46+ if (!parser.deviceName().isEmpty()) {
47+ m_qmlArgs.setDeviceName(parser.deviceName());
48+ } else {
49+ char buffer[200];
50+ property_get("ro.product.device", buffer /* value */, "desktop" /* default_value*/);
51+ m_qmlArgs.setDeviceName(QString(buffer));
52+ }
53+
54+ m_qmlArgs.setMode(parser.mode());
55+
56+ // The testability driver is only loaded by QApplication but not by QGuiApplication.
57+ // However, QApplication depends on QWidget which would add some unneeded overhead => Let's load the testability driver on our own.
58+ if (parser.hasTestability() || getenv("QT_LOAD_TESTABILITY")) {
59+ QLibrary testLib(QStringLiteral("qttestability"));
60+ if (testLib.load()) {
61+ typedef void (*TasInitialize)(void);
62+ TasInitialize initFunction = (TasInitialize)testLib.resolve("qt_testability_init");
63+ if (initFunction) {
64+ initFunction();
65+ } else {
66+ qCritical("Library qttestability resolve failed!");
67+ }
68+ } else {
69+ qCritical("Library qttestability load failed!");
70+ }
71+ }
72+
73+ bindtextdomain("unity8", translationDirectory().toUtf8().data());
74+ textdomain("unity8");
75+
76+ m_shellView.reset(new ShellView(m_qmlEngine, &m_qmlArgs));
77+
78+ if (parser.windowGeometry().isValid()) {
79+ m_shellView->setWidth(parser.windowGeometry().width());
80+ m_shellView->setHeight(parser.windowGeometry().height());
81+ }
82+
83+ if (parser.hasFrameless()) {
84+ m_shellView->setFlags(Qt::FramelessWindowHint);
85+ }
86+
87+ // You will need this if you want to interact with touch-only components using a mouse
88+ // Needed only when manually testing on a desktop.
89+ if (parser.hasMouseToTouch()) {
90+ m_mouseTouchAdaptor.reset(MouseTouchAdaptor::instance());
91+ }
92+
93+
94+ // Some hard-coded policy for now.
95+ // NB: We don't support more than two screens at the moment
96+ //
97+ // TODO: Support an arbitrary number of screens and different policies
98+ // (eg cloned desktop, several desktops, etc)
99+ if (isMirServer && screens().count() == 2) {
100+ m_shellView->setScreen(screens().at(1));
101+
102+ m_secondaryWindow.reset(new SecondaryWindow(m_qmlEngine));
103+ m_secondaryWindow->setScreen(screens().at(0));
104+ // QWindow::showFullScreen() also calls QWindow::requestActivate() and we don't want that!
105+ m_secondaryWindow->setWindowState(Qt::WindowFullScreen);
106+ m_secondaryWindow->setVisible(true);
107+ }
108+
109+ if (isMirServer || parser.hasFullscreen()) {
110+ m_shellView->showFullScreen();
111+ } else {
112+ m_shellView->show();
113+ }
114+}
115+
116+void ShellApplication::setupQmlEngine(bool isMirServer)
117+{
118+ m_qmlEngine = new QQmlEngine(this);
119+
120+ m_qmlEngine->setBaseUrl(QUrl::fromLocalFile(::qmlDirectory()));
121+
122+ prependImportPaths(m_qmlEngine, ::overrideImportPaths());
123+ if (!isMirServer) {
124+ prependImportPaths(m_qmlEngine, ::nonMirImportPaths());
125+ }
126+ appendImportPaths(m_qmlEngine, ::fallbackImportPaths());
127+
128+ m_qmlEngine->setNetworkAccessManagerFactory(new CachingNetworkManagerFactory);
129+
130+ QObject::connect(m_qmlEngine, &QQmlEngine::quit, this, &QGuiApplication::quit);
131+}
132+
133+void ShellApplication::onScreenAdded(QScreen * /*screen*/)
134+{
135+ // TODO: Support an arbitrary number of screens and different policies
136+ // (eg cloned desktop, several desktops, etc)
137+ if (screens().count() == 2) {
138+ m_shellView->setScreen(screens().at(1));
139+ // Changing the QScreen where a QWindow is drawn makes it also lose focus (besides having
140+ // its backing QPlatformWindow recreated). So lets refocus it.
141+ m_shellView->requestActivate();
142+
143+ m_secondaryWindow.reset(new SecondaryWindow(m_qmlEngine));
144+ m_secondaryWindow->setScreen(screens().at(0));
145+
146+ // QWindow::showFullScreen() also calls QWindow::requestActivate() and we don't want that!
147+ m_secondaryWindow->setWindowState(Qt::WindowFullScreen);
148+ m_secondaryWindow->setVisible(true);
149+ }
150+}
151+
152+void ShellApplication::onScreenAboutToBeRemoved(QScreen *screen)
153+{
154+ // TODO: Support an arbitrary number of screens and different policies
155+ // (eg cloned desktop, several desktops, etc)
156+ if (screen == m_shellView->screen()) {
157+ Q_ASSERT(screens().count() > 1);
158+ Q_ASSERT(screens().at(0) != screen);
159+ Q_ASSERT(!m_secondaryWindow.isNull());
160+ m_secondaryWindow.reset();
161+ m_shellView->setScreen(screens().first());
162+ // Changing the QScreen where a QWindow is drawn makes it also lose focus (besides having
163+ // its backing QPlatformWindow recreated). So lets refocus it.
164+ m_shellView->requestActivate();
165+ }
166+}
src/ShellApplication.hnew file+52
@@ -0,0 +1,52 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#ifndef SHELLAPPLICATION_H
18+#define SHELLAPPLICATION_H
19+
20+#include <QGuiApplication>
21+#include <QQmlEngine>
22+#include <QQuickView>
23+#include <QScopedPointer>
24+
25+#include "ApplicationArguments.h"
26+#include "MouseTouchAdaptor.h"
27+#include "SecondaryWindow.h"
28+#include "ShellView.h"
29+
30+class ShellApplication : public QGuiApplication
31+{
32+ Q_OBJECT
33+public:
34+ ShellApplication(int & argc, char ** argv, bool isMirServer);
35+
36+public Q_SLOTS:
37+ // called by qtmir
38+ void onScreenAboutToBeRemoved(QScreen *screen);
39+
40+private Q_SLOTS:
41+ void onScreenAdded(QScreen*);
42+
43+private:
44+ void setupQmlEngine(bool isMirServer);
45+ ApplicationArguments m_qmlArgs;
46+ QScopedPointer<ShellView> m_shellView;
47+ QScopedPointer<SecondaryWindow> m_secondaryWindow;
48+ QScopedPointer<MouseTouchAdaptor> m_mouseTouchAdaptor;
49+ QQmlEngine *m_qmlEngine;
50+};
51+
52+#endif // SHELLAPPLICATION_H
src/ShellView.cppnew file+36
@@ -0,0 +1,36 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#include "ShellView.h"
18+
19+// Qt
20+#include <QQmlContext>
21+
22+// local
23+#include <paths.h>
24+
25+ShellView::ShellView(QQmlEngine *engine, QObject *qmlArgs)
26+ : QQuickView(engine, nullptr)
27+{
28+ setResizeMode(QQuickView::SizeRootObjectToView);
29+ setColor("black");
30+ setTitle(QStringLiteral("Unity8"));
31+
32+ rootContext()->setContextProperty(QStringLiteral("applicationArguments"), qmlArgs);
33+
34+ QUrl source(::qmlDirectory() + "/OrientedShell.qml");
35+ setSource(source);
36+}
src/ShellView.hnew file+30
@@ -0,0 +1,30 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#ifndef UNITY_SHELL_VIEW_H
18+#define UNITY_SHELL_VIEW_H
19+
20+#include <QQuickView>
21+
22+class ShellView : public QQuickView
23+{
24+ Q_OBJECT
25+
26+public:
27+ ShellView(QQmlEngine *engine, QObject *qmlArgs);
28+};
29+
30+#endif // UNITY_SHELL_VIEW_H
src/main.cpp+2−101
@@ -14,26 +14,8 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−// Qt
18−#include <QCommandLineParser>
19−#include <QtQuick/QQuickView>
20−#include <QtGui/QGuiApplication>
21−#include <QtQml/QQmlEngine>
22−#include <QtQml/QQmlContext>
23−#include <QLibrary>
24−#include <QDebug>
25−#include <csignal>
26−#include <libintl.h>
27−
28−// libandroid-properties
29−#include <hybris/properties/properties.h>
30−
3117// local
32−#include <paths.h>
33−#include "MouseTouchAdaptor.h"
34−#include "ApplicationArguments.h"
35−#include "CachingNetworkManagerFactory.h"
36−#include "UnityCommandLineParser.h"
18+#include "ShellApplication.h"
3719
3820int main(int argc, const char *argv[])
3921{
@@ -43,91 +25,10 @@ int main(int argc, const char *argv[])
4325 isMirServer = true;
4426 }
4527
46− QGuiApplication::setApplicationName(QStringLiteral("unity8"));
47− QGuiApplication *application;
48−
49− application = new QGuiApplication(argc, (char**)argv);
50−
51− UnityCommandLineParser parser(*application);
52−
53− ApplicationArguments qmlArgs;
54−
55− if (!parser.deviceName().isEmpty()) {
56− qmlArgs.setDeviceName(parser.deviceName());
57− } else {
58− char buffer[200];
59− property_get("ro.product.device", buffer /* value */, "desktop" /* default_value*/);
60− qmlArgs.setDeviceName(QString(buffer));
61− }
62−
63− qmlArgs.setMode(parser.mode());
64−
65− // The testability driver is only loaded by QApplication but not by QGuiApplication.
66− // However, QApplication depends on QWidget which would add some unneeded overhead => Let's load the testability driver on our own.
67− if (parser.hasTestability() || getenv("QT_LOAD_TESTABILITY")) {
68− QLibrary testLib(QStringLiteral("qttestability"));
69− if (testLib.load()) {
70− typedef void (*TasInitialize)(void);
71− TasInitialize initFunction = (TasInitialize)testLib.resolve("qt_testability_init");
72− if (initFunction) {
73− initFunction();
74− } else {
75− qCritical("Library qttestability resolve failed!");
76− }
77− } else {
78− qCritical("Library qttestability load failed!");
79− }
80− }
81−
82− bindtextdomain("unity8", translationDirectory().toUtf8().data());
83− textdomain("unity8");
84−
85− QQuickView* view = new QQuickView();
86− view->setResizeMode(QQuickView::SizeRootObjectToView);
87− view->setColor("black");
88− view->setTitle(QStringLiteral("Unity8 Shell"));
89−
90− if (parser.windowGeometry().isValid()) {
91− view->setWidth(parser.windowGeometry().width());
92− view->setHeight(parser.windowGeometry().height());
93− }
94−
95− view->engine()->setBaseUrl(QUrl::fromLocalFile(::qmlDirectory()));
96− view->rootContext()->setContextProperty(QStringLiteral("applicationArguments"), &qmlArgs);
97− if (parser.hasFrameless()) {
98− view->setFlags(Qt::FramelessWindowHint);
99− }
100−
101− // You will need this if you want to interact with touch-only components using a mouse
102− // Needed only when manually testing on a desktop.
103− MouseTouchAdaptor *mouseTouchAdaptor = 0;
104− if (parser.hasMouseToTouch()) {
105− mouseTouchAdaptor = MouseTouchAdaptor::instance();
106− }
107−
108− QUrl source(::qmlDirectory() + "/OrientedShell.qml");
109− prependImportPaths(view->engine(), ::overrideImportPaths());
110− if (!isMirServer) {
111− prependImportPaths(view->engine(), ::nonMirImportPaths());
112− }
113− appendImportPaths(view->engine(), ::fallbackImportPaths());
114−
115− CachingNetworkManagerFactory *managerFactory = new CachingNetworkManagerFactory();
116− view->engine()->setNetworkAccessManagerFactory(managerFactory);
117−
118− view->setSource(source);
119− QObject::connect(view->engine(), &QQmlEngine::quit, application, &QGuiApplication::quit);
120−
121− if (isMirServer || parser.hasFullscreen()) {
122− view->showFullScreen();
123− } else {
124− view->show();
125− }
28+ ShellApplication *application = new ShellApplication(argc, (char**)argv, isMirServer);
12629
12730 int result = application->exec();
12831
129− delete view;
130− delete mouseTouchAdaptor;
13132 delete application;
13233
13334 return result;
tests/qmltests/CMakeLists.txt+1
@@ -2,6 +2,7 @@
22add_subdirectory(Components)
33
44add_unity8_qmltest(. OrientedShell LIGHTDM)
5+add_unity8_qmltest(. SecondaryDisplay)
56add_unity8_qmltest(. Shell LIGHTDM)
67add_unity8_qmltest(. ShellWithPin LIGHTDM)
78add_unity8_qmltest(Components Background)
tests/qmltests/tst_SecondaryDisplay.qmlnew file+37
@@ -0,0 +1,37 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.4
18+import QtTest 1.0
19+import Unity.Test 0.1
20+import "../../qml"
21+
22+
23+Item {
24+ id: root
25+ width: units.gu(70)
26+ height: units.gu(70)
27+
28+ SecondaryDisplay {
29+ anchors.fill: parent
30+ }
31+
32+ UnityTestCase {
33+ id: testCase
34+ name: "SecondaryDisplay"
35+ when: windowShown
36+ }
37+}