on xenial help sign in
Changes to make it work on "Qt compositor" mode

- Use "mirserver" QPA instead of "ubuntumirserver - Drop unity-mir lib usage ("mirserver" QPA has all that previously was in unity-mir) - Use Mir.Application module (from mirserver) instead of Unity.Application (from ubuntumirserver) - Drop all hacks from the old architecture, such as InputFilterArea and OSKController. They are not needed in the "Qt compositor" architecture

commit6f37b4cee81de279d0db13c54e92bab1e09845b7 authorDaniel d'Andrada <daniel.dandrada@canonical.com> dateMon 19 May 2014, 10:07 (12 years ago) parent1564e33
10 files changed+204−288
debian/control−1 qml/Components/EdgeDemoOverlay.qml+1−1 qml/Components/InputMethod.qml+98 qml/Dash/Apps/RunningApplicationTile.qml+1−1 qml/Dash/Apps/RunningApplicationsGrid.qml+1−1 qml/Dash/DashApps.qml+1−1 qml/Dash/GenericScopeView.qml+1−1 qml/Shell.qml+91−218 src/CMakeLists.txt−3 src/main.cpp+10−61
debian/control−1
@@ -18,7 +18,6 @@ Build-Depends: cmake,
1818 libqmenumodel-dev (>= 0.2.7),
1919 libqt5xmlpatterns5-dev,
2020 libunity-api-dev (>= 7.80.6),
21− libunity-mir-dev,
2221 libusermetricsoutput1-dev,
2322 libxcb1-dev,
2423 pkg-config,
qml/Components/EdgeDemoOverlay.qml+1−1
@@ -17,7 +17,7 @@
1717import Powerd 0.1
1818import QtQuick 2.0
1919import QtGraphicalEffects 1.0
20−import Unity.Application 0.1
20+import Mir.Application 0.1
2121import Ubuntu.Components 0.1
2222
2323Showable {
qml/Components/InputMethod.qmlnew file+98
@@ -0,0 +1,98 @@
1+/*
2+ * Copyright (C) 2014 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 Mir.Application 0.1
19+import Ubuntu.Components 0.1
20+
21+Item {
22+ id: root
23+
24+ property var surface: null
25+
26+ property int transitionDuration: UbuntuAnimation.FastDuration
27+
28+ state: {
29+ if (surface && surface.state == MirSurfaceItem.Maximized) {
30+ return "shown";
31+ } else {
32+ return "hidden";
33+ }
34+ }
35+
36+ states: [
37+ State {
38+ name: "shown"
39+ PropertyChanges {
40+ target: root
41+ visible: true
42+ y: 0
43+ }
44+ },
45+ State {
46+ name: "hidden"
47+ PropertyChanges {
48+ target: root
49+ visible: false
50+ // half-way down because the vkb occupies only the lower half of the surface
51+ // TODO: consider keyboard rotation
52+ y: root.parent.height / 2.0
53+ }
54+ }
55+ ]
56+
57+ transitions: [
58+ Transition {
59+ from: "*"; to: "*"
60+ PropertyAction { property: "visible"; value: true }
61+ UbuntuNumberAnimation { property: "y"; duration: transitionDuration }
62+ }
63+ ]
64+
65+ Connections {
66+ target: surface
67+ ignoreUnknownSignals: true // don't wanna spam the log when surface is null
68+ onStateChanged: {
69+ if (state == MirSurfaceItem.Minimized) {
70+ root.hide();
71+ } else if (state == MirSurfaceItem.Maximized) {
72+ root.show();
73+ }
74+ }
75+ }
76+
77+ function removeSurface() {
78+ surface.parent = null;
79+ surface.release();
80+ }
81+
82+ onSurfaceChanged: {
83+ if (surface) {
84+ root.width = surface.implicitWidth;
85+ root.height = surface.implicitHeight;
86+ surface.parent = root;
87+ surface.anchors.fill = root;
88+ }
89+ }
90+
91+ Component.onDestruction: {
92+ if (surface) {
93+ surface.parent = null;
94+ surface.release();
95+ surface = null;
96+ }
97+ }
98+}
qml/Dash/Apps/RunningApplicationTile.qml+1−1
@@ -16,7 +16,7 @@
1616
1717import QtQuick 2.0
1818import Ubuntu.Components 0.1
19−import Unity.Application 0.1
19+import Mir.Application 0.1
2020import "../../Components/"
2121import "../../Components/ListItems"
2222
qml/Dash/Apps/RunningApplicationsGrid.qml+1−1
@@ -18,7 +18,7 @@ import QtQuick 2.0
1818import "../../Components"
1919
2020import Ubuntu.Gestures 0.1
21−import Unity.Application 0.1
21+import Mir.Application 0.1
2222
2323ResponsiveFlowView {
2424 id: root
qml/Dash/DashApps.qml+1−1
@@ -17,7 +17,7 @@
1717import QtQuick 2.0
1818import Ubuntu.Components 0.1
1919import Utils 0.1
20−import Unity.Application 0.1
20+import Mir.Application 0.1
2121import "../Components"
2222import "../Components/ListItems"
2323import "Apps"
qml/Dash/GenericScopeView.qml+1−1
@@ -18,7 +18,7 @@ import QtQuick 2.0
1818import Ubuntu.Components 0.1
1919import Utils 0.1
2020import Unity 0.2
21−import Unity.Application 0.1
21+import Mir.Application 0.1
2222import "../Components"
2323import "../Components/ListItems" as ListItems
2424
qml/Shell.qml+91−218
@@ -17,7 +17,7 @@
1717import QtQuick 2.0
1818import AccountsService 0.1
1919import GSettings 1.0
20−import Unity.Application 0.1
20+import Mir.Application 0.1
2121import Ubuntu.Components 0.1
2222import Ubuntu.Gestures 0.1
2323import Unity.Launcher 0.1
@@ -30,6 +30,7 @@ import "Launcher"
3030import "Panel"
3131import "Components"
3232import "Notifications"
33+import "Stages"
3334import Unity.Notifications 1.0 as NotificationBackend
3435
3536FocusScope {
@@ -48,19 +49,14 @@ FocusScope {
4849 property bool dashShown: dash.shown
4950
5051 property bool sideStageEnabled: shell.width >= units.gu(100)
51− readonly property string focusedApplicationId: ApplicationManager.focusedApplicationId
5252
5353 function activateApplication(appId) {
5454 if (ApplicationManager.findApplication(appId)) {
5555 ApplicationManager.requestFocusApplication(appId);
56− stages.show(true);
57− if (stages.locked && ApplicationManager.focusedApplicationId == appId) {
58− applicationsDisplayLoader.item.select(appId);
59− }
6056 } else {
6157 var execFlags = shell.sideStageEnabled ? ApplicationManager.NoFlag : ApplicationManager.ForceMainStage;
6258 ApplicationManager.startApplication(appId, execFlags);
63− stages.show(false);
59+ stages.show();
6460 }
6561 }
6662
@@ -91,87 +87,65 @@ FocusScope {
9187 Keys.onVolumeDownPressed: volumeControl.volumeDown()
9288
9389 Item {
94− id: underlayClipper
90+ id: underlay
91+ objectName: "underlay"
9592 anchors.fill: parent
96− anchors.rightMargin: stages.overlayWidth
97− clip: stages.overlayMode && !stages.painting
9893
99− InputFilterArea {
100− anchors.fill: parent
101− blockInput: parent.clip
102− }
94+ // Whether the underlay is fully covered by opaque UI elements.
95+ property bool fullyCovered: panel.indicators.fullyOpened && shell.width <= panel.indicatorsMenuWidth
10396
104− Item {
105− id: underlay
106− objectName: "underlay"
107− anchors.fill: parent
108− anchors.rightMargin: -parent.anchors.rightMargin
97+ // NB! Application surfaces are stacked behind the shell one. So they can only be seen by the user
98+ // through the translucent parts of the shell surface.
99+ visible: !fullyCovered
109100
110− // Whether the underlay is fully covered by opaque UI elements.
111− property bool fullyCovered: panel.indicators.fullyOpened && shell.width <= panel.indicatorsMenuWidth
101+ CrossFadeImage {
102+ id: backgroundImage
103+ objectName: "backgroundImage"
112104
113− // Whether the user should see the topmost application surface (if there's one at all).
114− readonly property bool applicationSurfaceShouldBeSeen: stages.shown && !stages.painting && !stages.overlayMode
105+ anchors.fill: parent
106+ source: shell.background
107+ fillMode: Image.PreserveAspectCrop
108+ }
115109
116− // NB! Application surfaces are stacked behind the shell one. So they can only be seen by the user
117− // through the translucent parts of the shell surface.
118− visible: !fullyCovered && !applicationSurfaceShouldBeSeen
110+ Rectangle {
111+ anchors.fill: parent
112+ color: "black"
113+ opacity: dash.disappearingAnimationProgress
114+ }
119115
120− CrossFadeImage {
121− id: backgroundImage
122− objectName: "backgroundImage"
116+ Image {
117+ anchors.fill: dash
118+ source: shell.width > shell.height ? "Dash/graphics/paper_landscape.png" : "Dash/graphics/paper_portrait.png"
119+ fillMode: Image.PreserveAspectCrop
120+ horizontalAlignment: Image.AlignRight
121+ verticalAlignment: Image.AlignTop
122+ }
123123
124− anchors.fill: parent
125− source: shell.background
126− fillMode: Image.PreserveAspectCrop
127− }
124+ Dash {
125+ id: dash
126+ objectName: "dash"
128127
129− Rectangle {
130− anchors.fill: parent
131− color: "black"
132− opacity: dash.disappearingAnimationProgress
133− }
128+ available: !greeter.shown && !lockscreen.shown
129+ hides: [stages, launcher, panel.indicators]
130+ shown: disappearingAnimationProgress !== 1.0 && greeterWrapper.showProgress !== 1.0
131+ enabled: disappearingAnimationProgress === 0.0 && greeterWrapper.showProgress === 0.0 && edgeDemo.dashEnabled
134132
135− Image {
136− anchors.fill: dash
137− source: shell.width > shell.height ? "Dash/graphics/paper_landscape.png" : "Dash/graphics/paper_portrait.png"
138− fillMode: Image.PreserveAspectCrop
139− horizontalAlignment: Image.AlignRight
140− verticalAlignment: Image.AlignTop
133+ anchors {
134+ fill: parent
135+ topMargin: panel.panelHeight
141136 }
142137
143− Dash {
144− id: dash
145− objectName: "dash"
146−
147− available: !greeter.shown && !lockscreen.shown
148− hides: [stages, launcher, panel.indicators]
149− shown: disappearingAnimationProgress !== 1.0 && greeterWrapper.showProgress !== 1.0
150− enabled: disappearingAnimationProgress === 0.0 && greeterWrapper.showProgress === 0.0 && edgeDemo.dashEnabled
151−
152− anchors {
153− fill: parent
154− topMargin: panel.panelHeight
155− }
156−
157− contentScale: 1.0 - 0.2 * disappearingAnimationProgress
158− opacity: 1.0 - disappearingAnimationProgress
159− property real disappearingAnimationProgress: {
160− if (stages.overlayMode) {
161− return 0;
162− } else {
163− return stages.showProgress
164− }
165− }
138+ contentScale: 1.0 - 0.2 * disappearingAnimationProgress
139+ opacity: 1.0 - disappearingAnimationProgress
140+ property real disappearingAnimationProgress: stages.showProgress
166141
167− // FIXME: only necessary because stages.showProgress is not animated
168− Behavior on disappearingAnimationProgress { SmoothedAnimation { velocity: 5 }}
169− }
142+ // FIXME: only necessary because stages.showProgress is not animated
143+ Behavior on disappearingAnimationProgress { SmoothedAnimation { velocity: 5 }}
170144 }
171145 }
172146
173147 EdgeDragArea {
174− id: stagesDragHandle
148+ id: stagesDragArea
175149 direction: Direction.Leftwards
176150
177151 anchors { top: parent.top; right: parent.right; bottom: parent.bottom }
@@ -181,99 +155,50 @@ FocusScope {
181155
182156 onTouchXChanged: {
183157 if (status == DirectionalDragArea.Recognized) {
184− if (ApplicationManager.count == 0) {
185− progress = Math.max(stages.width - stagesDragHandle.width + touchX, stages.width * .3)
158+ if (stages.empty) {
159+ progress = Math.max(stages.width - stagesDragArea.width + touchX, stages.width * .3);
186160 } else {
187− progress = stages.width - stagesDragHandle.width + touchX
161+ progress = stages.width - stagesDragArea.width + touchX;
188162 }
189163 }
190164 }
191165
192166 onDraggingChanged: {
193167 if (!dragging) {
194− if (ApplicationManager.count > 0 && progress < stages.width - units.gu(10)) {
195− stages.show(true)
168+ if (!stages.empty && progress < stages.width - units.gu(10)) {
169+ stages.show();
196170 }
197− stagesDragHandle.progress = stages.width;
171+ stagesDragArea.progress = stages.width;
198172 }
199173 }
200174 }
201175
202− Item {
176+ Rectangle {
203177 id: stages
204178 objectName: "stages"
205179 width: parent.width
206180 height: parent.height
181+ color: "khaki"
207182
208− x: {
209− if (shown) {
210− if (overlayMode || locked) {
211− return 0;
212− }
213− return launcher.progress
214− } else {
215− return stagesDragHandle.progress
216− }
217− }
218−
183+ x: shown ? launcher.progress : stagesDragArea.progress
219184 Behavior on x { SmoothedAnimation { velocity: 600; duration: UbuntuAnimation.FastDuration } }
220185
221186 property bool shown: false
222187
223− property real showProgress: overlayMode ? 0 : MathUtils.clamp(1 - x / shell.width, 0, 1)
188+ property real showProgress: MathUtils.clamp(1 - x / shell.width, 0, 1)
224189
225190 property bool fullyShown: x == 0
226191 property bool fullyHidden: x == width
227192
228− property bool painting: applicationsDisplayLoader.item ? applicationsDisplayLoader.item.painting : false
229− property bool fullscreen: applicationsDisplayLoader.item ? applicationsDisplayLoader.item.fullscreen : false
230− property bool overlayMode: applicationsDisplayLoader.item ? applicationsDisplayLoader.item.overlayMode : false
231− property int overlayWidth: applicationsDisplayLoader.item ? applicationsDisplayLoader.item.overlayWidth : false
232− property bool locked: applicationsDisplayLoader.item ? applicationsDisplayLoader.item.locked : false
193+ property bool empty: SurfaceManager.count == 0
233194
234− function show(focusApp) {
195+ function show() {
235196 shown = true;
236− panel.indicators.hide();
237− edgeDemo.stopDemo();
238− greeter.hide();
239− if (!ApplicationManager.focusedApplicationId && ApplicationManager.count > 0 && focusApp) {
240− ApplicationManager.focusApplication(ApplicationManager.get(0).appId);
241− }
197+// panel.indicators.hide();
242198 }
243199
244200 function hide() {
245201 shown = false;
246− if (ApplicationManager.focusedApplicationId) {
247− ApplicationManager.unfocusCurrentApplication();
248− }
249− }
250−
251− Connections {
252− target: ApplicationManager
253−
254− onFocusRequested: {
255− stages.show(true);
256− }
257−
258− onFocusedApplicationIdChanged: {
259− if (ApplicationManager.focusedApplicationId.length > 0) {
260− stages.show(false);
261− } else {
262− if (!stages.overlayMode) {
263− stages.hide();
264− }
265− }
266− }
267−
268− onApplicationAdded: {
269− stages.show(false);
270− }
271−
272− onApplicationRemoved: {
273− if (ApplicationManager.focusedApplicationId.length == 0) {
274− stages.hide();
275− }
276− }
277202 }
278203
279204 Loader {
@@ -284,13 +209,8 @@ FocusScope {
284209
285210 Binding {
286211 target: applicationsDisplayLoader.item
287− property: "moving"
288− value: !stages.fullyShown
289− }
290− Binding {
291− target: applicationsDisplayLoader.item
292− property: "shown"
293− value: stages.shown
212+ property: "surfaces"
213+ value: SurfaceManager
294214 }
295215 Binding {
296216 target: applicationsDisplayLoader.item
@@ -300,6 +220,32 @@ FocusScope {
300220 }
301221 }
302222
223+ InputMethod {
224+ id: inputMethod
225+ }
226+
227+ Connections {
228+ target: SurfaceManager
229+ onSurfaceCreated: {
230+ if (surface.type == MirSurfaceItem.InputMethod) {
231+ inputMethod.surface = surface;
232+ } else {
233+ stages.show();
234+ }
235+ }
236+
237+ onSurfaceDestroyed: {
238+ var orphan = !surface.parent;
239+ if (inputMethod.surface == surface) {
240+ inputMethod.removeSurface(surface);
241+ }
242+ if (orphan) {
243+ // there's no one displaying it. delete it right away
244+ surface.release();
245+ }
246+ }
247+ }
248+
303249 Lockscreen {
304250 id: lockscreen
305251 objectName: "lockscreen"
@@ -419,12 +365,6 @@ FocusScope {
419365 }
420366 }
421367
422− InputFilterArea {
423− anchors.fill: parent
424− blockInput: ApplicationManager.focusedApplicationId.length === 0 || greeter.shown || lockscreen.shown || launcher.shown
425− || panel.indicators.shown
426− }
427−
428368 Connections {
429369 id: powerConnection
430370 target: Powerd
@@ -472,28 +412,9 @@ FocusScope {
472412 }
473413 property string focusedAppId: ApplicationManager.focusedApplicationId
474414 property var focusedApplication: ApplicationManager.findApplication(focusedAppId)
475− fullscreenMode: focusedApplication && stages.fullscreen && !greeter.shown && !lockscreen.shown
415+ //fullscreenMode: focusedApplication && stages.fullscreen && !greeter.shown && !lockscreen.shown
416+ fullscreenMode: focusedApplication && !greeter.shown && !lockscreen.shown
476417 searchVisible: !greeter.shown && !lockscreen.shown && dash.shown && dash.searchable
477−
478− InputFilterArea {
479− anchors {
480− top: parent.top
481− left: parent.left
482− right: parent.right
483− }
484− height: (panel.fullscreenMode) ? shell.edgeSize : panel.panelHeight
485− blockInput: true
486− }
487− }
488−
489− InputFilterArea {
490− blockInput: launcher.shown
491− anchors {
492− top: parent.top
493− bottom: parent.bottom
494− left: parent.left
495− }
496− width: launcher.width
497418 }
498419
499420 Launcher {
@@ -514,11 +435,9 @@ FocusScope {
514435 showHome()
515436 }
516437 onDash: {
517− if (stages.shown && !stages.overlayMode) {
518− if (!stages.locked) {
519− stages.hide();
520− launcher.hide();
521− }
438+ if (!stages.locked) {
439+ stages.hide();
440+ launcher.hide();
522441 }
523442 if (greeter.shown) {
524443 greeter.hideRight();
@@ -548,11 +467,6 @@ FocusScope {
548467 MouseArea {
549468 anchors.fill: parent
550469 }
551−
552− InputFilterArea {
553− anchors.fill: parent
554− blockInput: modalNotificationBackground.visible
555− }
556470 }
557471
558472 Notifications {
@@ -580,59 +494,18 @@ FocusScope {
580494 PropertyChanges { target: notifications; width: units.gu(38) }
581495 }
582496 ]
583−
584− InputFilterArea {
585− anchors { left: parent.left; right: parent.right }
586− height: parent.contentHeight
587− blockInput: height > 0
588− }
589497 }
590498 }
591499
592500 focus: true
593501 onFocusChanged: if (!focus) forceActiveFocus();
594502
595− InputFilterArea {
596− anchors {
597− top: parent.top
598− bottom: parent.bottom
599− left: parent.left
600− }
601− width: shell.edgeSize
602− blockInput: true
603− }
604−
605− InputFilterArea {
606− anchors {
607− top: parent.top
608− bottom: parent.bottom
609− right: parent.right
610− }
611− width: shell.edgeSize
612− blockInput: true
613− }
614−
615503 Binding {
616504 target: i18n
617505 property: "domain"
618506 value: "unity8"
619507 }
620508
621− OSKController {
622− anchors.topMargin: panel.panelHeight
623− anchors.fill: parent // as needs to know the geometry of the shell
624− }
625−
626− //FIXME: This should be handled in the input stack, keyboard shouldnt propagate
627− MouseArea {
628− anchors.bottom: parent.bottom
629− anchors.left: parent.left
630− anchors.right: parent.right
631− height: ApplicationManager.keyboardVisible ? ApplicationManager.keyboardHeight : 0
632−
633− enabled: ApplicationManager.keyboardVisible
634− }
635−
636509 Label {
637510 anchors.centerIn: parent
638511 visible: ApplicationManager.fake ? ApplicationManager.fake : false
src/CMakeLists.txt−3
@@ -1,8 +1,5 @@
1−pkg_check_modules(UNITY-MIR REQUIRED unity-mir)
2−
31include_directories(
42 ${Qt5Gui_PRIVATE_INCLUDE_DIRS}
5− ${UNITY-MIR_INCLUDE_DIRS}
63)
74
85file(GLOB_RECURSE QML_FILES
src/main.cpp+10−61
@@ -35,12 +35,9 @@
3535#include "MouseTouchAdaptor.h"
3636#include "ApplicationArguments.h"
3737
38−#include <unity-mir/qmirserver.h>
39−
40−
41−int startShell(int argc, const char** argv, void* server)
38+int startShell(int argc, const char** argv)
4239{
43− const bool isUbuntuMirServer = qgetenv("QT_QPA_PLATFORM") == "ubuntumirserver";
40+ const bool isMirServer = qgetenv("QT_QPA_PLATFORM") == "mirserver";
4441
4542 QGuiApplication::setApplicationName("Unity 8");
4643 QGuiApplication *application;
@@ -70,21 +67,7 @@ int startShell(int argc, const char** argv, void* server)
7067Load the testability driver");
7168 parser.addOption(testabilityOption);
7269
73− if (isUbuntuMirServer) {
74− QLibrary unityMir("unity-mir", 1);
75− unityMir.load();
76−
77− typedef QGuiApplication* (*createServerApplication_t)(int&, const char **, void*);
78− createServerApplication_t createQMirServerApplication = (createServerApplication_t) unityMir.resolve("createQMirServerApplication");
79− if (!createQMirServerApplication) {
80− qDebug() << "unable to resolve symbol: createQMirServerApplication";
81− return 4;
82− }
83−
84− application = createQMirServerApplication(argc, argv, server);
85− } else {
86− application = new QGuiApplication(argc, (char**)argv);
87− }
70+ application = new QGuiApplication(argc, (char**)argv);
8871
8972 // Treat args with single dashes the same as arguments with two dashes
9073 // Ex: -fullscreen == --fullscreen
@@ -154,15 +137,14 @@ Load the testability driver");
154137
155138 QUrl source(::qmlDirectory()+"Shell.qml");
156139 prependImportPaths(view->engine(), ::overrideImportPaths());
157− if (!isUbuntuMirServer) {
140+ if (!isMirServer) {
158141 prependImportPaths(view->engine(), ::nonMirImportPaths());
159142 }
160143 appendImportPaths(view->engine(), ::fallbackImportPaths());
161144
162145 view->setSource(source);
163− view->setColor("transparent");
164146
165− if (qgetenv("QT_QPA_PLATFORM") == "ubuntu" || isUbuntuMirServer || parser.isSet(fullscreenOption)) {
147+ if (isMirServer || parser.isSet(fullscreenOption)) {
166148 view->showFullScreen();
167149 } else {
168150 view->show();
@@ -187,43 +169,10 @@ int main(int argc, const char *argv[])
187169 setenv("QML_FORCE_THREADED_RENDERER", "1", 1);
188170 setenv("QML_FIXED_ANIMATION_STEP", "1", 1);
189171
190− // For ubuntumirserver/ubuntumirclient
191− if (qgetenv("QT_QPA_PLATFORM").startsWith("ubuntumir")) {
192− setenv("QT_QPA_PLATFORM", "ubuntumirserver", 1);
193−
194− // If we use unity-mir directly, we automatically link to the Mir-server
195− // platform-api bindings, which result in unexpected behaviour when
196− // running the non-Mir scenario.
197− QLibrary unityMir("unity-mir", 1);
198− unityMir.load();
199− if (!unityMir.isLoaded()) {
200− qDebug() << "Library unity-mir not found/loaded";
201− return 1;
202− }
203−
204− typedef QMirServer* (*createServer_t)(int, const char **);
205− createServer_t createQMirServer = (createServer_t) unityMir.resolve("createQMirServer");
206− if (!createQMirServer) {
207− qDebug() << "unable to resolve symbol: createQMirServer";
208− return 2;
209− }
210−
211− QMirServer* mirServer = createQMirServer(argc, argv);
212−
213− typedef int (*runWithClient_t)(QMirServer*, std::function<int(int, const char**, void*)>);
214− runWithClient_t runWithClient = (runWithClient_t) unityMir.resolve("runQMirServerWithClient");
215− if (!runWithClient) {
216− qDebug() << "unable to resolve symbol: runWithClient";
217− return 3;
218− }
219−
220− return runWithClient(mirServer, startShell);
221− } else {
222− if (qgetenv("UPSTART_JOB") == "unity8") {
223− // Emit SIGSTOP as expected by upstart, under Mir it's unity-mir that will raise it.
224− // see http://upstart.ubuntu.com/cookbook/#expect-stop
225− raise(SIGSTOP);
226− }
227− return startShell(argc, argv, nullptr);
172+ if (qgetenv("QT_QPA_PLATFORM") == "ubuntuclient"
173+ || qgetenv("QT_QPA_PLATFORM") == "ubuntumirclient") {
174+ setenv("QT_QPA_PLATFORM", "mirserver", 1 /* overwrite */);
228175 }
176+
177+ return startShell(argc, argv);
229178}