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>
This commit is contained in:
Johan Klokkhammer Helsing 2016-03-30 15:13:44 +02:00 committed by Johan Helsing
parent e7ba33c0ec
commit d77d934874
2 changed files with 24 additions and 3 deletions

View File

@ -116,13 +116,13 @@ QWaylandWindow::~QWaylandWindow()
void QWaylandWindow::initWindow() void QWaylandWindow::initWindow()
{ {
init(mDisplay->createSurface(static_cast<QtWayland::wl_surface *>(this))); init(mDisplay->createSurface(static_cast<QtWayland::wl_surface *>(this)));
if (QPlatformWindow::parent()) {
if (shouldCreateSubSurface()) {
QWaylandWindow *p = static_cast<QWaylandWindow *>(QPlatformWindow::parent()); QWaylandWindow *p = static_cast<QWaylandWindow *>(QPlatformWindow::parent());
if (::wl_subsurface *ss = mDisplay->createSubSurface(this, p)) { if (::wl_subsurface *ss = mDisplay->createSubSurface(this, p)) {
mSubSurfaceWindow = new QWaylandSubSurface(this, p, ss); mSubSurfaceWindow = new QWaylandSubSurface(this, p, ss);
} }
} else if (!(qEnvironmentVariableIsSet("QT_WAYLAND_USE_BYPASSWINDOWMANAGERHINT") && } else if (shouldCreateShellSurface()) {
window()->flags() & Qt::BypassWindowManagerHint)) {
mShellSurface = mDisplay->createShellSurface(this); mShellSurface = mDisplay->createShellSurface(this);
} }
@ -176,6 +176,25 @@ void QWaylandWindow::initWindow()
handleContentOrientationChange(window()->contentOrientation()); 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() void QWaylandWindow::reset()
{ {
delete mShellSurface; delete mShellSurface;

View File

@ -234,6 +234,8 @@ private:
bool setWindowStateInternal(Qt::WindowState flags); bool setWindowStateInternal(Qt::WindowState flags);
void setGeometry_helper(const QRect &rect); void setGeometry_helper(const QRect &rect);
void initWindow(); void initWindow();
bool shouldCreateShellSurface() const;
bool shouldCreateSubSurface() const;
void reset(); void reset();
void handleMouseEventWithDecoration(QWaylandInputDevice *inputDevice, const QWaylandPointerEvent &e); void handleMouseEventWithDecoration(QWaylandInputDevice *inputDevice, const QWaylandPointerEvent &e);