diff options
author | Johan Klokkhammer Helsing <johan.helsing@qt.io> | 2016-05-20 13:40:07 +0200 |
---|---|---|
committer | Johan Helsing <johan.helsing@qt.io> | 2016-06-15 08:07:32 +0000 |
commit | a0c54d6435edd23a7eaacef73b074475730ec208 (patch) | |
tree | 36e08f755563c82f3a03cc878f9fc0f3667b6f6c | |
parent | 5fbb2043a1be8b14e70335c2b2db77702e52fa10 (diff) |
Add QML popup support for xdg_shell
Change-Id: I5b35ff3b1c6c2dc884b52e6f077c0f2bb2db68a2
Reviewed-by: Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
7 files changed, 60 insertions, 8 deletions
diff --git a/examples/wayland/pure-qml/qml/main.qml b/examples/wayland/pure-qml/qml/main.qml index fb61aeacd..0d99275eb 100644 --- a/examples/wayland/pure-qml/qml/main.qml +++ b/examples/wayland/pure-qml/qml/main.qml @@ -73,8 +73,14 @@ WaylandCompositor { } }, XdgShell { + property variant viewsBySurface: ({}) onXdgSurfaceCreated: { - chromeComponent.createObject(defaultOutput.surfaceArea, { "shellSurface": xdgSurface } ); + var item = chromeComponent.createObject(defaultOutput.surfaceArea, { "shellSurface": xdgSurface } ); + viewsBySurface[xdgSurface.surface] = item; + } + onXdgPopupCreated: { + var parentView = viewsBySurface[xdgPopup.parentSurface]; + chromeComponent.createObject(parentView, { "shellSurface": xdgPopup } ); } }, TextInputManager { diff --git a/src/compositor/extensions/qwaylandquickshellsurfaceitem_p.h b/src/compositor/extensions/qwaylandquickshellsurfaceitem_p.h index c2f46917e..53c88c965 100644 --- a/src/compositor/extensions/qwaylandquickshellsurfaceitem_p.h +++ b/src/compositor/extensions/qwaylandquickshellsurfaceitem_p.h @@ -39,6 +39,8 @@ #include <QtWaylandCompositor/private/qwaylandquickitem_p.h> +#include <functional> + QT_BEGIN_NAMESPACE // @@ -82,7 +84,7 @@ class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandQuickShellEventFilter : public QObject { Q_OBJECT public: - typedef void (*CallbackFunction)(void); + typedef std::function<void()> CallbackFunction; static void startFilter(QWaylandClient *client, CallbackFunction closePopupCallback); static void cancelFilter(); diff --git a/src/compositor/extensions/qwaylandxdgshell.cpp b/src/compositor/extensions/qwaylandxdgshell.cpp index 6e3185bde..0b45b21ac 100644 --- a/src/compositor/extensions/qwaylandxdgshell.cpp +++ b/src/compositor/extensions/qwaylandxdgshell.cpp @@ -940,7 +940,7 @@ QWaylandQuickShellIntegration *QWaylandXdgSurface::createIntegration(QWaylandQui * Constructs a QWaylandXdgPopup. */ QWaylandXdgPopup::QWaylandXdgPopup() - : QWaylandCompositorExtensionTemplate<QWaylandXdgPopup>(*new QWaylandXdgPopupPrivate) + : QWaylandShellSurfaceTemplate<QWaylandXdgPopup>(*new QWaylandXdgPopupPrivate) { } @@ -950,7 +950,7 @@ QWaylandXdgPopup::QWaylandXdgPopup() */ QWaylandXdgPopup::QWaylandXdgPopup(QWaylandXdgShell *xdgShell, QWaylandSurface *surface, QWaylandSurface *parentSurface, const QPoint &position, const QWaylandResource &resource) - : QWaylandCompositorExtensionTemplate<QWaylandXdgPopup>(*new QWaylandXdgPopupPrivate) + : QWaylandShellSurfaceTemplate<QWaylandXdgPopup>(*new QWaylandXdgPopupPrivate) { initialize(xdgShell, surface, parentSurface, position, resource); } @@ -1043,7 +1043,7 @@ QPoint QWaylandXdgPopup::position() const */ void QWaylandXdgPopup::initialize() { - QWaylandCompositorExtensionTemplate::initialize(); + QWaylandCompositorExtension::initialize(); } /*! @@ -1081,4 +1081,9 @@ void QWaylandXdgPopup::sendPopupDone() d->send_popup_done(); } +QWaylandQuickShellIntegration *QWaylandXdgPopup::createIntegration(QWaylandQuickShellSurfaceItem *item) +{ + return new QtWayland::XdgPopupIntegration(item); +} + QT_END_NAMESPACE diff --git a/src/compositor/extensions/qwaylandxdgshell.h b/src/compositor/extensions/qwaylandxdgshell.h index a259b12ed..2187086ac 100644 --- a/src/compositor/extensions/qwaylandxdgshell.h +++ b/src/compositor/extensions/qwaylandxdgshell.h @@ -192,7 +192,7 @@ private Q_SLOTS: void handleSurfaceSizeChanged(); }; -class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandXdgPopup : public QWaylandCompositorExtensionTemplate<QWaylandXdgPopup> +class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandXdgPopup : public QWaylandShellSurfaceTemplate<QWaylandXdgPopup> { Q_OBJECT Q_DECLARE_PRIVATE(QWaylandXdgPopup) @@ -219,6 +219,8 @@ public: Q_INVOKABLE void sendPopupDone(); + QWaylandQuickShellIntegration *createIntegration(QWaylandQuickShellSurfaceItem *item) Q_DECL_OVERRIDE; + Q_SIGNALS: void surfaceChanged(); void parentSurfaceChanged(); diff --git a/src/compositor/extensions/qwaylandxdgshell_p.h b/src/compositor/extensions/qwaylandxdgshell_p.h index 1e4ccf0fb..fa0e7037d 100644 --- a/src/compositor/extensions/qwaylandxdgshell_p.h +++ b/src/compositor/extensions/qwaylandxdgshell_p.h @@ -73,13 +73,13 @@ public: bool isValidPopupParent(QWaylandSurface *parentSurface) const; QWaylandXdgPopup *topmostPopupForClient(struct wl_client* client) const; -private: QSet<uint32_t> m_pings; QMultiMap<struct wl_client *, QWaylandXdgSurface *> m_xdgSurfaces; QMultiMap<struct wl_client *, QWaylandXdgPopup *> m_xdgPopups; QWaylandXdgSurface *xdgSurfaceFromSurface(QWaylandSurface *surface); +protected: void xdg_shell_destroy(Resource *resource) Q_DECL_OVERRIDE; void xdg_shell_get_xdg_surface(Resource *resource, uint32_t id, struct ::wl_resource *surface) Q_DECL_OVERRIDE; @@ -157,7 +157,6 @@ public: QWaylandXdgPopupPrivate(); static QWaylandXdgPopupPrivate *get(QWaylandXdgPopup *xdgPopup) { return xdgPopup->d_func(); } -private: QWaylandSurface *m_surface; QWaylandSurface *m_parentSurface; QWaylandXdgShell *m_xdgShell; diff --git a/src/compositor/extensions/qwaylandxdgshellintegration.cpp b/src/compositor/extensions/qwaylandxdgshellintegration.cpp index b0ba00b16..251dc337a 100644 --- a/src/compositor/extensions/qwaylandxdgshellintegration.cpp +++ b/src/compositor/extensions/qwaylandxdgshellintegration.cpp @@ -39,7 +39,9 @@ #include <QtWaylandCompositor/QWaylandQuickShellSurfaceItem> #include <QtWaylandCompositor/QWaylandCompositor> #include <QtWaylandCompositor/QWaylandInputDevice> +#include <QtWaylandCompositor/private/qwaylandxdgshell_p.h> #include <QMouseEvent> +#include <QGuiApplication> QT_BEGIN_NAMESPACE @@ -168,6 +170,28 @@ void XdgShellIntegration::handleSurfaceSizeChanged() } } +XdgPopupIntegration::XdgPopupIntegration(QWaylandQuickShellSurfaceItem *item) + : QWaylandQuickShellIntegration (item) + , m_xdgPopup(qobject_cast<QWaylandXdgPopup *>(item->shellSurface())) + , m_xdgShell(QWaylandXdgPopupPrivate::get(m_xdgPopup)->m_xdgShell) +{ + item->setSurface(m_xdgPopup->surface()); + item->setPosition(QPointF(m_xdgPopup->position() * item->view()->output()->scaleFactor())); + + QWaylandClient *client = m_xdgPopup->surface()->client(); + QWaylandQuickShellEventFilter::startFilter(client, [&]() { m_xdgShell->closeAllPopups(); }); + + connect(m_xdgPopup, &QWaylandXdgPopup::destroyed, this, &XdgPopupIntegration::handlePopupDestroyed); +} + +void XdgPopupIntegration::handlePopupDestroyed() +{ + QWaylandXdgShellPrivate *shellPrivate = QWaylandXdgShellPrivate::get(m_xdgShell); + auto popups = shellPrivate->m_xdgPopups; + if (popups.isEmpty()) + QWaylandQuickShellEventFilter::cancelFilter(); +} + } QT_END_NAMESPACE diff --git a/src/compositor/extensions/qwaylandxdgshellintegration_p.h b/src/compositor/extensions/qwaylandxdgshellintegration_p.h index df2fa8b8d..c3021c080 100644 --- a/src/compositor/extensions/qwaylandxdgshellintegration_p.h +++ b/src/compositor/extensions/qwaylandxdgshellintegration_p.h @@ -104,6 +104,20 @@ private: } maximizeState; }; +class XdgPopupIntegration : public QWaylandQuickShellIntegration +{ + Q_OBJECT +public: + XdgPopupIntegration(QWaylandQuickShellSurfaceItem *item); + +private Q_SLOTS: + void handlePopupDestroyed(); + +private: + QWaylandXdgPopup *m_xdgPopup; + QWaylandXdgShell *m_xdgShell; +}; + } QT_END_NAMESPACE |