diff options
author | Johan Klokkhammer Helsing <johan.helsing@theqtcompany.com> | 2016-03-19 15:36:22 +0100 |
---|---|---|
committer | Johan Helsing <johan.helsing@qt.io> | 2016-09-20 08:15:55 +0000 |
commit | b248defd1741cd443dd1e5050fe5143e8650a7c7 (patch) | |
tree | 1dc2b7a552ba2051cbf549b510fe6d0b6a5a3979 | |
parent | c7e417e8d552f3a6a10ac12f96119d083f081fc0 (diff) |
Compositor API: Add closeAllPopups method to QWaylandWlShell
The WlShell implementation now matches xdg shell. Also adds a
convenience method to QWaylandWlShell to get all popups.
QWaylandWlShellIntegration and qwindow-compositor uses this new API.
Change-Id: Ibfe3323ad7f56d43379785582b9be6801905a485
Reviewed-by: Pier Luigi Fiorini <pierluigi.fiorini@hawaiios.org>
-rw-r--r-- | examples/wayland/qwindow-compositor/compositor.cpp | 27 | ||||
-rw-r--r-- | examples/wayland/qwindow-compositor/compositor.h | 3 | ||||
-rw-r--r-- | src/compositor/extensions/qwaylandwlshell.cpp | 31 | ||||
-rw-r--r-- | src/compositor/extensions/qwaylandwlshell.h | 5 | ||||
-rw-r--r-- | src/compositor/extensions/qwaylandwlshellintegration.cpp | 35 | ||||
-rw-r--r-- | src/compositor/extensions/qwaylandwlshellintegration_p.h | 3 | ||||
-rw-r--r-- | src/compositor/extensions/qwaylandxdgshellv5.cpp | 10 | ||||
-rw-r--r-- | src/compositor/extensions/qwaylandxdgshellv5.h | 1 |
8 files changed, 70 insertions, 45 deletions
diff --git a/examples/wayland/qwindow-compositor/compositor.cpp b/examples/wayland/qwindow-compositor/compositor.cpp index 9d608d404..eed270cd6 100644 --- a/examples/wayland/qwindow-compositor/compositor.cpp +++ b/examples/wayland/qwindow-compositor/compositor.cpp @@ -193,13 +193,6 @@ void Compositor::surfaceHasContentChanged() || surface->role() == QWaylandXdgPopupV5::role()) { defaultSeat()->setKeyboardFocus(surface); } - } else if (popupActive()) { - for (int i = 0; i < m_popupViews.count(); i++) { - if (m_popupViews.at(i)->surface() == surface) { - m_popupViews.removeAt(i); - break; - } - } } triggerRender(); } @@ -308,7 +301,6 @@ void Compositor::onSetPopup(QWaylandSeat *seat, QWaylandSurface *parent, const Q Q_UNUSED(seat); QWaylandWlShellSurface *surface = qobject_cast<QWaylandWlShellSurface*>(sender()); View *view = findView(surface->surface()); - m_popupViews << view; if (view) { raise(view); View *parentView = findView(parent); @@ -380,21 +372,18 @@ void Compositor::adjustCursorSurface(QWaylandSurface *surface, int hotspotX, int void Compositor::closePopups() { - Q_FOREACH (View *view, m_popupViews) { - if (view->m_wlShellSurface) - view->m_wlShellSurface->sendPopupDone(); - } - m_popupViews.clear(); - + m_wlShell->closeAllPopups(); m_xdgShell->closeAllPopups(); } void Compositor::handleMouseEvent(QWaylandView *target, QMouseEvent *me) { - if (target && popupActive() && me->type() == QEvent::MouseButtonPress - && target->surface()->client() != m_popupViews.first()->surface()->client()) { + auto popClient = popupClient(); + if (target && me->type() == QEvent::MouseButtonPress + && popClient && popClient != target->surface()->client()) { closePopups(); } + QWaylandSeat *input = defaultSeat(); QWaylandSurface *surface = target ? target->surface() : nullptr; switch (me->type()) { @@ -462,6 +451,12 @@ void Compositor::handleDrag(View *target, QMouseEvent *me) } } +QWaylandClient *Compositor::popupClient() const +{ + auto client = m_wlShell->popupClient(); + return client ? client : m_xdgShell->popupClient(); +} + // We only have a flat list of views, plus pointers from child to parent, // so maintaining a stacking order gets a bit complex. A better data // structure is left as an exercise for the reader. diff --git a/examples/wayland/qwindow-compositor/compositor.h b/examples/wayland/qwindow-compositor/compositor.h index cfeccffda..636def97e 100644 --- a/examples/wayland/qwindow-compositor/compositor.h +++ b/examples/wayland/qwindow-compositor/compositor.h @@ -107,7 +107,7 @@ public: void handleResize(View *target, const QSize &initialSize, const QPoint &delta, int edge); void handleDrag(View *target, QMouseEvent *me); - bool popupActive() const { return !m_popupViews.isEmpty(); } + QWaylandClient *popupClient() const; void closePopups(); protected: void adjustCursorSurface(QWaylandSurface *surface, int hotspotX, int hotspotY); @@ -146,7 +146,6 @@ private: View *findView(const QWaylandSurface *s) const; QWindow *m_window; QList<View*> m_views; - QList<View*> m_popupViews; QWaylandWlShell *m_wlShell; QWaylandXdgShellV5 *m_xdgShell; QWaylandView m_cursorView; diff --git a/src/compositor/extensions/qwaylandwlshell.cpp b/src/compositor/extensions/qwaylandwlshell.cpp index a1313a6c2..97d2b3958 100644 --- a/src/compositor/extensions/qwaylandwlshell.cpp +++ b/src/compositor/extensions/qwaylandwlshell.cpp @@ -350,6 +350,37 @@ QList<QWaylandWlShellSurface *> QWaylandWlShell::shellSurfacesForClient(QWayland return surfsForClient; } +QList<QWaylandWlShellSurface *> QWaylandWlShell::mappedPopups() const +{ + Q_D(const QWaylandWlShell); + QList<QWaylandWlShellSurface *> popupSurfaces; + Q_FOREACH (QWaylandWlShellSurface *shellSurface, d->m_shellSurfaces) { + if (shellSurface->windowType() == Qt::WindowType::Popup + && shellSurface->surface()->hasContent()) { + popupSurfaces.append(shellSurface); + } + } + return popupSurfaces; +} + +QWaylandClient *QWaylandWlShell::popupClient() const +{ + Q_D(const QWaylandWlShell); + Q_FOREACH (QWaylandWlShellSurface *shellSurface, d->m_shellSurfaces) { + if (shellSurface->windowType() == Qt::WindowType::Popup + && shellSurface->surface()->hasContent()) { + return shellSurface->surface()->client(); + } + } + return nullptr; +} + +void QWaylandWlShell::closeAllPopups() +{ + Q_FOREACH (QWaylandWlShellSurface* shellSurface, mappedPopups()) + shellSurface->sendPopupDone(); +} + /*! * Returns the Wayland interface for the QWaylandWlShell. */ diff --git a/src/compositor/extensions/qwaylandwlshell.h b/src/compositor/extensions/qwaylandwlshell.h index c2d40a87c..e6cbf2268 100644 --- a/src/compositor/extensions/qwaylandwlshell.h +++ b/src/compositor/extensions/qwaylandwlshell.h @@ -65,10 +65,15 @@ public: void initialize() Q_DECL_OVERRIDE; QList<QWaylandWlShellSurface *> shellSurfaces() const; QList<QWaylandWlShellSurface *> shellSurfacesForClient(QWaylandClient* client) const; + QList<QWaylandWlShellSurface *> mappedPopups() const; + QWaylandClient *popupClient() const; static const struct wl_interface *interface(); static QByteArray interfaceName(); +public Q_SLOTS: + void closeAllPopups(); + Q_SIGNALS: void wlShellSurfaceRequested(QWaylandSurface *surface, const QWaylandResource &resource); void wlShellSurfaceCreated(QWaylandWlShellSurface *shellSurface); diff --git a/src/compositor/extensions/qwaylandwlshellintegration.cpp b/src/compositor/extensions/qwaylandwlshellintegration.cpp index 1acc01dd7..ba2fe5fb4 100644 --- a/src/compositor/extensions/qwaylandwlshellintegration.cpp +++ b/src/compositor/extensions/qwaylandwlshellintegration.cpp @@ -56,6 +56,7 @@ WlShellIntegration::WlShellIntegration(QWaylandQuickShellSurfaceItem *item) connect(m_shellSurface, &QWaylandWlShellSurface::startMove, this, &WlShellIntegration::handleStartMove); connect(m_shellSurface, &QWaylandWlShellSurface::startResize, this, &WlShellIntegration::handleStartResize); connect(m_shellSurface->surface(), &QWaylandSurface::offsetForNextFrame, this, &WlShellIntegration::adjustOffsetForNextFrame); + connect(m_shellSurface->surface(), &QWaylandSurface::hasContentChanged, this, &WlShellIntegration::handleSurfaceHasContentChanged); connect(m_shellSurface, &QWaylandWlShellSurface::setPopup, this, &WlShellIntegration::handleSetPopup); connect(m_shellSurface, &QWaylandWlShellSurface::destroyed, this, &WlShellIntegration::handleShellSurfaceDestroyed); } @@ -107,13 +108,12 @@ void WlShellIntegration::handleSetPopup(QWaylandSeat *seat, QWaylandSurface *par } isPopup = true; - QWaylandQuickShellEventFilter::startFilter(m_shellSurface->surface()->client(), &closePopups); + QWaylandQuickShellEventFilter::startFilter(m_shellSurface->surface()->client(), [&]() { + m_shellSurface->shell()->closeAllPopups(); + }); - if (!popupShellSurfaces.contains(m_shellSurface)) { - popupShellSurfaces.append(m_shellSurface); - QObject::connect(m_shellSurface->surface(), &QWaylandSurface::hasContentChanged, - this, &WlShellIntegration::handleSurfaceHasContentChanged); - } + QObject::connect(m_shellSurface->surface(), &QWaylandSurface::hasContentChanged, + this, &WlShellIntegration::handleSurfaceHasContentChanged); } void WlShellIntegration::handlePopupClosed() @@ -126,9 +126,7 @@ void WlShellIntegration::handlePopupClosed() void WlShellIntegration::handlePopupRemoved() { - if (m_shellSurface) - popupShellSurfaces.removeOne(m_shellSurface); - if (popupShellSurfaces.isEmpty()) + if (m_shellSurface->shell()->mappedPopups().isEmpty()) QWaylandQuickShellEventFilter::cancelFilter(); isPopup = false; } @@ -143,9 +141,10 @@ void WlShellIntegration::handleShellSurfaceDestroyed() void WlShellIntegration::handleSurfaceHasContentChanged() { - if (!m_shellSurface || !m_shellSurface->surface()->size().isEmpty()) - return; - handlePopupClosed(); + if (m_shellSurface && m_shellSurface->surface()->size().isEmpty() + && m_shellSurface->windowType() == Qt::WindowType::Popup) { + handlePopupClosed(); + } } void WlShellIntegration::adjustOffsetForNextFrame(const QPointF &offset) @@ -194,18 +193,6 @@ bool WlShellIntegration::mouseReleaseEvent(QMouseEvent *event) return false; } -QVector<QWaylandWlShellSurface*> WlShellIntegration::popupShellSurfaces; - -void WlShellIntegration::closePopups() -{ - if (!popupShellSurfaces.isEmpty()) { - Q_FOREACH (QWaylandWlShellSurface* shellSurface, popupShellSurfaces) { - shellSurface->sendPopupDone(); - } - popupShellSurfaces.clear(); - } -} - } QT_END_NAMESPACE diff --git a/src/compositor/extensions/qwaylandwlshellintegration_p.h b/src/compositor/extensions/qwaylandwlshellintegration_p.h index f68040cdf..7d965ff07 100644 --- a/src/compositor/extensions/qwaylandwlshellintegration_p.h +++ b/src/compositor/extensions/qwaylandwlshellintegration_p.h @@ -82,8 +82,6 @@ private: void handlePopupClosed(); void handlePopupRemoved(); - static void closePopups(); - QWaylandQuickShellSurfaceItem *m_item; QWaylandWlShellSurface *m_shellSurface; GrabberState grabberState; @@ -100,7 +98,6 @@ private: bool initialized; } resizeState; - static QVector<QWaylandWlShellSurface*> popupShellSurfaces; bool isPopup; }; diff --git a/src/compositor/extensions/qwaylandxdgshellv5.cpp b/src/compositor/extensions/qwaylandxdgshellv5.cpp index 284aa8b05..a14f58e05 100644 --- a/src/compositor/extensions/qwaylandxdgshellv5.cpp +++ b/src/compositor/extensions/qwaylandxdgshellv5.cpp @@ -531,6 +531,16 @@ void QWaylandXdgShellV5::initialize() this, &QWaylandXdgShellV5::handleSeatChanged); } +QWaylandClient *QWaylandXdgShellV5::popupClient() const +{ + Q_D(const QWaylandXdgShellV5); + Q_FOREACH (QWaylandXdgPopupV5 *popup, d->m_xdgPopups) { + if (popup->surface()->hasContent()) + return popup->surface()->client(); + } + return nullptr; +} + /*! * Returns the Wayland interface for the QWaylandXdgShellV5. */ diff --git a/src/compositor/extensions/qwaylandxdgshellv5.h b/src/compositor/extensions/qwaylandxdgshellv5.h index c99f36282..605701dd2 100644 --- a/src/compositor/extensions/qwaylandxdgshellv5.h +++ b/src/compositor/extensions/qwaylandxdgshellv5.h @@ -68,6 +68,7 @@ public: QWaylandXdgShellV5(QWaylandCompositor *compositor); void initialize() Q_DECL_OVERRIDE; + QWaylandClient *popupClient() const; static const struct wl_interface *interface(); static QByteArray interfaceName(); |