From b94be41409a6dfa58d8b3ae8413c6930e76fc040 Mon Sep 17 00:00:00 2001 From: Johan Klokkhammer Helsing <johan.helsing@theqtcompany.com> Date: Wed, 30 Mar 2016 15:13:44 +0200 Subject: [PATCH] Client: Don't create shell surfaces for QShapedPixmapWindow QShapedPixmapWindow is used as a drag-and-drop icon. This caused two roles (wl_data_device-icon and wl_shell_surface) to be assigned to the same surface, resulting in a protocol error. This bug hasn't been encountered before because QShapedPixmapWindow sets X11BypassWindowManagerHint, which was previously used to determine whether to create a shell surface or not. Task-number: QTBUG-52052 Change-Id: I1d79f3ec8ad08e0be1551c39df6232876dc2ac2e Reviewed-by: Giulio Camuffo <giulio.camuffo@kdab.com> Reviewed-by: Erik Larsson <erik@ortogonal.com> --- src/client/qwaylandwindow.cpp | 25 ++++++++++++++++++++++--- src/client/qwaylandwindow_p.h | 2 ++ 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp index 68fea2fac..2dd58e89c 100644 --- a/src/client/qwaylandwindow.cpp +++ b/src/client/qwaylandwindow.cpp @@ -116,13 +116,13 @@ QWaylandWindow::~QWaylandWindow() void QWaylandWindow::initWindow() { init(mDisplay->createSurface(static_cast<QtWayland::wl_surface *>(this))); - if (QPlatformWindow::parent()) { + + if (shouldCreateSubSurface()) { QWaylandWindow *p = static_cast<QWaylandWindow *>(QPlatformWindow::parent()); if (::wl_subsurface *ss = mDisplay->createSubSurface(this, p)) { mSubSurfaceWindow = new QWaylandSubSurface(this, p, ss); } - } else if (!(qEnvironmentVariableIsSet("QT_WAYLAND_USE_BYPASSWINDOWMANAGERHINT") && - window()->flags() & Qt::BypassWindowManagerHint)) { + } else if (shouldCreateShellSurface()) { mShellSurface = mDisplay->createShellSurface(this); } @@ -176,6 +176,25 @@ void QWaylandWindow::initWindow() handleContentOrientationChange(window()->contentOrientation()); } +bool QWaylandWindow::shouldCreateShellSurface() const +{ + if (shouldCreateSubSurface()) + return false; + + if (window()->inherits("QShapedPixmapWindow")) + return false; + + if (qEnvironmentVariableIsSet("QT_WAYLAND_USE_BYPASSWINDOWMANAGERHINT")) + return window()->flags() & Qt::BypassWindowManagerHint; + + return true; +} + +bool QWaylandWindow::shouldCreateSubSurface() const +{ + return QPlatformWindow::parent() != Q_NULLPTR; +} + void QWaylandWindow::reset() { delete mShellSurface; diff --git a/src/client/qwaylandwindow_p.h b/src/client/qwaylandwindow_p.h index a905641f3..6e271cc10 100644 --- a/src/client/qwaylandwindow_p.h +++ b/src/client/qwaylandwindow_p.h @@ -234,6 +234,8 @@ private: bool setWindowStateInternal(Qt::WindowState flags); void setGeometry_helper(const QRect &rect); void initWindow(); + bool shouldCreateShellSurface() const; + bool shouldCreateSubSurface() const; void reset(); void handleMouseEventWithDecoration(QWaylandInputDevice *inputDevice, const QWaylandPointerEvent &e); -- GitLab