@@ -15,8 +15,10 @@
1515 */
1616
1717#include "MirSurfaceItem.h"
18+#include "ApplicationInfo.h"
1819
1920#include <QPainter>
21+#include <QQmlEngine>
2022
2123MirSurfaceItem::MirSurfaceItem(const QString& name,
2224 MirSurfaceItem::Type type,
@@ -24,12 +26,16 @@ MirSurfaceItem::MirSurfaceItem(const QString& name,
2426 const QUrl& screenshot,
2527 QQuickItem *parent)
2628 : QQuickPaintedItem(parent)
29+ , m_application(nullptr)
2730 , m_name(name)
2831 , m_type(type)
2932 , m_state(state)
3033 , m_img(screenshot.isLocalFile() ? screenshot.toLocalFile() : screenshot.toString())
34+ , m_parentSurface(nullptr)
3135 , m_haveInputMethod(false)
3236{
37+ QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership);
38+
3339 // The virtual keyboard (input method) has a big transparent area so that
3440 // content behind it show through
3541 setFillColor(Qt::transparent);
@@ -38,6 +44,19 @@ MirSurfaceItem::MirSurfaceItem(const QString& name,
3844 this, &MirSurfaceItem::onFocusChanged);
3945}
4046
47+MirSurfaceItem::~MirSurfaceItem()
48+{
49+ QList<MirSurfaceItem*> children(m_children);
50+ for (MirSurfaceItem* child : children) {
51+ child->setParentSurface(nullptr);
52+ }
53+ if (m_parentSurface)
54+ m_parentSurface->removeChildSurface(this);
55+
56+ if (m_application)
57+ m_application->setSurface(nullptr);
58+}
59+
4160void MirSurfaceItem::paint(QPainter * painter)
4261{
4362 if (!m_img.isNull()) {
@@ -45,6 +64,91 @@ void MirSurfaceItem::paint(QPainter * painter)
4564 }
4665}
4766
67+void MirSurfaceItem::release()
68+{
69+ QList<MirSurfaceItem*> children(m_children);
70+ for (MirSurfaceItem* child : children) {
71+ child->release();
72+ }
73+ if (m_parentSurface) {
74+ m_parentSurface->removeChildSurface(this);
75+ }
76+
77+ if (m_application) {
78+ m_application->setSurface(nullptr);
79+ }
80+ if (!parent()) {
81+ deleteLater();
82+ }
83+}
84+
85+void MirSurfaceItem::setApplication(ApplicationInfo* application)
86+{
87+ m_application = application;
88+}
89+
90+void MirSurfaceItem::setParentSurface(MirSurfaceItem* surface)
91+{
92+ if (m_parentSurface == surface || surface == this)
93+ return;
94+
95+ if (m_parentSurface) {
96+ m_parentSurface->removeChildSurface(this);
97+ }
98+
99+ m_parentSurface = surface;
100+
101+ if (m_parentSurface) {
102+ m_parentSurface->addChildSurface(this);
103+ }
104+ Q_EMIT parentSurfaceChanged(surface);
105+}
106+
107+void MirSurfaceItem::removeChildSurface(MirSurfaceItem* surface)
108+{
109+ if (m_children.contains(surface)) {
110+ m_children.removeOne(surface);
111+ Q_EMIT childSurfacesChanged();
112+ }
113+}
114+
115+void MirSurfaceItem::addChildSurface(MirSurfaceItem* surface)
116+{
117+ m_children.append(surface);
118+ Q_EMIT childSurfacesChanged();
119+}
120+
121+void MirSurfaceItem::foreachChildSurface(std::function<void(MirSurfaceItem*)> f) const
122+{
123+ for(MirSurfaceItem* child : m_children) {
124+ f(child);
125+ }
126+}
127+
128+QQmlListProperty<MirSurfaceItem> MirSurfaceItem::childSurfaces()
129+{
130+ return QQmlListProperty<MirSurfaceItem>(this,
131+ 0,
132+ MirSurfaceItem::childSurfaceCount,
133+ MirSurfaceItem::childSurfaceAt);
134+}
135+
136+int MirSurfaceItem::childSurfaceCount(QQmlListProperty<MirSurfaceItem> *prop)
137+{
138+ MirSurfaceItem *p = qobject_cast<MirSurfaceItem*>(prop->object);
139+ return p->m_children.count();
140+}
141+
142+MirSurfaceItem* MirSurfaceItem::childSurfaceAt(QQmlListProperty<MirSurfaceItem> *prop, int index)
143+{
144+ MirSurfaceItem *p = qobject_cast<MirSurfaceItem*>(prop->object);
145+
146+ if (index < 0 || index >= p->m_children.count())
147+ return nullptr;
148+ return p->m_children[index];
149+}
150+
151+
48152void MirSurfaceItem::touchEvent(QTouchEvent * event)
49153{
50154 if (event->type() == QEvent::TouchBegin && hasFocus()) {