@@ -15,7 +15,6 @@
1515 */
1616
1717#include "MirSurfaceItem.h"
18−#include "Session.h"
1918
2019#include <paths.h>
2120
@@ -27,69 +26,30 @@
2726
2827#include <QDebug>
2928
30−MirSurfaceItem::MirSurfaceItem(const QString& name,
31− MirSurfaceItem::Type type,
32− MirSurfaceItem::State state,
33− const QUrl& screenshot,
34− const QString &qmlFilePath,
35− QQuickItem *parent)
36− : QQuickItem(parent)
37− , m_session(nullptr)
38− , m_name(name)
39− , m_type(type)
40− , m_state(state)
41− , m_live(true)
42− , m_orientationAngle(Angle0)
29+using namespace unity::shell::application;
30+
31+MirSurfaceItem::MirSurfaceItem(QQuickItem *parent)
32+ : MirSurfaceItemInterface(parent)
33+ , m_qmlSurface(nullptr)
4334 , m_qmlItem(nullptr)
44− , m_screenshotUrl(screenshot)
35+ , m_consumesInput(false)
36+ , m_surfaceWidth(0)
37+ , m_surfaceHeight(0)
4538 , m_touchPressCount(0)
4639 , m_touchReleaseCount(0)
4740{
41+ qDebug() << "MirSurfaceItem::MirSurfaceItem() " << (void*)(this) << name();
4842 setAcceptedMouseButtons(Qt::LeftButton | Qt::MiddleButton | Qt::RightButton |
4943 Qt::ExtraButton1 | Qt::ExtraButton2 | Qt::ExtraButton3 | Qt::ExtraButton4 |
5044 Qt::ExtraButton5 | Qt::ExtraButton6 | Qt::ExtraButton7 | Qt::ExtraButton8 |
5145 Qt::ExtraButton9 | Qt::ExtraButton10 | Qt::ExtraButton11 |
5246 Qt::ExtraButton12 | Qt::ExtraButton13);
53−
54− QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership);
55−
56− // The assumptions I make here really should hold.
57− QQuickView *quickView =
58− qobject_cast<QQuickView*>(QGuiApplication::topLevelWindows()[0]);
59−
60− QString qmlComponentFilePath;
61− if (!qmlFilePath.isEmpty()) {
62− qmlComponentFilePath.append(qmlFilePath);
63− } else {
64− qmlComponentFilePath = QString("%1/Unity/Application/MirSurfaceItem.qml")
65− .arg(mockPluginsDir());
66− }
67−
68− m_qmlContentComponent = new QQmlComponent(quickView->engine(), qmlComponentFilePath);
69−
70− switch (m_qmlContentComponent->status()) {
71− case QQmlComponent::Ready:
72− createQmlContentItem();
73− break;
74− case QQmlComponent::Loading:
75− connect(m_qmlContentComponent, &QQmlComponent::statusChanged,
76− this, &MirSurfaceItem::onComponentStatusChanged);
77− break;
78− case QQmlComponent::Error:
79− printComponentErrors();
80− qFatal("MirSurfaceItem: failed to create content component.");
81− break;
82− default:
83− qFatal("MirSurfaceItem: Unhandled component status");
84− }
8547}
8648
8749MirSurfaceItem::~MirSurfaceItem()
8850{
89− qDebug() << "MirSurfaceItem::~MirSurfaceItem() " << name();
90− if (m_session) {
91− m_session->setSurface(nullptr);
92− }
51+ qDebug() << "MirSurfaceItem::~MirSurfaceItem() " << (void*)(this) << name();
52+ setSurface(nullptr);
9353}
9454
9555void MirSurfaceItem::printComponentErrors()
@@ -100,58 +60,70 @@ void MirSurfaceItem::printComponentErrors()
10060 }
10161}
10262
103−void MirSurfaceItem::release()
63+Mir::Type MirSurfaceItem::type() const
10464{
105− qDebug() << "MirSurfaceItem::release " << name();
106−
107− if (m_session) {
108− m_session->setSurface(nullptr);
109− }
110− if (!parent()) {
111− deleteLater();
65+ if (m_qmlSurface) {
66+ return m_qmlSurface->type();
67+ } else {
68+ return Mir::UnknownType;
11269 }
11370}
11471
115−void MirSurfaceItem::setOrientationAngle(OrientationAngle angle)
72+Mir::State MirSurfaceItem::surfaceState() const
11673{
117− if (m_orientationAngle == angle)
118− return;
119−
120− m_orientationAngle = angle;
121−
122− QQmlProperty orientationProp(m_qmlItem, "orientationAngle");
123− orientationProp.write(QVariant::fromValue(m_orientationAngle));
124−
125− Q_EMIT orientationAngleChanged(m_orientationAngle);
74+ if (m_qmlSurface) {
75+ return m_qmlSurface->state();
76+ } else {
77+ return Mir::UnknownState;
78+ }
12679}
12780
128−void MirSurfaceItem::setSession(Session* session)
81+QString MirSurfaceItem::name() const
12982{
130− m_session = session;
83+ if (m_qmlSurface) {
84+ return m_qmlSurface->name();
85+ } else {
86+ return QString();
87+ }
13188}
13289
133−void MirSurfaceItem::setScreenshot(const QUrl& screenshot)
90+bool MirSurfaceItem::live() const
13491{
135− m_screenshotUrl = screenshot;
136− if (m_qmlItem) {
137− QQmlProperty screenshotSource(m_qmlItem, "screenshotSource");
138− screenshotSource.write(QVariant::fromValue(m_screenshotUrl));
92+ if (m_qmlSurface) {
93+ return m_qmlSurface->live();
94+ } else {
95+ return false;
13996 }
14097}
14198
142−void MirSurfaceItem::setLive(bool live)
99+Mir::OrientationAngle MirSurfaceItem::orientationAngle() const
143100{
144− if (m_live != live) {
145− m_live = live;
146− Q_EMIT liveChanged(m_live);
101+ if (m_qmlSurface) {
102+ return m_qmlSurface->orientationAngle();
103+ } else {
104+ return Mir::Angle0;
147105 }
148106}
149107
150−void MirSurfaceItem::setState(MirSurfaceItem::State newState)
108+void MirSurfaceItem::setOrientationAngle(Mir::OrientationAngle angle)
151109{
152− if (newState != m_state) {
153− m_state = newState;
154− Q_EMIT stateChanged(newState);
110+ if (!m_qmlSurface)
111+ return;
112+
113+ if (m_qmlSurface->orientationAngle() == angle)
114+ return;
115+
116+ m_qmlSurface->setOrientationAngle(angle);
117+
118+ QQmlProperty orientationProp(m_qmlItem, "orientationAngle");
119+ orientationProp.write(QVariant::fromValue(m_qmlSurface->orientationAngle()));
120+}
121+
122+void MirSurfaceItem::updateScreenshot(QUrl screenshotUrl)
123+{
124+ if (m_qmlItem) {
125+ QQmlProperty screenshotSource(m_qmlItem, "screenshotSource");
126+ screenshotSource.write(QVariant::fromValue(screenshotUrl));
155127 }
156128}
157129
@@ -174,7 +146,7 @@ void MirSurfaceItem::createQmlContentItem()
174146
175147 {
176148 QQmlProperty screenshotSource(m_qmlItem, "screenshotSource");
177− screenshotSource.write(QVariant::fromValue(m_screenshotUrl));
149+ screenshotSource.write(QVariant::fromValue(m_qmlSurface->screenshotUrl()));
178150 }
179151}
180152
@@ -188,3 +160,124 @@ void MirSurfaceItem::touchEvent(QTouchEvent * event)
188160 Q_EMIT touchReleaseCountChanged(m_touchReleaseCount);
189161 }
190162}
163+
164+void MirSurfaceItem::setSurface(MirSurfaceInterface* surface)
165+{
166+ qDebug().nospace() << "MirSurfaceItem::setSurface() this=" << (void*)(this)
167+ << " name=" << name()
168+ << " surface=" << surface;
169+
170+ if (m_qmlSurface == surface) {
171+ return;
172+ }
173+
174+ if (m_qmlSurface) {
175+ delete m_qmlItem;
176+ m_qmlItem = nullptr;
177+
178+ delete m_qmlContentComponent;
179+ m_qmlContentComponent = nullptr;
180+
181+ disconnect(m_qmlSurface, nullptr, this, nullptr);
182+ m_qmlSurface->decrementViewCount();
183+ }
184+
185+ m_qmlSurface = static_cast<MirSurface*>(surface);
186+
187+ if (m_qmlSurface) {
188+ m_qmlSurface->incrementViewCount();
189+
190+ m_qmlSurface->setActiveFocus(hasActiveFocus());
191+
192+ updateSurfaceSize();
193+
194+ connect(m_qmlSurface, &MirSurface::orientationAngleChanged, this, &MirSurfaceItem::orientationAngleChanged);
195+ connect(m_qmlSurface, &MirSurface::screenshotUrlChanged, this, &MirSurfaceItem::updateScreenshot);
196+ connect(m_qmlSurface, &MirSurface::liveChanged, this, &MirSurfaceItem::liveChanged);
197+ connect(m_qmlSurface, &MirSurface::stateChanged, this, &MirSurfaceItem::surfaceStateChanged);
198+
199+ // The assumptions I make here really should hold.
200+ QQuickView *quickView =
201+ qobject_cast<QQuickView*>(QGuiApplication::topLevelWindows()[0]);
202+
203+ QString qmlComponentFilePath;
204+ if (!m_qmlSurface->qmlFilePath().isEmpty()) {
205+ qmlComponentFilePath.append(m_qmlSurface->qmlFilePath());
206+ } else {
207+ qmlComponentFilePath = QString("%1/Unity/Application/MirSurfaceItem.qml")
208+ .arg(mockPluginsDir());
209+ }
210+
211+ m_qmlContentComponent = new QQmlComponent(quickView->engine(), qmlComponentFilePath);
212+
213+ switch (m_qmlContentComponent->status()) {
214+ case QQmlComponent::Ready:
215+ createQmlContentItem();
216+ break;
217+ case QQmlComponent::Loading:
218+ connect(m_qmlContentComponent, &QQmlComponent::statusChanged,
219+ this, &MirSurfaceItem::onComponentStatusChanged);
220+ break;
221+ case QQmlComponent::Error:
222+ printComponentErrors();
223+ qFatal("MirSurfaceItem: failed to create content component.");
224+ break;
225+ default:
226+ qFatal("MirSurfaceItem: Unhandled component status");
227+ }
228+ }
229+
230+ Q_EMIT surfaceChanged(m_qmlSurface);
231+}
232+
233+void MirSurfaceItem::itemChange(ItemChange change, const ItemChangeData & value)
234+{
235+ if (change == QQuickItem::ItemActiveFocusHasChanged) {
236+ if (m_qmlSurface) {
237+ m_qmlSurface->setActiveFocus(value.boolValue);
238+ }
239+ }
240+}
241+
242+void MirSurfaceItem::setConsumesInput(bool value)
243+{
244+ if (m_consumesInput != value) {
245+ m_consumesInput = value;
246+ Q_EMIT consumesInputChanged(value);
247+ }
248+}
249+
250+int MirSurfaceItem::surfaceWidth() const
251+{
252+ return m_surfaceWidth;
253+}
254+
255+void MirSurfaceItem::setSurfaceWidth(int value)
256+{
257+ if (m_surfaceWidth != value) {
258+ m_surfaceWidth = value;
259+ Q_EMIT surfaceWidthChanged(m_surfaceWidth);
260+ updateSurfaceSize();
261+ }
262+}
263+
264+int MirSurfaceItem::surfaceHeight() const
265+{
266+ return m_surfaceHeight;
267+}
268+
269+void MirSurfaceItem::setSurfaceHeight(int value)
270+{
271+ if (m_surfaceHeight != value) {
272+ m_surfaceHeight = value;
273+ Q_EMIT surfaceHeightChanged(m_surfaceHeight);
274+ updateSurfaceSize();
275+ }
276+}
277+
278+void MirSurfaceItem::updateSurfaceSize()
279+{
280+ if (m_qmlSurface && m_surfaceWidth > 0 && m_surfaceHeight > 0) {
281+ m_qmlSurface->resize(m_surfaceWidth, m_surfaceHeight);
282+ }
283+}