Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save ortogonal/addff2910322254aabd7 to your computer and use it in GitHub Desktop.
Save ortogonal/addff2910322254aabd7 to your computer and use it in GitHub Desktop.
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