summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohan Klokkhammer Helsing <johan.helsing@theqtcompany.com>2016-03-19 15:36:22 +0100
committerJohan Helsing <johan.helsing@qt.io>2016-09-20 08:15:55 +0000
commitb248defd1741cd443dd1e5050fe5143e8650a7c7 (patch)
tree1dc2b7a552ba2051cbf549b510fe6d0b6a5a3979
parentc7e417e8d552f3a6a10ac12f96119d083f081fc0 (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.cpp27
-rw-r--r--examples/wayland/qwindow-compositor/compositor.h3
-rw-r--r--src/compositor/extensions/qwaylandwlshell.cpp31
-rw-r--r--src/compositor/extensions/qwaylandwlshell.h5
-rw-r--r--src/compositor/extensions/qwaylandwlshellintegration.cpp35
-rw-r--r--src/compositor/extensions/qwaylandwlshellintegration_p.h3
-rw-r--r--src/compositor/extensions/qwaylandxdgshellv5.cpp10
-rw-r--r--src/compositor/extensions/qwaylandxdgshellv5.h1
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();