Created
January 26, 2016 18:15
-
-
Save ortogonal/addff2910322254aabd7 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From 2e783f9a84422d0eaee7f5adc9cc203bcc4f84ab Mon Sep 17 00:00:00 2001 | |
From: Erik Larsson <[email protected]> | |
Date: Thu, 31 Dec 2015 16:25:06 +0100 | |
Subject: [PATCH] Add support to handle popups in QWaylandQuickShellSurface. | |
Change-Id: I59ebfaf221b9bad60d26024803da483bf00eda77 | |
--- | |
.../extensions/qwaylandquickshellsurfaceitem.cpp | 133 ++++++++++++++++++++- | |
.../extensions/qwaylandquickshellsurfaceitem.h | 6 + | |
.../extensions/qwaylandquickshellsurfaceitem_p.h | 6 + | |
src/compositor/extensions/qwaylandshell.cpp | 10 +- | |
src/compositor/extensions/qwaylandshell.h | 2 + | |
5 files changed, 154 insertions(+), 3 deletions(-) | |
diff --git a/src/compositor/extensions/qwaylandquickshellsurfaceitem.cpp b/src/compositor/extensions/qwaylandquickshellsurfaceitem.cpp | |
index 5eb34b8..05e9c25 100644 | |
--- a/src/compositor/extensions/qwaylandquickshellsurfaceitem.cpp | |
+++ b/src/compositor/extensions/qwaylandquickshellsurfaceitem.cpp | |
@@ -39,6 +39,10 @@ | |
#include <QtWaylandCompositor/QWaylandCompositor> | |
#include <QtWaylandCompositor/QWaylandInputDevice> | |
+#include <QtWaylandCompositor/QWaylandShellSurface> | |
+#include <QtWaylandCompositor/QWaylandSurface> | |
+#include <QPointF> | |
+#include <QDebug> | |
QT_BEGIN_NAMESPACE | |
@@ -78,6 +82,12 @@ QWaylandQuickShellSurfaceItem::QWaylandQuickShellSurfaceItem(QWaylandQuickShellS | |
{ | |
} | |
+QWaylandQuickShellSurfaceItem::~QWaylandQuickShellSurfaceItem() { | |
+ Q_D(QWaylandQuickShellSurfaceItem); | |
+ if (d->shellSurface) | |
+ d->shellSurface->destroy(); | |
+} | |
+ | |
/*! | |
* \qmlproperty object QtWaylandCompositor::ShellSurfaceItem::shellSurface | |
* | |
@@ -104,11 +114,16 @@ void QWaylandQuickShellSurfaceItem::setShellSurface(QWaylandShellSurface *shellS | |
if (d->shellSurface) { | |
disconnect(d->shellSurface, &QWaylandShellSurface::startMove, this, &QWaylandQuickShellSurfaceItem::handleStartMove); | |
disconnect(d->shellSurface, &QWaylandShellSurface::startResize, this, &QWaylandQuickShellSurfaceItem::handleStartResize); | |
+ disconnect(d->shellSurface, &QWaylandShellSurface::setPopup, this, &QWaylandQuickShellSurfaceItem::handleSetPopup); | |
+ disconnect(d->shellSurface, &QWaylandShellSurface::destroyed, this, &QWaylandQuickShellSurfaceItem::handleShellSurfaceDestroyed); | |
} | |
+ | |
d->shellSurface = shellSurface; | |
if (d->shellSurface) { | |
connect(d->shellSurface, &QWaylandShellSurface::startMove, this, &QWaylandQuickShellSurfaceItem::handleStartMove); | |
connect(d->shellSurface, &QWaylandShellSurface::startResize, this, &QWaylandQuickShellSurfaceItem::handleStartResize); | |
+ connect(d->shellSurface, &QWaylandShellSurface::setPopup, this, &QWaylandQuickShellSurfaceItem::handleSetPopup); | |
+ connect(d->shellSurface, &QWaylandShellSurface::destroyed, this, &QWaylandQuickShellSurfaceItem::handleShellSurfaceDestroyed); | |
} | |
emit shellSurfaceChanged(); | |
} | |
@@ -143,6 +158,7 @@ void QWaylandQuickShellSurfaceItem::handleStartMove(QWaylandInputDevice *inputDe | |
d->grabberState = QWaylandQuickShellSurfaceItemPrivate::MoveState; | |
d->moveState.inputDevice = inputDevice; | |
d->moveState.initialized = false; | |
+ d->closePopups(); | |
} | |
/*! | |
@@ -156,6 +172,98 @@ void QWaylandQuickShellSurfaceItem::handleStartResize(QWaylandInputDevice *input | |
d->resizeState.resizeEdges = edges; | |
d->resizeState.initialSize = surface()->size(); | |
d->resizeState.initialized = false; | |
+ d->closePopups(); | |
+} | |
+ | |
+/*! | |
+ * \internal | |
+ */ | |
+void QWaylandQuickShellSurfaceItem::handleSetPopup(QWaylandInputDevice *inputDevice, QWaylandSurface *parent, const QPoint &relativeToParent) | |
+{ | |
+ Q_UNUSED(inputDevice); | |
+ Q_D(QWaylandQuickShellSurfaceItem); | |
+ | |
+ /*QWaylandQuickShellSurfaceItem* parentItem = qobject_cast<QWaylandQuickShellSurfaceItem*>(parent->views().first()->renderObject()); | |
+ if (parentItem) { | |
+ //qDebug() << Q_FUNC_INFO << "this" << this; | |
+ //qDebug() << Q_FUNC_INFO << parentItem << parentItem->mapToItem(this->parentItem(), relativeToParent); | |
+ //qDebug() << this->mapToItem(this->parentItem(), QPointF(0,0)); | |
+ | |
+ | |
+ QPoint pnt = parentItem->mapToItem(this->parentItem(), relativeToParent).toPoint(); | |
+ qDebug() << pnt; | |
+ this->setX(pnt.x()); | |
+ this->setY(pnt.y()); | |
+ | |
+ }*/ | |
+ if (!d->popupshellSurfaces.contains(this->shellSurface())) | |
+ d->popupshellSurfaces.append(this->shellSurface()); | |
+ | |
+ d->relativeToParent = relativeToParent; | |
+ d->popupParent = parent; | |
+ connect(this, &QQuickItem::widthChanged, | |
+ this, &QWaylandQuickShellSurfaceItem::adjustForPopupTransformation); | |
+ connect(this, &QQuickItem::heightChanged, | |
+ this, &QWaylandQuickShellSurfaceItem::adjustForPopupTransformation); | |
+} | |
+ | |
+/*! | |
+ * \internal | |
+ */ | |
+void QWaylandQuickShellSurfaceItem::handleShellSurfaceDestroyed() { | |
+ Q_D(QWaylandQuickShellSurfaceItem); | |
+ d->shellSurface = NULL; | |
+} | |
+ | |
+/*! | |
+ * \internal | |
+ */ | |
+void QWaylandQuickShellSurfaceItem::handleSurfaceMappedChanged() { | |
+ /*Q_D(QWaylandQuickShellSurfaceItem); | |
+ QWaylandSurface *surface = qobject_cast<QWaylandSurface *>(sender()); | |
+ qDebug() << Q_FUNC_INFO << surface; | |
+ if (surface->isMapped()) { | |
+ //if (!surface->isCursorSurface()) | |
+ // defaultInputDevice()->setKeyboardFocus(surface); | |
+ } else if (d->popupshellSurfaces.count() > 0) { | |
+ for (int i = 0; i < d->popupshellSurfaces.count(); i++) { | |
+ if (d->popupshellSurfaces.at(i)->surface() == surface) { | |
+ qDebug() << "Re"; | |
+ d->popupshellSurfaces.removeAt(i); | |
+ break; | |
+ } | |
+ } | |
+ }*/ | |
+} | |
+ | |
+/*! | |
+ * \internal | |
+ */ | |
+void QWaylandQuickShellSurfaceItem::adjustForPopupTransformation() | |
+{ | |
+ Q_D(QWaylandQuickShellSurfaceItem); | |
+ if (this->width() > -1 && this->height() > -1 && | |
+ (this->x() == 0 && this->y() == 0)) | |
+ { | |
+ QWaylandQuickShellSurfaceItem* parentItem = qobject_cast<QWaylandQuickShellSurfaceItem*>(d->popupParent->views().first()->renderObject()); | |
+ if (parentItem) { | |
+ qDebug() << Q_FUNC_INFO << "this" << this; | |
+ qDebug() << Q_FUNC_INFO << parentItem << parentItem->mapToItem(this->parentItem(), d->relativeToParent); | |
+ qDebug() << this->mapToItem(this->parentItem(), QPointF(0,0)); | |
+ | |
+ QPoint pnt = parentItem->mapToItem(this->parentItem(), d->relativeToParent).toPoint(); | |
+ QPoint pnt2 = this->mapToItem(this->parentItem(), QPointF(0,0)).toPoint(); | |
+ this->setX(pnt.x() - pnt2.x()); | |
+ this->setY(pnt.y() - pnt2.y()); | |
+ qDebug() << pnt << pnt2 << pnt - pnt2 << this->x() << this->y(); | |
+ | |
+ } | |
+ | |
+ disconnect(this, &QQuickItem::widthChanged, | |
+ this, &QWaylandQuickShellSurfaceItem::adjustForPopupTransformation); | |
+ disconnect(this, &QQuickItem::heightChanged, | |
+ this, &QWaylandQuickShellSurfaceItem::adjustForPopupTransformation); | |
+ } | |
} | |
/*! | |
@@ -219,11 +327,17 @@ void QWaylandQuickShellSurfaceItem::mouseReleaseEvent(QMouseEvent *event) | |
*/ | |
void QWaylandQuickShellSurfaceItem::surfaceChangedEvent(QWaylandSurface *newSurface, QWaylandSurface *oldSurface) | |
{ | |
- if (oldSurface) | |
+ if (oldSurface) { | |
disconnect(oldSurface, &QWaylandSurface::offsetForNextFrame, this, &QWaylandQuickShellSurfaceItem::adjustOffsetForNextFrame); | |
+ disconnect(oldSurface, &QWaylandSurface::mappedChanged, | |
+ this, &QWaylandQuickShellSurfaceItem::handleSurfaceMappedChanged); | |
+ } | |
- if (newSurface) | |
+ if (newSurface) { | |
connect(newSurface, &QWaylandSurface::offsetForNextFrame, this, &QWaylandQuickShellSurfaceItem::adjustOffsetForNextFrame); | |
+ connect(newSurface, &QWaylandSurface::mappedChanged, | |
+ this, &QWaylandQuickShellSurfaceItem::handleSurfaceMappedChanged); | |
+ } | |
} | |
/*! | |
@@ -238,4 +352,19 @@ void QWaylandQuickShellSurfaceItem::componentComplete() | |
QWaylandQuickItem::componentComplete(); | |
} | |
+QList<QWaylandShellSurface*> QWaylandQuickShellSurfaceItemPrivate::popupshellSurfaces; | |
+ | |
+/*! | |
+ * \internal | |
+ */ | |
+void QWaylandQuickShellSurfaceItemPrivate::closePopups() | |
+{ | |
+ if (!popupshellSurfaces.isEmpty()) { | |
+ Q_FOREACH (QWaylandShellSurface* shellSurface, popupshellSurfaces) { | |
+ shellSurface->sendPopupDone(); | |
+ } | |
+ popupshellSurfaces.clear(); | |
+ } | |
+} | |
+ | |
QT_END_NAMESPACE | |
diff --git a/src/compositor/extensions/qwaylandquickshellsurfaceitem.h b/src/compositor/extensions/qwaylandquickshellsurfaceitem.h | |
index a6f773b..26811b7 100644 | |
--- a/src/compositor/extensions/qwaylandquickshellsurfaceitem.h | |
+++ b/src/compositor/extensions/qwaylandquickshellsurfaceitem.h | |
@@ -54,6 +54,7 @@ class Q_COMPOSITOR_EXPORT QWaylandQuickShellSurfaceItem : public QWaylandQuickIt | |
public: | |
QWaylandQuickShellSurfaceItem(QQuickItem *parent = 0); | |
+ virtual ~QWaylandQuickShellSurfaceItem(); | |
static QWaylandQuickShellSurfaceItemPrivate *get(QWaylandQuickShellSurfaceItem *item) { return item->d_func(); } | |
@@ -69,6 +70,10 @@ Q_SIGNALS: | |
private Q_SLOTS: | |
void handleStartMove(QWaylandInputDevice *inputDevice); | |
void handleStartResize(QWaylandInputDevice *inputDevice, QWaylandShellSurface::ResizeEdge edges); | |
+ void handleSetPopup(QWaylandInputDevice *inputDevice, QWaylandSurface *parent, const QPoint &relativeToParent); | |
+ void handleShellSurfaceDestroyed(); | |
+ void handleSurfaceMappedChanged(); | |
+ void adjustForPopupTransformation(); | |
void adjustOffsetForNextFrame(const QPointF &offset); | |
protected: | |
QWaylandQuickShellSurfaceItem(QWaylandQuickShellSurfaceItemPrivate &dd, QQuickItem *parent); | |
@@ -79,6 +84,7 @@ protected: | |
void surfaceChangedEvent(QWaylandSurface *newSurface, QWaylandSurface *oldSurface) Q_DECL_OVERRIDE; | |
void componentComplete() Q_DECL_OVERRIDE; | |
+ | |
}; | |
QT_END_NAMESPACE | |
diff --git a/src/compositor/extensions/qwaylandquickshellsurfaceitem_p.h b/src/compositor/extensions/qwaylandquickshellsurfaceitem_p.h | |
index 510ff2c..ebdf75e 100644 | |
--- a/src/compositor/extensions/qwaylandquickshellsurfaceitem_p.h | |
+++ b/src/compositor/extensions/qwaylandquickshellsurfaceitem_p.h | |
@@ -68,6 +68,8 @@ public: | |
, grabberState(DefaultState) | |
{} | |
+ void closePopups(); | |
+ | |
QWaylandShellSurface *shellSurface; | |
QQuickItem *moveItem; | |
@@ -85,6 +87,10 @@ public: | |
QPointF initialMousePos; | |
bool initialized; | |
} resizeState; | |
+ | |
+ static QList<QWaylandShellSurface*> popupshellSurfaces; | |
+ QPoint relativeToParent; | |
+ QWaylandSurface *popupParent; | |
}; | |
QT_END_NAMESPACE | |
diff --git a/src/compositor/extensions/qwaylandshell.cpp b/src/compositor/extensions/qwaylandshell.cpp | |
index e06dc92..2ff66f4 100644 | |
--- a/src/compositor/extensions/qwaylandshell.cpp | |
+++ b/src/compositor/extensions/qwaylandshell.cpp | |
@@ -90,7 +90,6 @@ void QWaylandShellSurfacePrivate::ping(uint32_t serial) | |
void QWaylandShellSurfacePrivate::shell_surface_destroy_resource(Resource *) | |
{ | |
Q_Q(QWaylandShellSurface); | |
- | |
delete q; | |
} | |
@@ -473,6 +472,15 @@ void QWaylandShellSurface::sendPopupDone() | |
} | |
/*! | |
+ * Make sure this shell surface resource are destroyed. | |
+ */ | |
+void QWaylandShellSurface::destroy() | |
+{ | |
+ Q_D(QWaylandShellSurface); | |
+ wl_resource_destroy(d->resource()->handle); | |
+} | |
+ | |
+/*! | |
* \qmlproperty object QtWaylandCompositor::ShellSurface::surface | |
* | |
* This property holds the surface associated with this ShellSurface. | |
diff --git a/src/compositor/extensions/qwaylandshell.h b/src/compositor/extensions/qwaylandshell.h | |
index 3794a11..4ea546a 100644 | |
--- a/src/compositor/extensions/qwaylandshell.h | |
+++ b/src/compositor/extensions/qwaylandshell.h | |
@@ -122,6 +122,8 @@ public: | |
Q_INVOKABLE QSize sizeForResize(const QSizeF &size, const QPointF &delta, ResizeEdge edges); | |
Q_INVOKABLE void sendConfigure(const QSize &size, ResizeEdge edges); | |
Q_INVOKABLE void sendPopupDone(); | |
+ void destroy(); | |
+ | |
Q_SIGNALS: | |
void surfaceChanged(); | |
void titleChanged(); | |
-- | |
1.9.1 | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment