From 458dfb4c65dd959115416a5bc9d6dfc5e4936bd6 Mon Sep 17 00:00:00 2001 From: Johan Klokkhammer Helsing Date: Thu, 6 Apr 2017 10:57:37 +0200 Subject: Compositor: Automatically create ShellSurfaceItems for popups Change-Id: I5e6b0147c4f1bb73ff3a8f5512d21884f962a89a Reviewed-by: Paul Olav Tvete --- examples/wayland/minimal-qml/main.qml | 1 + examples/wayland/pure-qml/qml/Chrome.qml | 1 + examples/wayland/pure-qml/qml/main.qml | 18 +-------- .../extensions/qwaylandquickshellsurfaceitem.cpp | 45 ++++++++++++++++++++++ .../extensions/qwaylandquickshellsurfaceitem.h | 5 +++ .../extensions/qwaylandquickshellsurfaceitem_p.h | 10 ++++- .../extensions/qwaylandxdgshellv5integration.cpp | 12 ++++++ .../extensions/qwaylandxdgshellv6integration.cpp | 13 +++++++ 8 files changed, 87 insertions(+), 18 deletions(-) diff --git a/examples/wayland/minimal-qml/main.qml b/examples/wayland/minimal-qml/main.qml index 0f0ca61bc..85c8c5783 100644 --- a/examples/wayland/minimal-qml/main.qml +++ b/examples/wayland/minimal-qml/main.qml @@ -67,6 +67,7 @@ WaylandCompositor { // resize/move, and forwarding of mouse and keyboard // events to the client process. ShellSurfaceItem { + autoCreatePopupItems: true shellSurface: modelData onSurfaceDestroyed: shellSurfaces.remove(index) } diff --git a/examples/wayland/pure-qml/qml/Chrome.qml b/examples/wayland/pure-qml/qml/Chrome.qml index e6fe97476..2e2586c1b 100644 --- a/examples/wayland/pure-qml/qml/Chrome.qml +++ b/examples/wayland/pure-qml/qml/Chrome.qml @@ -53,6 +53,7 @@ import QtWayland.Compositor 1.0 ShellSurfaceItem { id: rootChrome + autoCreatePopupItems: true property bool isChild: parent.shellSurface !== undefined diff --git a/examples/wayland/pure-qml/qml/main.qml b/examples/wayland/pure-qml/qml/main.qml index 77ed3ecd9..7bf2a623c 100644 --- a/examples/wayland/pure-qml/qml/main.qml +++ b/examples/wayland/pure-qml/qml/main.qml @@ -83,29 +83,15 @@ WaylandCompositor { } } - property variant viewsBySurface: ({}) - XdgShellV5 { onXdgSurfaceCreated: { - var item = chromeComponent.createObject(defaultOutput.surfaceArea, { "shellSurface": xdgSurface } ); - viewsBySurface[xdgSurface.surface] = item; - } - onXdgPopupCreated: { - var parentView = viewsBySurface[xdgPopup.parentSurface]; - var item = chromeComponent.createObject(parentView, { "shellSurface": xdgPopup } ); - viewsBySurface[xdgPopup.surface] = item; + chromeComponent.createObject(defaultOutput.surfaceArea, { "shellSurface": xdgSurface } ); } } XdgShellV6 { onToplevelCreated: { - var item = chromeComponent.createObject(defaultOutput.surfaceArea, { "shellSurface": xdgSurface } ); - viewsBySurface[xdgSurface.surface] = item; - } - onPopupCreated: { - var parentView = viewsBySurface[popup.parentXdgSurface.surface]; - var item = chromeComponent.createObject(parentView, { "shellSurface": xdgSurface } ); - viewsBySurface[xdgSurface.surface] = item; + chromeComponent.createObject(defaultOutput.surfaceArea, { "shellSurface": xdgSurface } ); } } diff --git a/src/compositor/extensions/qwaylandquickshellsurfaceitem.cpp b/src/compositor/extensions/qwaylandquickshellsurfaceitem.cpp index 6b8845797..84e9c356d 100644 --- a/src/compositor/extensions/qwaylandquickshellsurfaceitem.cpp +++ b/src/compositor/extensions/qwaylandquickshellsurfaceitem.cpp @@ -45,6 +45,21 @@ QT_BEGIN_NAMESPACE +QWaylandQuickShellSurfaceItem *QWaylandQuickShellSurfaceItemPrivate::maybeCreateAutoPopup(QWaylandShellSurface* shellSurface) +{ + if (!m_autoCreatePopupItems) + return nullptr; + + Q_Q(QWaylandQuickShellSurfaceItem); + auto *popupItem = new QWaylandQuickShellSurfaceItem(q); + popupItem->setShellSurface(shellSurface); + popupItem->setAutoCreatePopupItems(true); + QObject::connect(popupItem, &QWaylandQuickShellSurfaceItem::surfaceDestroyed, [popupItem](){ + popupItem->deleteLater(); + }); + return popupItem; +} + /*! * \qmltype ShellSurfaceItem * \inherits WaylandQuickItem @@ -163,6 +178,36 @@ void QWaylandQuickShellSurfaceItem::setMoveItem(QQuickItem *moveItem) moveItemChanged(); } +/*! + * \qmlproperty bool QtWaylandCompositor::ShellSurfaceItem::autoCreatePopupItems + * + * This property holds whether ShellSurfaceItems for popups parented to the shell + * surface managed by this item should automatically be created. + */ + +/*! + * \property QWaylandQuickShellSurfaceItem::autoCreatePopupItems + * + * This property holds whether QWaylandQuickShellSurfaceItems for popups + * parented to the shell surface managed by this item should automatically be created. + */ +bool QWaylandQuickShellSurfaceItem::autoCreatePopupItems() +{ + Q_D(const QWaylandQuickShellSurfaceItem); + return d->m_autoCreatePopupItems; +} + +void QWaylandQuickShellSurfaceItem::setAutoCreatePopupItems(bool enabled) +{ + Q_D(QWaylandQuickShellSurfaceItem); + + if (enabled == d->m_autoCreatePopupItems) + return; + + d->m_autoCreatePopupItems = enabled; + emit autoCreatePopupItemsChanged(); +} + void QWaylandQuickShellSurfaceItem::mouseMoveEvent(QMouseEvent *event) { Q_D(QWaylandQuickShellSurfaceItem); diff --git a/src/compositor/extensions/qwaylandquickshellsurfaceitem.h b/src/compositor/extensions/qwaylandquickshellsurfaceitem.h index e2c823651..d14fa3fce 100644 --- a/src/compositor/extensions/qwaylandquickshellsurfaceitem.h +++ b/src/compositor/extensions/qwaylandquickshellsurfaceitem.h @@ -54,6 +54,7 @@ class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandQuickShellSurfaceItem : public QWaylan Q_DECLARE_PRIVATE(QWaylandQuickShellSurfaceItem) Q_PROPERTY(QWaylandShellSurface *shellSurface READ shellSurface WRITE setShellSurface NOTIFY shellSurfaceChanged) Q_PROPERTY(QQuickItem *moveItem READ moveItem WRITE setMoveItem NOTIFY moveItemChanged) + Q_PROPERTY(bool autoCreatePopupItems READ autoCreatePopupItems WRITE setAutoCreatePopupItems NOTIFY autoCreatePopupItemsChanged) public: QWaylandQuickShellSurfaceItem(QQuickItem *parent = nullptr); ~QWaylandQuickShellSurfaceItem() override; @@ -64,9 +65,13 @@ public: QQuickItem *moveItem() const; void setMoveItem(QQuickItem *moveItem); + bool autoCreatePopupItems(); + void setAutoCreatePopupItems(bool enabled); + Q_SIGNALS: void shellSurfaceChanged(); void moveItemChanged(); + void autoCreatePopupItemsChanged(); protected: QWaylandQuickShellSurfaceItem(QWaylandQuickShellSurfaceItemPrivate &dd, QQuickItem *parent); diff --git a/src/compositor/extensions/qwaylandquickshellsurfaceitem_p.h b/src/compositor/extensions/qwaylandquickshellsurfaceitem_p.h index abb56221e..7a458381e 100644 --- a/src/compositor/extensions/qwaylandquickshellsurfaceitem_p.h +++ b/src/compositor/extensions/qwaylandquickshellsurfaceitem_p.h @@ -40,6 +40,7 @@ #ifndef QWAYLANDQUICKSHELLSURFACEITEM_P_H #define QWAYLANDQUICKSHELLSURFACEITEM_P_H +#include #include #include @@ -60,15 +61,20 @@ QT_BEGIN_NAMESPACE class QWaylandQuickShellIntegration; class QWaylandShellSurface; +class QWaylandQuickShellSurfaceItem; class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandQuickShellSurfaceItemPrivate : public QWaylandQuickItemPrivate { + Q_DECLARE_PUBLIC(QWaylandQuickShellSurfaceItem) public: - QWaylandQuickShellSurfaceItemPrivate() - {} + QWaylandQuickShellSurfaceItemPrivate() {} + QWaylandQuickShellSurfaceItem *maybeCreateAutoPopup(QWaylandShellSurface* shellSurface); + static QWaylandQuickShellSurfaceItemPrivate *get(QWaylandQuickShellSurfaceItem *item) { return item->d_func(); } + QWaylandQuickShellIntegration *m_shellIntegration = nullptr; QWaylandShellSurface *m_shellSurface = nullptr; QQuickItem *m_moveItem = nullptr; + bool m_autoCreatePopupItems = false; }; class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandQuickShellIntegration : public QObject diff --git a/src/compositor/extensions/qwaylandxdgshellv5integration.cpp b/src/compositor/extensions/qwaylandxdgshellv5integration.cpp index a349a25aa..ea04a33d2 100644 --- a/src/compositor/extensions/qwaylandxdgshellv5integration.cpp +++ b/src/compositor/extensions/qwaylandxdgshellv5integration.cpp @@ -50,6 +50,12 @@ QT_BEGIN_NAMESPACE namespace QtWayland { +static void handlePopupCreated(QWaylandQuickShellSurfaceItem *parentItem, QWaylandXdgPopupV5 *popup) +{ + if (parentItem->surface() == popup->parentSurface()) + QWaylandQuickShellSurfaceItemPrivate::get(parentItem)->maybeCreateAutoPopup(popup); +} + XdgShellV5Integration::XdgShellV5Integration(QWaylandQuickShellSurfaceItem *item) : QWaylandQuickShellIntegration(item) , m_item(item) @@ -66,6 +72,9 @@ XdgShellV5Integration::XdgShellV5Integration(QWaylandQuickShellSurfaceItem *item connect(m_xdgSurface, &QWaylandXdgSurfaceV5::maximizedChanged, this, &XdgShellV5Integration::handleMaximizedChanged); connect(m_xdgSurface, &QWaylandXdgSurfaceV5::activatedChanged, this, &XdgShellV5Integration::handleActivatedChanged); connect(m_xdgSurface->surface(), &QWaylandSurface::sizeChanged, this, &XdgShellV5Integration::handleSurfaceSizeChanged); + connect(m_xdgSurface->shell(), &QWaylandXdgShellV5::xdgPopupCreated, this, [item](QWaylandXdgPopupV5 *popup){ + handlePopupCreated(item, popup); + }); } XdgShellV5Integration::~XdgShellV5Integration() @@ -213,6 +222,9 @@ XdgPopupV5Integration::XdgPopupV5Integration(QWaylandQuickShellSurfaceItem *item QWaylandQuickShellEventFilter::startFilter(client, [shell]() { shell->closeAllPopups(); }); connect(m_xdgPopup, &QWaylandXdgPopupV5::destroyed, this, &XdgPopupV5Integration::handlePopupDestroyed); + connect(m_xdgPopup->shell(), &QWaylandXdgShellV5::xdgPopupCreated, this, [item](QWaylandXdgPopupV5 *popup) { + handlePopupCreated(item, popup); + }); } XdgPopupV5Integration::~XdgPopupV5Integration() diff --git a/src/compositor/extensions/qwaylandxdgshellv6integration.cpp b/src/compositor/extensions/qwaylandxdgshellv6integration.cpp index 17ee10db7..68230937f 100644 --- a/src/compositor/extensions/qwaylandxdgshellv6integration.cpp +++ b/src/compositor/extensions/qwaylandxdgshellv6integration.cpp @@ -44,6 +44,12 @@ QT_BEGIN_NAMESPACE namespace QtWayland { +static void handlePopupCreated(QWaylandQuickShellSurfaceItem *parentItem, QWaylandXdgPopupV6 *popup) +{ + if (parentItem->shellSurface() == popup->parentXdgSurface()) + QWaylandQuickShellSurfaceItemPrivate::get(parentItem)->maybeCreateAutoPopup(popup->xdgSurface()); +} + XdgToplevelV6Integration::XdgToplevelV6Integration(QWaylandQuickShellSurfaceItem *item) : QWaylandQuickShellIntegration(item) , m_item(item) @@ -54,12 +60,16 @@ XdgToplevelV6Integration::XdgToplevelV6Integration(QWaylandQuickShellSurfaceItem Q_ASSERT(m_toplevel); m_item->setSurface(m_xdgSurface->surface()); + connect(m_toplevel, &QWaylandXdgToplevelV6::startMove, this, &XdgToplevelV6Integration::handleStartMove); connect(m_toplevel, &QWaylandXdgToplevelV6::startResize, this, &XdgToplevelV6Integration::handleStartResize); connect(m_toplevel, &QWaylandXdgToplevelV6::setMaximized, this, &XdgToplevelV6Integration::handleSetMaximized); connect(m_toplevel, &QWaylandXdgToplevelV6::unsetMaximized, this, &XdgToplevelV6Integration::handleUnsetMaximized); connect(m_toplevel, &QWaylandXdgToplevelV6::maximizedChanged, this, &XdgToplevelV6Integration::handleMaximizedChanged); connect(m_toplevel, &QWaylandXdgToplevelV6::activatedChanged, this, &XdgToplevelV6Integration::handleActivatedChanged); + connect(m_xdgSurface->shell(), &QWaylandXdgShellV6::popupCreated, this, [item](QWaylandXdgPopupV6 *popup, QWaylandXdgSurfaceV6 *){ + handlePopupCreated(item, popup); + }); connect(m_xdgSurface->surface(), &QWaylandSurface::sizeChanged, this, &XdgToplevelV6Integration::handleSurfaceSizeChanged); } @@ -181,6 +191,9 @@ XdgPopupV6Integration::XdgPopupV6Integration(QWaylandQuickShellSurfaceItem *item handleGeometryChanged(); connect(m_popup, &QWaylandXdgPopupV6::configuredGeometryChanged, this, &XdgPopupV6Integration::handleGeometryChanged); + connect(m_xdgSurface->shell(), &QWaylandXdgShellV6::popupCreated, this, [item](QWaylandXdgPopupV6 *popup, QWaylandXdgSurfaceV6 *){ + handlePopupCreated(item, popup); + }); } void XdgPopupV6Integration::handleGeometryChanged() -- cgit v1.2.3