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 <paul.tvete@qt.io>
This commit is contained in:
Johan Klokkhammer Helsing 2016-11-03 16:32:20 +01:00 committed by Johan Helsing
parent 2744dfbb87
commit ff3c3ad9f6
2 changed files with 21 additions and 4 deletions

View File

@ -54,11 +54,13 @@ namespace QtWaylandClient {
QWaylandXdgShell::QWaylandXdgShell(struct ::xdg_shell *shell) QWaylandXdgShell::QWaylandXdgShell(struct ::xdg_shell *shell)
: QtWayland::xdg_shell(shell) : QtWayland::xdg_shell(shell)
, m_popupSerial(0)
{ {
} }
QWaylandXdgShell::QWaylandXdgShell(struct ::wl_registry *registry, uint32_t id) QWaylandXdgShell::QWaylandXdgShell(struct ::wl_registry *registry, uint32_t id)
: QtWayland::xdg_shell(registry, id, 1) : QtWayland::xdg_shell(registry, id, 1)
, m_popupSerial(0)
{ {
use_unstable_version(QtWayland::xdg_shell::version_current); use_unstable_version(QtWayland::xdg_shell::version_current);
} }
@ -75,15 +77,26 @@ QWaylandXdgSurface *QWaylandXdgShell::createXdgSurface(QWaylandWindow *window)
QWaylandXdgPopup *QWaylandXdgShell::createXdgPopup(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(); ::wl_surface *parentSurface = parentWindow->object();
QWaylandInputDevice *inputDevice = window->display()->lastInputDevice(); QWaylandInputDevice *inputDevice = window->display()->lastInputDevice();
if (m_popupSerial == 0)
m_popupSerial = inputDevice->serial();
::wl_seat *seat = inputDevice->wl_seat(); ::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 x = position.x() + parentWindow->frameMargins().left();
int y = position.y() + parentWindow->frameMargins().top(); 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) void QWaylandXdgShell::xdg_shell_ping(uint32_t serial)

View File

@ -52,6 +52,7 @@
// //
#include <QtCore/QSize> #include <QtCore/QSize>
#include <QtCore/QVector>
#include <wayland-client.h> #include <wayland-client.h>
@ -82,6 +83,9 @@ public:
private: private:
void xdg_shell_ping(uint32_t serial) Q_DECL_OVERRIDE; void xdg_shell_ping(uint32_t serial) Q_DECL_OVERRIDE;
QVector<QWaylandWindow *> m_popups;
uint m_popupSerial;
}; };
QT_END_NAMESPACE QT_END_NAMESPACE