on xenial help sign in
multiple shell instances
commita706fb00467148793fa8d4220c4e4e45f43f94e4 authorNick Dedekind <nick.dedekind@canonical.com> dateThu 12 Jan 2017, 18:36 (10 years ago) parent795acac
21 files changed+206−332
qml/Components/VirtualTouchPad.qml+3−8 qml/DisabledScreenNotice.qml+2−1 qml/OrientedShell.qml+6−9 qml/Shell.qml+1−1 qml/ShellApplication.qml+47 qml/ShellNotifier.qml+1−2 qml/ShellScreen.qml+63 src/ApplicationArguments.cpp+11−2 src/ApplicationArguments.h+16−15 src/CMakeLists.txt−2 src/SecondaryWindow.cpp−40 src/SecondaryWindow.h−30 src/ShellApplication.cpp+29−107 src/ShellApplication.h+2−14 src/ShellView.cpp−63 src/ShellView.h−34 src/UnityCommandLineParser.h+1−1 tests/mocks/Unity/InputInfo/mockcontroller.cpp+2−1 tests/mocks/Unity/Screens/plugin.cpp+9−1 tests/qmltests/tst_OrientedShell.qml+7−1 tests/qmltests/tst_Shell.qml+6
qml/Components/VirtualTouchPad.qml+3−8
@@ -25,14 +25,13 @@ import "../Components"
2525Item {
2626 id: root
2727
28− Component.onCompleted: UInput.createMouse()
29− Component.onDestruction: UInput.removeMouse()
30−
3128 Component.onCompleted: {
29+ UInput.createMouse();
3230 if (!settings.touchpadTutorialHasRun) {
3331 root.runTutorial()
3432 }
3533 }
34+ Component.onDestruction: UInput.removeMouse()
3635
3736 function runTutorial() {
3837 // If the tutorial animation is started too early, e.g. in Component.onCompleted,
@@ -238,14 +237,10 @@ Item {
238237 }
239238 }
240239
241− Screens {
242− id: screens
243− }
244−
245240 InputMethod {
246241 id: inputMethod
247242 // Don't resize when there is only one screen to avoid resize clashing with the InputMethod in the Shell.
248− enabled: screens.count > 1 && settings.oskEnabled && !tutorial.running
243+ enabled: Screens.count > 1 && settings.oskEnabled && !tutorial.running
249244 objectName: "inputMethod"
250245 anchors.fill: parent
251246 }
qml/DisabledScreenNotice.qml+2−1
@@ -28,8 +28,9 @@ Item {
2828 property var screen: Screen
2929 property var orientationLock: OrientationLock
3030
31+ property alias deviceConfiguration: _deviceConfiguration
3132 DeviceConfiguration {
32− id: deviceConfiguration
33+ id: _deviceConfiguration
3334 name: applicationArguments.deviceName
3435 }
3536
qml/OrientedShell.qml+6−9
@@ -32,15 +32,16 @@ Item {
3232 implicitWidth: units.gu(40)
3333 implicitHeight: units.gu(71)
3434
35+ property alias deviceConfiguration: _deviceConfiguration
36+ property alias orientations: d.orientations
37+
3538 onWidthChanged: calculateUsageMode();
3639
3740 DeviceConfiguration {
38− id: deviceConfiguration
41+ id: _deviceConfiguration
3942 name: applicationArguments.deviceName
4043 }
4144
42− property alias orientations: d.orientations
43−
4445 Item {
4546 id: d
4647
@@ -151,10 +152,6 @@ Item {
151152 return false;
152153 }
153154
154− Screens {
155− id: screens
156− }
157−
158155 property int orientation
159156 onPhysicalOrientationChanged: {
160157 if (!orientationLocked) {
@@ -252,7 +249,7 @@ Item {
252249
253250 Shell {
254251 id: shell
255− objectName: "shell"
252+ objectName: "shell-"+screenWindow.objectName
256253 width: root.width
257254 height: root.height
258255 orientation: root.angleToOrientation(orientationAngle)
@@ -265,7 +262,7 @@ Item {
265262 // have multiple keyboards around. For now we only enable one keyboard at a time
266263 // thus hiding it here if there is a physical one around or if we have a second
267264 // screen (the virtual touchpad & osk on the phone) attached.
268− oskEnabled: (keyboardsModel.count === 0 && screens.count === 1) ||
265+ oskEnabled: (keyboardsModel.count === 0 && Screens.count === 1) ||
269266 forceOSKEnabled
270267
271268 usageScenario: {
qml/Shell.qml+1−1
@@ -1,4 +1,4 @@
1−/*
1+/*
22 * Copyright (C) 2013-2016 Canonical, Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
qml/ShellApplication.qmlnew file+47
@@ -0,0 +1,47 @@
1+/*
2+* Copyright (C) 2016 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 QtQuick.Window 2.2
19+import Unity.Screens 0.1
20+
21+Instantiator {
22+ id: root
23+ model: Screens
24+
25+ ShellScreen {
26+ id: screen
27+ objectName: "screen"+index
28+ screen: model.screen
29+ visibility: applicationArguments.hasFullscreen ? Window.FullScreen : Window.Windowed
30+ flags: applicationArguments.hasFrameless ? Qt.FramelessWindowHint : 0
31+
32+ Binding {
33+ when: applicationArguments.hasGeometry
34+ target: screen
35+ property: "width"
36+ value: applicationArguments.windowGeometry.width
37+ }
38+ Binding {
39+ when: applicationArguments.hasGeometry
40+ target: screen
41+ property: "height"
42+ value: applicationArguments.windowGeometry.height
43+ }
44+
45+ primary: index == 0
46+ }
47+}
qml/ShellNotifier.qml+1−2
@@ -23,9 +23,8 @@ import QtQuick 2.4
2323
2424QtObject {
2525 property var greeter: QtObject {
26− signal show()
2726 signal hide(bool now)
2827
29− property bool shown: false
28+ property bool shown: true
3029 }
3130}
qml/ShellScreen.qmlnew file+63
@@ -0,0 +1,63 @@
1+/*
2+* Copyright (C) 2016 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 Unity.Screens 0.1
20+import Cursor 1.1
21+import "Components"
22+
23+ScreenWindow {
24+ id: screenWindow
25+
26+ color: "black"
27+ title: "Unity8 Shell"
28+ property bool primary: false
29+
30+ DeviceConfiguration {
31+ id: deviceConfiguration
32+ name: applicationArguments.deviceName
33+ }
34+
35+ Loader {
36+ width: screenWindow.width
37+ height: screenWindow.height
38+
39+ sourceComponent: {
40+ if (Screens.count > 1 && primary && deviceConfiguration.category !== "desktop") {
41+ return disabledScreenComponent;
42+ }
43+ return shellComponent;
44+ }
45+ }
46+
47+ Component {
48+ id: shellComponent
49+ OrientedShell {
50+ implicitWidth: screenWindow.width
51+ implicitHeight: screenWindow.height
52+
53+ deviceConfiguration {
54+ name: Screens.count > 1 ? "desktop" : applicationArguments.deviceName
55+ }
56+ }
57+ }
58+
59+ Component {
60+ id: disabledScreenComponent
61+ DisabledScreenNotice {}
62+ }
63+}
src/ApplicationArguments.cpp+11−2
@@ -16,7 +16,16 @@
1616
1717#include "ApplicationArguments.h"
1818
19−ApplicationArguments::ApplicationArguments(QObject *parent)
20− : QObject(parent)
19+ApplicationArguments::ApplicationArguments(QCoreApplication *app)
20+ : QObject(app)
21+ , UnityCommandLineParser(*app)
2122{
2223}
24+
25+void ApplicationArguments::setDeviceName(const QString &deviceName)
26+{
27+ if (deviceName != m_deviceName) {
28+ m_deviceName = deviceName;
29+ Q_EMIT deviceNameChanged(m_deviceName);
30+ }
31+}
src/ApplicationArguments.h+16−15
@@ -23,31 +23,32 @@
2323#include <QSize>
2424#include <QString>
2525
26−class ApplicationArguments : public QObject
26+#include "UnityCommandLineParser.h"
27+
28+class ApplicationArguments : public QObject,
29+ public UnityCommandLineParser
2730{
2831 Q_OBJECT
2932 Q_PROPERTY(QString deviceName READ deviceName NOTIFY deviceNameChanged)
3033 Q_PROPERTY(QString mode READ mode CONSTANT)
34+
35+ Q_PROPERTY(bool hasGeometry READ hasGeometry CONSTANT)
36+ Q_PROPERTY(QSize windowGeometry READ windowGeometry CONSTANT)
37+ Q_PROPERTY(bool hasTestability READ hasTestability CONSTANT)
38+ Q_PROPERTY(bool hasFrameless READ hasFrameless CONSTANT)
39+#ifdef UNITY8_ENABLE_TOUCH_EMULATION
40+ Q_PROPERTY(bool hasMouseToTouch READ hasMouseToTouch CONSTANT)
41+#endif
42+
3143public:
32− ApplicationArguments(QObject *parent = nullptr);
44+ ApplicationArguments(QCoreApplication *app);
3345
34− void setDeviceName(const QString &deviceName) {
35− if (deviceName != m_deviceName) {
36− m_deviceName = deviceName;
37− Q_EMIT deviceNameChanged(m_deviceName);
38− }
39− }
40− QString deviceName() const { return m_deviceName; }
46+ void setDeviceName(const QString &deviceName);
4147
42− void setMode(const QString &mode) { m_mode = mode; }
43− QString mode() const { return m_mode; }
48+ bool hasGeometry() const { return m_windowGeometry.isValid(); }
4449
4550Q_SIGNALS:
4651 void deviceNameChanged(const QString&);
47−
48−private:
49− QString m_deviceName;
50− QString m_mode;
5152};
5253
5354#endif // APPLICATION_ARGUMENTS_H
src/CMakeLists.txt−2
@@ -20,9 +20,7 @@ set(SOURCE_FILES
2020 ApplicationArguments.cpp
2121 main.cpp
2222 CachingNetworkManagerFactory.cpp
23− SecondaryWindow.cpp
2423 ShellApplication.cpp
25− ShellView.cpp
2624 UnityCommandLineParser.cpp
2725 UnixSignalHandler.cpp
2826 ${QML_FILES} # This is to make qml and image files appear in the IDE's project tree
src/SecondaryWindow.cppdeleted−40
@@ -1,40 +0,0 @@
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−#include <QQmlContext>
23−
24−SecondaryWindow::SecondaryWindow(QQmlEngine *engine)
25− : QQuickView(engine, nullptr)
26−{
27− QByteArray pxpguEnv = qgetenv("GRID_UNIT_PX");
28− bool ok;
29− int pxpgu = pxpguEnv.toInt(&ok);
30− if (!ok) {
31− pxpgu = 8;
32− }
33− engine->rootContext()->setContextProperty(QStringLiteral("internalGu"), pxpgu);
34− setResizeMode(QQuickView::SizeRootObjectToView);
35− setColor("black");
36− setTitle(QStringLiteral("Unity8 Shell - Secondary Screen"));
37−
38− QUrl source(::qmlDirectory() + "/DisabledScreenNotice.qml");
39− setSource(source);
40−}
src/SecondaryWindow.hdeleted−30
@@ -1,30 +0,0 @@
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.cpp+29−107
@@ -20,6 +20,7 @@
2020#include <QLibrary>
2121#include <QProcess>
2222#include <QScreen>
23+#include <QQmlContext>
2324
2425#include <libintl.h>
2526
@@ -33,31 +34,23 @@
3334
3435ShellApplication::ShellApplication(int & argc, char ** argv, bool isMirServer)
3536 : QGuiApplication(argc, argv)
37+ , m_qmlArgs(this)
3638{
3739
3840 setApplicationName(QStringLiteral("unity8"));
3941 setOrganizationName(QStringLiteral("Canonical"));
4042
41− connect(this, &QGuiApplication::screenAdded, this, &ShellApplication::onScreenAdded);
42−
4343 setupQmlEngine(isMirServer);
4444
45− UnityCommandLineParser parser(*this);
46−
47− if (!parser.deviceName().isEmpty()) {
48− m_deviceName = parser.deviceName();
49− } else {
45+ if (m_qmlArgs.deviceName().isEmpty()) {
5046 char buffer[200];
5147 property_get("ro.product.device", buffer /* value */, "desktop" /* default_value*/);
52− m_deviceName = QString(buffer);
48+ m_qmlArgs.setDeviceName(QString(buffer));
5349 }
54− m_qmlArgs.setDeviceName(m_deviceName);
55−
56− m_qmlArgs.setMode(parser.mode());
5750
5851 // The testability driver is only loaded by QApplication but not by QGuiApplication.
5952 // However, QApplication depends on QWidget which would add some unneeded overhead => Let's load the testability driver on our own.
60− if (parser.hasTestability() || getenv("QT_LOAD_TESTABILITY")) {
53+ if (m_qmlArgs.hasTestability() || getenv("QT_LOAD_TESTABILITY")) {
6154 QLibrary testLib(QStringLiteral("qttestability"));
6255 if (testLib.load()) {
6356 typedef void (*TasInitialize)(void);
@@ -75,57 +68,39 @@ ShellApplication::ShellApplication(int & argc, char ** argv, bool isMirServer)
7568 bindtextdomain("unity8", translationDirectory().toUtf8().data());
7669 textdomain("unity8");
7770
78− m_shellView = new ShellView(m_qmlEngine, &m_qmlArgs);
71+ m_qmlEngine->rootContext()->setContextProperty(QStringLiteral("applicationArguments"), &m_qmlArgs);
7972
80− if (parser.windowGeometry().isValid()) {
81− m_shellView->setWidth(parser.windowGeometry().width());
82− m_shellView->setHeight(parser.windowGeometry().height());
73+ QByteArray pxpguEnv = qgetenv("GRID_UNIT_PX");
74+ bool ok;
75+ int pxpgu = pxpguEnv.toInt(&ok);
76+ if (!ok) {
77+ pxpgu = 8;
8378 }
84−
85− if (parser.hasFrameless()) {
86− m_shellView->setFlags(Qt::FramelessWindowHint);
87− }
88−
79+ m_qmlEngine->rootContext()->setContextProperty("internalGu", pxpgu);
80+ m_qmlEngine->load(::qmlDirectory() + "/ShellApplication.qml");
8981
9082 #ifdef UNITY8_ENABLE_TOUCH_EMULATION
9183 // You will need this if you want to interact with touch-only components using a mouse
9284 // Needed only when manually testing on a desktop.
93− if (parser.hasMouseToTouch()) {
85+ if (m_qmlArgs.hasMouseToTouch()) {
9486 m_mouseTouchAdaptor = MouseTouchAdaptor::instance();
9587 }
9688 #endif
9789
98−
99− // Some hard-coded policy for now.
100− // NB: We don't support more than two screens at the moment
101− //
102− // TODO: Support an arbitrary number of screens and different policies
103− // (eg cloned desktop, several desktops, etc)
104− if (isMirServer && screens().count() == 2) {
105− m_shellView->setScreen(screens().at(1));
106− m_qmlArgs.setDeviceName(QStringLiteral("desktop"));
107−
108− m_secondaryWindow = new SecondaryWindow(m_qmlEngine);
109− m_secondaryWindow->setScreen(screens().at(0));
110− // QWindow::showFullScreen() also calls QWindow::requestActivate() and we don't want that!
111− m_secondaryWindow->setWindowState(Qt::WindowFullScreen);
112− m_secondaryWindow->setVisible(true);
113− }
114−
115− if (parser.mode().compare("greeter") == 0) {
116− QSize primaryScreenSize = this->primaryScreen()->size();
117− m_shellView->setHeight(primaryScreenSize.height());
118− m_shellView->setWidth(primaryScreenSize.width());
119− m_shellView->show();
120− m_shellView->requestActivate();
121− if (!QProcess::startDetached("initctl emit --no-wait unity8-greeter-started")) {
122− qDebug() << "Unable to send unity8-greeter-started event to Upstart";
123− }
124− } else if (isMirServer || parser.hasFullscreen()) {
125− m_shellView->showFullScreen();
126− } else {
127− m_shellView->show();
128− }
90+// if (parser.mode().compare("greeter") == 0) {
91+// QSize primaryScreenSize = this->primaryScreen()->size();
92+// m_shellView->setHeight(primaryScreenSize.height());
93+// m_shellView->setWidth(primaryScreenSize.width());
94+// m_shellView->show();
95+// m_shellView->requestActivate();
96+// if (!QProcess::startDetached("/sbin/initctl emit --no-wait unity8-greeter-started")) {
97+// qDebug() << "Unable to send unity8-greeter-started event to Upstart";
98+// }
99+// } else if (isMirServer || parser.hasFullscreen()) {
100+// m_shellView->showFullScreen();
101+// } else {
102+// m_shellView->show();
103+// }
129104}
130105
131106ShellApplication::~ShellApplication()
@@ -135,14 +110,6 @@ ShellApplication::~ShellApplication()
135110
136111void ShellApplication::destroyResources()
137112{
138− // Deletion order is important. Don't use QScopedPointers and the like
139− // Otherwise the process will hang on shutdown (bug somewhere I guess).
140− delete m_shellView;
141− m_shellView = nullptr;
142−
143− delete m_secondaryWindow;
144− m_secondaryWindow = nullptr;
145−
146113 #ifdef UNITY8_ENABLE_TOUCH_EMULATION
147114 delete m_mouseTouchAdaptor;
148115 m_mouseTouchAdaptor = nullptr;
@@ -154,7 +121,7 @@ void ShellApplication::destroyResources()
154121
155122void ShellApplication::setupQmlEngine(bool isMirServer)
156123{
157− m_qmlEngine = new QQmlEngine(this);
124+ m_qmlEngine = new QQmlApplicationEngine(this);
158125
159126 m_qmlEngine->setBaseUrl(QUrl::fromLocalFile(::qmlDirectory()));
160127
@@ -168,48 +135,3 @@ void ShellApplication::setupQmlEngine(bool isMirServer)
168135
169136 QObject::connect(m_qmlEngine, &QQmlEngine::quit, this, &QGuiApplication::quit);
170137}
171−
172−void ShellApplication::onScreenAdded(QScreen * /*screen*/)
173−{
174− // TODO: Support an arbitrary number of screens and different policies
175− // (eg cloned desktop, several desktops, etc)
176− if (screens().count() == 2) {
177− m_shellView->setScreen(screens().at(1));
178− m_qmlArgs.setDeviceName(QStringLiteral("desktop"));
179− // Changing the QScreen where a QWindow is drawn makes it also lose focus (besides having
180− // its backing QPlatformWindow recreated). So lets refocus it.
181− m_shellView->requestActivate();
182− // QWindow::destroy() is called when it changes between screens. We have to manually make it visible again
183− // <dandrader> This bug is supposedly fixed in Qt 5.5.1, although I can still reproduce it there. :-/
184− m_shellView->setVisible(true);
185−
186− m_secondaryWindow = new SecondaryWindow(m_qmlEngine);
187− m_secondaryWindow->setScreen(screens().at(0));
188−
189− // QWindow::showFullScreen() also calls QWindow::requestActivate() and we don't want that!
190− m_secondaryWindow->setWindowState(Qt::WindowFullScreen);
191− m_secondaryWindow->setVisible(true);
192− }
193−}
194−
195−void ShellApplication::onScreenAboutToBeRemoved(QScreen *screen)
196−{
197− // TODO: Support an arbitrary number of screens and different policies
198− // (eg cloned desktop, several desktops, etc)
199− if (screen == m_shellView->screen()) {
200− const QList<QScreen *> allScreens = screens();
201− Q_ASSERT(allScreens.count() > 1);
202− Q_ASSERT(allScreens.at(0) != screen);
203− Q_ASSERT(m_secondaryWindow);
204− delete m_secondaryWindow;
205− m_secondaryWindow = nullptr;
206− m_shellView->setScreen(allScreens.first());
207− m_qmlArgs.setDeviceName(m_deviceName);
208− // Changing the QScreen where a QWindow is drawn makes it also lose focus (besides having
209− // its backing QPlatformWindow recreated). So lets refocus it.
210− m_shellView->requestActivate();
211− // QWindow::destroy() is called when it changes between screens. We have to manually make it visible again
212− // <dandrader> This bug is supposedly fixed in Qt 5.5.1, although I can still reproduce it there. :-/
213− m_shellView->setVisible(true);
214− }
215−}
src/ShellApplication.h+2−14
@@ -18,7 +18,7 @@
1818#define SHELLAPPLICATION_H
1919
2020#include <QGuiApplication>
21−#include <QQmlEngine>
21+#include <QQmlApplicationEngine>
2222#include <QQuickView>
2323#include <QScopedPointer>
2424
@@ -28,9 +28,6 @@
2828#include "MouseTouchAdaptor.h"
2929#endif
3030
31−#include "SecondaryWindow.h"
32−#include "ShellView.h"
33−
3431class ShellApplication : public QGuiApplication
3532{
3633 Q_OBJECT
@@ -39,25 +36,16 @@ public:
3936 virtual ~ShellApplication();
4037
4138 void destroyResources();
42−public Q_SLOTS:
43− // called by qtmir
44− void onScreenAboutToBeRemoved(QScreen *screen);
45−
46−private Q_SLOTS:
47− void onScreenAdded(QScreen*);
4839
4940private:
5041 void setupQmlEngine(bool isMirServer);
51− QString m_deviceName;
5242 ApplicationArguments m_qmlArgs;
53− ShellView *m_shellView{nullptr};
54− SecondaryWindow *m_secondaryWindow{nullptr};
5543
5644 #ifdef UNITY8_ENABLE_TOUCH_EMULATION
5745 MouseTouchAdaptor *m_mouseTouchAdaptor{nullptr};
5846 #endif
5947
60− QQmlEngine *m_qmlEngine{nullptr};
48+ QQmlApplicationEngine *m_qmlEngine{nullptr};
6149};
6250
6351#endif // SHELLAPPLICATION_H
src/ShellView.cppdeleted−63
@@ -1,63 +0,0 @@
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−#include <QQuickItem>
22−
23−// local
24−#include <paths.h>
25−
26−ShellView::ShellView(QQmlEngine *engine, QObject *qmlArgs)
27− : QQuickView(engine, nullptr)
28−{
29− setResizeMode(QQuickView::SizeRootObjectToView);
30− setColor("black");
31− setTitle(QStringLiteral("Unity8"));
32−
33− rootContext()->setContextProperty(QStringLiteral("applicationArguments"), qmlArgs);
34−
35− QUrl source(::qmlDirectory() + "/OrientedShell.qml");
36− setSource(source);
37−
38− connect(this, &QWindow::widthChanged, this, &ShellView::onWidthChanged);
39− connect(this, &QWindow::heightChanged, this, &ShellView::onHeightChanged);
40−}
41−
42−void ShellView::onWidthChanged(int w)
43−{
44− // For good measure in case SizeRootObjectToView doesn't fulfill its promise.
45− //
46− // There's at least one situation that's know to leave the root object with an outdated size.
47− // (really looks like Qt bug)
48− // Happens when starting unity8 with an external monitor already connected.
49− // The QResizeEvent we get still has the size of the first screen and since the resize move is triggered
50− // from the resize event handler, the root item doesn't get resized.
51− // TODO: Confirm the Qt bug and submit a patch upstream
52− if (rootObject()) {
53− rootObject()->setWidth(w);
54− }
55−}
56−
57−void ShellView::onHeightChanged(int h)
58−{
59− // See comment in ShellView::onWidthChanged()
60− if (rootObject()) {
61− rootObject()->setHeight(h);
62− }
63−}
src/ShellView.hdeleted−34
@@ -1,34 +0,0 @@
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−private Q_SLOTS:
30− void onWidthChanged(int);
31− void onHeightChanged(int);
32−};
33−
34−#endif // UNITY_SHELL_VIEW_H
src/UnityCommandLineParser.h+1−1
@@ -36,8 +36,8 @@ public:
3636 bool hasFullscreen() const { return m_hasFullscreen; }
3737 QString deviceName() const { return m_deviceName; }
3838 QString mode() const { return m_mode; }
39−private:
4039
40+protected:
4141 int parsePixelsValue(const QString &str);
4242 static float getenvFloat(const char* name, float defaultValue);
4343 void resolveMode(QCommandLineParser &parser, QCommandLineOption &modeOption);
tests/mocks/Unity/InputInfo/mockcontroller.cpp+2−1
@@ -18,10 +18,11 @@
1818
1919#include "qinputdeviceinfo_mock_p.h"
2020
21+#include <QQuickView>
22+
2123MockController::MockController(QObject *parent):
2224 QObject(parent)
2325{
24−
2526}
2627
2728MockController *MockController::instance()
tests/mocks/Unity/Screens/plugin.cpp+9−1
@@ -20,13 +20,21 @@
2020
2121#include <QScreen>
2222
23+namespace {
24+QObject* screensSingleton(QQmlEngine* engine, QJSEngine* scriptEngine) {
25+ Q_UNUSED(engine);
26+ Q_UNUSED(scriptEngine);
27+ return new Screens();
28+}
29+}
30+
2331void UnityScreensPlugin::registerTypes(const char* uri)
2432{
2533 Q_ASSERT(QLatin1String(uri) == QLatin1String("Unity.Screens"));
2634
2735 qRegisterMetaType<QScreen*>("QScreen*");
2836
29− qmlRegisterType<Screens>(uri, 0, 1, "Screens");
37+ qmlRegisterSingletonType<Screens>(uri, 0, 1, "Screens", screensSingleton);
3038 qmlRegisterType<ScreenWindow>(uri, 0, 1, "ScreenWindow");
3139 qmlRegisterRevision<QWindow,1>(uri, 0, 1);
3240}
tests/qmltests/tst_OrientedShell.qml+7−1
@@ -74,6 +74,12 @@ Rectangle {
7474 deviceFilter: InputInfo.Keyboard
7575 }
7676
77+ QtObject {
78+ id: _screenWindow
79+ property bool primary: true
80+ }
81+ property alias screenWindow: _screenWindow
82+
7783 property int physicalOrientation0
7884 property int physicalOrientation90
7985 property int physicalOrientation180
@@ -442,7 +448,7 @@ Rectangle {
442448
443449 onOrientedShellChanged: {
444450 if (orientedShell) {
445− panelState = findInvisibleChild(shell, "panelState");
451+ panelState = findInvisibleChild(orientedShell, "panelState");
446452 } else {
447453 panelState = undefined;
448454 }
tests/qmltests/tst_Shell.qml+6
@@ -65,6 +65,12 @@ Rectangle {
6565 property var topLevelSurfaceList: null
6666 property var panelState: undefined
6767
68+ QtObject {
69+ id: _screenWindow
70+ property bool primary: false
71+ }
72+ property alias screenWindow: _screenWindow
73+
6874 Item {
6975 id: shellContainer
7076 anchors.left: root.left