From c88b5f632c767bee17c8b8df60af3d11724b2e5b Mon Sep 17 00:00:00 2001 From: Johan Klokkhammer Helsing Date: Thu, 3 Nov 2016 16:32:20 +0100 Subject: Follow the protocol for nested xdg_popups The previous implementation sent the wrong parent for nested popups and used a new serial for each popup instead of reusing the one for the current grab. Change-Id: I22b1cbe997a64562d47275821c9146157c51bc42 Reviewed-by: Paul Olav Tvete --- src/client/qwaylandxdgshell.cpp | 21 +++++++++++++++++---- src/client/qwaylandxdgshell_p.h | 4 ++++ 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/client/qwaylandxdgshell.cpp b/src/client/qwaylandxdgshell.cpp index 6a378b8db..6a9930608 100644 --- a/src/client/qwaylandxdgshell.cpp +++ b/src/client/qwaylandxdgshell.cpp @@ -54,11 +54,13 @@ namespace QtWaylandClient { QWaylandXdgShell::QWaylandXdgShell(struct ::xdg_shell *shell) : QtWayland::xdg_shell(shell) + , m_popupSerial(0) { } QWaylandXdgShell::QWaylandXdgShell(struct ::wl_registry *registry, uint32_t id) : QtWayland::xdg_shell(registry, id, 1) + , m_popupSerial(0) { use_unstable_version(QtWayland::xdg_shell::version_current); } @@ -75,15 +77,26 @@ QWaylandXdgSurface *QWaylandXdgShell::createXdgSurface(QWaylandWindow *window) QWaylandXdgPopup *QWaylandXdgShell::createXdgPopup(QWaylandWindow *window) { - QWaylandWindow *parentWindow = window->transientParent(); + QWaylandWindow *parentWindow = m_popups.empty() ? window->transientParent() : m_popups.last(); ::wl_surface *parentSurface = parentWindow->object(); + QWaylandInputDevice *inputDevice = window->display()->lastInputDevice(); + if (m_popupSerial == 0) + m_popupSerial = inputDevice->serial(); ::wl_seat *seat = inputDevice->wl_seat(); - uint serial = inputDevice->serial(); - QPoint position = window->geometry().topLeft(); + + QPoint position = window->geometry().topLeft() - parentWindow->geometry().topLeft(); int x = position.x() + parentWindow->frameMargins().left(); int y = position.y() + parentWindow->frameMargins().top(); - return new QWaylandXdgPopup(get_xdg_popup(window->object(), parentSurface, seat, serial, x, y), window); + + auto popup = new QWaylandXdgPopup(get_xdg_popup(window->object(), parentSurface, seat, m_popupSerial, x, y), window); + m_popups.append(window); + QObject::connect(popup, &QWaylandXdgPopup::destroyed, [this, window](){ + m_popups.removeOne(window); + if (m_popups.empty()) + m_popupSerial = 0; + }); + return popup; } void QWaylandXdgShell::xdg_shell_ping(uint32_t serial) diff --git a/src/client/qwaylandxdgshell_p.h b/src/client/qwaylandxdgshell_p.h index c04a9ce66..8b35e36ab 100644 --- a/src/client/qwaylandxdgshell_p.h +++ b/src/client/qwaylandxdgshell_p.h @@ -52,6 +52,7 @@ // #include +#include #include @@ -82,6 +83,9 @@ public: private: void xdg_shell_ping(uint32_t serial) Q_DECL_OVERRIDE; + + QVector m_popups; + uint m_popupSerial; }; QT_END_NAMESPACE -- cgit v1.2.3