summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@qt.io>2017-09-20 11:38:52 +0200
committerLiang Qi <liang.qi@qt.io>2017-09-20 11:38:52 +0200
commit20ebb685e0fef048e56ed19403575634ce4b3435 (patch)
tree6ad6fedfbe4d361e40a0307f1f0cdc39044b53b6
parente1f89e15cf00420bd77ac16a867a1cadc9b942fc (diff)
parent3cb09edd71745edda4bbe8de3a6d7ad8e4ea5f58 (diff)
Merge remote-tracking branch 'origin/5.9' into 5.10
-rw-r--r--dist/changes-5.6.331
-rw-r--r--src/client/qwaylandintegration.cpp2
-rw-r--r--src/client/qwaylandscreen.cpp6
-rw-r--r--src/client/qwaylandscreen_p.h1
-rw-r--r--src/client/qwaylandwindow.cpp97
-rw-r--r--src/client/qwaylandwindow_p.h15
-rw-r--r--src/compositor/compositor_api/qwaylandpointer.cpp90
-rw-r--r--src/compositor/compositor_api/qwaylandpointer_p.h6
-rw-r--r--src/compositor/compositor_api/qwaylandtouch.h3
-rw-r--r--src/compositor/extensions/qwaylandquickshellsurfaceitem.cpp13
-rw-r--r--tests/auto/client/client/tst_client.cpp27
11 files changed, 229 insertions, 62 deletions
diff --git a/dist/changes-5.6.3 b/dist/changes-5.6.3
new file mode 100644
index 000000000..9312b6367
--- /dev/null
+++ b/dist/changes-5.6.3
@@ -0,0 +1,31 @@
+Qt 5.6.3 is a bug-fix release. It maintains both forward and backward
+compatibility (source and binary) with Qt 5.6.0.
+
+For more details, refer to the online documentation included in this
+distribution. The documentation is also available online:
+
+ http://doc.qt.io/qt-5/index.html
+
+The Qt version 5.6 series is binary compatible with the 5.5.x series.
+Applications compiled for 5.5 will continue to run with 5.6.
+
+Some of the changes listed in this file include issue tracking numbers
+corresponding to tasks in the Qt Bug Tracker:
+
+ https://bugreports.qt.io/
+
+Each of these identifiers can be entered in the bug tracker to obtain more
+information about a particular change.
+
+
+Qt Wayland QPA Plugin
+---------------------
+
+ - [QTBUG-56187] Fixed an issue where dragging with the mouse would cause the
+ next touch event to not generate a synthesized mouse press event.
+ - [QTBUG-56187] Fixed touch input getting stuck after drag-and-drop.
+ - [QTBUG-56192] Fixed build issues when some features are disabled (clipboard,
+ draganddrop, sessionmanager, opengl, accessibility).
+ - [QTBUG-52118] Fixed subsurface positions sometimes not being committed.
+ - [QTBUG-55343] Window decorations are now removed and added when toggling
+ fullscreen.
diff --git a/src/client/qwaylandintegration.cpp b/src/client/qwaylandintegration.cpp
index 400f3517c..bffadf29a 100644
--- a/src/client/qwaylandintegration.cpp
+++ b/src/client/qwaylandintegration.cpp
@@ -359,7 +359,7 @@ void QWaylandIntegration::initializeServerBufferIntegration()
disableHardwareIntegration = disableHardwareIntegration || !mDisplay->hardwareIntegration();
if (disableHardwareIntegration) {
QByteArray serverBufferIntegrationName = qgetenv("QT_WAYLAND_SERVER_BUFFER_INTEGRATION");
- QString targetKey = QString::fromLocal8Bit(serverBufferIntegrationName);
+ targetKey = QString::fromLocal8Bit(serverBufferIntegrationName);
} else {
targetKey = mDisplay->hardwareIntegration()->serverBufferIntegration();
}
diff --git a/src/client/qwaylandscreen.cpp b/src/client/qwaylandscreen.cpp
index 7f12a4214..5b43428d9 100644
--- a/src/client/qwaylandscreen.cpp
+++ b/src/client/qwaylandscreen.cpp
@@ -185,6 +185,12 @@ QWaylandScreen * QWaylandScreen::waylandScreenFromWindow(QWindow *window)
return static_cast<QWaylandScreen *>(platformScreen);
}
+QWaylandScreen *QWaylandScreen::fromWlOutput(::wl_output *output)
+{
+ auto wlOutput = static_cast<QtWayland::wl_output *>(wl_output_get_user_data(output));
+ return static_cast<QWaylandScreen *>(wlOutput);
+}
+
void QWaylandScreen::output_mode(uint32_t flags, int width, int height, int refresh)
{
if (!(flags & WL_OUTPUT_MODE_CURRENT))
diff --git a/src/client/qwaylandscreen_p.h b/src/client/qwaylandscreen_p.h
index 526c94878..674e1a913 100644
--- a/src/client/qwaylandscreen_p.h
+++ b/src/client/qwaylandscreen_p.h
@@ -102,6 +102,7 @@ public:
::wl_output *output() { return object(); }
static QWaylandScreen *waylandScreenFromWindow(QWindow *window);
+ static QWaylandScreen *fromWlOutput(::wl_output *output);
private:
void output_mode(uint32_t flags, int width, int height, int refresh) override;
diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp
index 9cc673c0c..cac92a7e1 100644
--- a/src/client/qwaylandwindow.cpp
+++ b/src/client/qwaylandwindow.cpp
@@ -69,6 +69,8 @@
#include <QtCore/QDebug>
+#include <wayland-client-core.h>
+
QT_BEGIN_NAMESPACE
namespace QtWaylandClient {
@@ -78,15 +80,13 @@ QWaylandWindow *QWaylandWindow::mMouseGrab = 0;
QWaylandWindow::QWaylandWindow(QWindow *window)
: QObject()
, QPlatformWindow(window)
- , mScreen(QWaylandScreen::waylandScreenFromWindow(window))
- , mDisplay(mScreen->display())
+ , mDisplay(screen()->display())
, mShellSurface(0)
, mSubSurfaceWindow(0)
, mWindowDecoration(0)
, mMouseEventsInContentArea(false)
, mMousePressedInContentArea(Qt::NoButton)
, mWaitingForFrameSync(false)
- , mFrameCallback(nullptr)
, mRequestResizeSent(false)
, mCanResize(true)
, mResizeDirty(false)
@@ -100,6 +100,7 @@ QWaylandWindow::QWaylandWindow(QWindow *window)
{
static WId id = 1;
mWindowId = id++;
+ connect(qApp, &QGuiApplication::screenRemoved, this, &QWaylandWindow::handleScreenRemoved);
initializeWlSurface();
}
@@ -349,9 +350,31 @@ void QWaylandWindow::sendExposeEvent(const QRect &rect)
QWindowSystemInterface::handleExposeEvent(window(), rect);
}
+
+static QVector<QPointer<QWaylandWindow>> activePopups;
+
+void QWaylandWindow::closePopups(QWaylandWindow *parent)
+{
+ while (!activePopups.isEmpty()) {
+ auto popup = activePopups.takeLast();
+ if (popup.isNull())
+ continue;
+ if (popup.data() == parent)
+ return;
+ popup->reset();
+ }
+}
+
+QWaylandScreen *QWaylandWindow::calculateScreenFromSurfaceEvents() const
+{
+ return mScreens.isEmpty() ? screen() : mScreens.first();
+}
+
void QWaylandWindow::setVisible(bool visible)
{
if (visible) {
+ if (window()->type() == Qt::Popup)
+ activePopups << this;
initWindow();
mDisplay->flushRequests();
@@ -365,6 +388,8 @@ void QWaylandWindow::setVisible(bool visible)
// case 'this' will be deleted. When that happens, we must abort right away.
QPointer<QWaylandWindow> deleteGuard(this);
QWindowSystemInterface::flushWindowSystemEvents();
+ if (!deleteGuard.isNull() && window()->type() == Qt::Popup)
+ closePopups(this);
if (!deleteGuard.isNull())
reset();
}
@@ -480,14 +505,63 @@ void QWaylandWindow::requestResize()
QWindowSystemInterface::flushWindowSystemEvents();
}
+void QWaylandWindow::surface_enter(wl_output *output)
+{
+ QWaylandScreen *oldScreen = calculateScreenFromSurfaceEvents();
+ auto addedScreen = QWaylandScreen::fromWlOutput(output);
+
+ if (mScreens.contains(addedScreen)) {
+ qWarning() << "Unexpected wl_surface.enter received for output with id:"
+ << wl_proxy_get_id(reinterpret_cast<wl_proxy *>(output))
+ << "screen name:" << addedScreen->name() << "screen model:" << addedScreen->model();
+ return;
+ }
+
+ mScreens.append(addedScreen);
+
+ QWaylandScreen *newScreen = calculateScreenFromSurfaceEvents();
+ if (oldScreen != newScreen) //currently this will only happen if the first wl_surface.enter is for a non-primary screen
+ QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->QPlatformScreen::screen());
+}
+
+void QWaylandWindow::surface_leave(wl_output *output)
+{
+ QWaylandScreen *oldScreen = calculateScreenFromSurfaceEvents();
+ auto *removedScreen = QWaylandScreen::fromWlOutput(output);
+ bool wasRemoved = mScreens.removeOne(removedScreen);
+ if (!wasRemoved) {
+ qWarning() << "Unexpected wl_surface.leave received for output with id:"
+ << wl_proxy_get_id(reinterpret_cast<wl_proxy *>(output))
+ << "screen name:" << removedScreen->name() << "screen model:" << removedScreen->model();
+ return;
+ }
+
+ QWaylandScreen *newScreen = calculateScreenFromSurfaceEvents();
+ if (oldScreen != newScreen)
+ QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->QPlatformScreen::screen());
+}
+
+void QWaylandWindow::handleScreenRemoved(QScreen *qScreen)
+{
+ QWaylandScreen *oldScreen = calculateScreenFromSurfaceEvents();
+ bool wasRemoved = mScreens.removeOne(static_cast<QWaylandScreen *>(qScreen->handle()));
+ if (wasRemoved) {
+ QWaylandScreen *newScreen = calculateScreenFromSurfaceEvents();
+ if (oldScreen != newScreen)
+ QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->QPlatformScreen::screen());
+ }
+}
+
void QWaylandWindow::attach(QWaylandBuffer *buffer, int x, int y)
{
- mFrameCallback = nullptr;
+ if (mFrameCallback) {
+ wl_callback_destroy(mFrameCallback);
+ mFrameCallback = nullptr;
+ }
if (buffer) {
- auto callback = frame();
- wl_callback_add_listener(callback, &QWaylandWindow::callbackListener, this);
- mFrameCallback = callback;
+ mFrameCallback = frame();
+ wl_callback_add_listener(mFrameCallback, &QWaylandWindow::callbackListener, this);
mWaitingForFrameSync = true;
buffer->setBusy();
@@ -530,8 +604,6 @@ void QWaylandWindow::frameCallback(void *data, struct wl_callback *callback, uin
QWaylandWindow *self = static_cast<QWaylandWindow*>(data);
self->mWaitingForFrameSync = false;
- wl_callback_destroy(callback);
- self->mFrameCallback.testAndSetRelaxed(callback, nullptr);
if (self->mUpdateRequested) {
QWindowPrivate *w = QWindowPrivate::get(self->window());
self->mUpdateRequested = false;
@@ -568,6 +640,11 @@ QWaylandSubSurface *QWaylandWindow::subSurfaceWindow() const
return mSubSurfaceWindow;
}
+QWaylandScreen *QWaylandWindow::screen() const
+{
+ return static_cast<QWaylandScreen *>(QPlatformWindow::screen());
+}
+
void QWaylandWindow::handleContentOrientationChange(Qt::ScreenOrientation orientation)
{
if (mDisplay->compositorVersion() < 2)
@@ -832,7 +909,7 @@ void QWaylandWindow::handleMouseEventWithDecoration(QWaylandInputDevice *inputDe
#if QT_CONFIG(cursor)
void QWaylandWindow::setMouseCursor(QWaylandInputDevice *device, const QCursor &cursor)
{
- device->setCursor(cursor, mScreen);
+ device->setCursor(cursor, screen());
}
void QWaylandWindow::restoreMouseCursor(QWaylandInputDevice *device)
diff --git a/src/client/qwaylandwindow_p.h b/src/client/qwaylandwindow_p.h
index 9f6ff5b4e..961b7881d 100644
--- a/src/client/qwaylandwindow_p.h
+++ b/src/client/qwaylandwindow_p.h
@@ -53,7 +53,6 @@
#include <QtCore/QWaitCondition>
#include <QtCore/QMutex>
-#include <QtCore/QAtomicPointer>
#include <QtGui/QIcon>
#include <QtCore/QVariant>
@@ -143,7 +142,7 @@ public:
QWaylandDisplay *display() const { return mDisplay; }
QWaylandShellSurface *shellSurface() const;
QWaylandSubSurface *subSurfaceWindow() const;
- QWaylandScreen *screen() const { return mScreen; }
+ QWaylandScreen *screen() const;
void handleContentOrientationChange(Qt::ScreenOrientation orientation) override;
void setOrientationMask(Qt::ScreenOrientations mask);
@@ -210,7 +209,10 @@ public slots:
void requestResize();
protected:
- QWaylandScreen *mScreen;
+ void surface_enter(struct ::wl_output *output) override;
+ void surface_leave(struct ::wl_output *output) override;
+
+ QVector<QWaylandScreen *> mScreens; //As seen by wl_surface.enter/leave events. Chronological order.
QWaylandDisplay *mDisplay;
QWaylandShellSurface *mShellSurface;
QWaylandSubSurface *mSubSurfaceWindow;
@@ -222,7 +224,7 @@ protected:
WId mWindowId;
bool mWaitingForFrameSync;
- QAtomicPointer<struct wl_callback> mFrameCallback;
+ struct ::wl_callback *mFrameCallback = nullptr;
QWaitCondition mFrameSyncWait;
QMutex mResizeLock;
@@ -245,6 +247,9 @@ protected:
QWaylandShmBackingStore *mBackingStore;
+private slots:
+ void handleScreenRemoved(QScreen *qScreen);
+
private:
bool setWindowStateInternal(Qt::WindowStates flags);
void setGeometry_helper(const QRect &rect);
@@ -254,6 +259,8 @@ private:
bool shouldCreateSubSurface() const;
void reset(bool sendDestroyEvent = true);
void sendExposeEvent(const QRect &rect);
+ static void closePopups(QWaylandWindow *parent);
+ QWaylandScreen *calculateScreenFromSurfaceEvents() const;
void handleMouseEventWithDecoration(QWaylandInputDevice *inputDevice, const QWaylandPointerEvent &e);
diff --git a/src/compositor/compositor_api/qwaylandpointer.cpp b/src/compositor/compositor_api/qwaylandpointer.cpp
index 267b5d980..d1ca174db 100644
--- a/src/compositor/compositor_api/qwaylandpointer.cpp
+++ b/src/compositor/compositor_api/qwaylandpointer.cpp
@@ -51,17 +51,29 @@ QWaylandPointerPrivate::QWaylandPointerPrivate(QWaylandPointer *pointer, QWaylan
, wl_pointer()
, seat(seat)
, output()
- , focusResource()
, hasSentEnter(false)
+ , enterSerial(0)
, buttonCount()
{
Q_UNUSED(pointer);
}
-void QWaylandPointerPrivate::pointer_destroy_resource(wl_pointer::Resource *resource)
+const QList<QtWaylandServer::wl_pointer::Resource *> QWaylandPointerPrivate::pointerResourcesForFocusedSurface() const
{
- if (focusResource == resource->handle)
- focusResource = 0;
+ if (!seat->mouseFocus())
+ return {};
+
+ return resourceMap().values(seat->mouseFocus()->surfaceResource()->client);
+}
+
+uint QWaylandPointerPrivate::sendButton(Qt::MouseButton button, uint32_t state)
+{
+ Q_Q(QWaylandPointer);
+ uint32_t time = compositor()->currentTimeMsecs();
+ uint32_t serial = compositor()->nextSerial();
+ for (auto resource : pointerResourcesForFocusedSurface())
+ send_button(resource->handle, serial, time, q->toWaylandButton(button), state);
+ return serial;
}
void QWaylandPointerPrivate::pointer_release(wl_pointer::Resource *resource)
@@ -160,12 +172,11 @@ void QWaylandPointer::setOutput(QWaylandOutput *output)
uint QWaylandPointer::sendMousePressEvent(Qt::MouseButton button)
{
Q_D(QWaylandPointer);
- uint32_t time = d->compositor()->currentTimeMsecs();
d->buttonCount++;
uint serial = 0;
- if (d->focusResource)
- serial = sendButton(d->focusResource, time, button, WL_POINTER_BUTTON_STATE_PRESSED);
+ if (d->seat->mouseFocus())
+ serial = d->sendButton(button, WL_POINTER_BUTTON_STATE_PRESSED);
if (d->buttonCount == 1) {
emit buttonPressedChanged();
@@ -182,12 +193,11 @@ uint QWaylandPointer::sendMousePressEvent(Qt::MouseButton button)
uint QWaylandPointer::sendMouseReleaseEvent(Qt::MouseButton button)
{
Q_D(QWaylandPointer);
- uint32_t time = d->compositor()->currentTimeMsecs();
d->buttonCount--;
uint serial = 0;
- if (d->focusResource)
- serial = sendButton(d->focusResource, time, button, WL_POINTER_BUTTON_STATE_RELEASED);
+ if (d->seat->mouseFocus())
+ serial = d->sendButton(button, WL_POINTER_BUTTON_STATE_RELEASED);
if (d->buttonCount == 0)
emit buttonPressedChanged();
@@ -219,31 +229,30 @@ void QWaylandPointer::sendMouseMoveEvent(QWaylandView *view, const QPointF &loca
d->localPosition.ry() -= 0.01;
}
- QWaylandPointerPrivate::Resource *resource = view ? d->resourceMap().value(view->surface()->waylandClient()) : 0;
- if (resource && !d->hasSentEnter) {
- uint32_t serial = d->compositor()->nextSerial();
+ if (!d->hasSentEnter) {
+ d->enterSerial = d->compositor()->nextSerial();
QWaylandKeyboard *keyboard = d->seat->keyboard();
- if (keyboard) {
- keyboard->sendKeyModifiers(view->surface()->client(), serial);
+ if (keyboard)
+ keyboard->sendKeyModifiers(view->surface()->client(), d->enterSerial);
+ for (auto resource : d->pointerResourcesForFocusedSurface()) {
+ d->send_enter(resource->handle, d->enterSerial, view->surface()->resource(),
+ wl_fixed_from_double(d->localPosition.x()),
+ wl_fixed_from_double(d->localPosition.y()));
}
- d->send_enter(resource->handle, serial, view->surface()->resource(),
- wl_fixed_from_double(d->localPosition.x()), wl_fixed_from_double(d->localPosition.y()));
-
d->focusDestroyListener.listenForDestruction(view->surface()->resource());
d->hasSentEnter = true;
}
- d->focusResource = resource ? resource->handle : 0;
-
if (view && view->output())
setOutput(view->output());
uint32_t time = d->compositor()->currentTimeMsecs();
- if (d->focusResource) {
+ if (d->seat->mouseFocus()) {
wl_fixed_t x = wl_fixed_from_double(currentLocalPosition().x());
wl_fixed_t y = wl_fixed_from_double(currentLocalPosition().y());
- wl_pointer_send_motion(d->focusResource, time, x, y);
+ for (auto resource : d->pointerResourcesForFocusedSurface())
+ wl_pointer_send_motion(resource->handle, time, x, y);
}
}
@@ -253,13 +262,15 @@ void QWaylandPointer::sendMouseMoveEvent(QWaylandView *view, const QPointF &loca
void QWaylandPointer::sendMouseWheelEvent(Qt::Orientation orientation, int delta)
{
Q_D(QWaylandPointer);
- if (!d->focusResource)
+ if (!d->seat->mouseFocus())
return;
uint32_t time = d->compositor()->currentTimeMsecs();
uint32_t axis = orientation == Qt::Horizontal ? WL_POINTER_AXIS_HORIZONTAL_SCROLL
: WL_POINTER_AXIS_VERTICAL_SCROLL;
- d->send_axis(d->focusResource, time, axis, wl_fixed_from_int(-delta / 12));
+
+ for (auto resource : d->pointerResourcesForFocusedSurface())
+ d->send_axis(resource->handle, time, axis, wl_fixed_from_int(-delta / 12));
}
/*!
@@ -304,19 +315,30 @@ bool QWaylandPointer::isButtonPressed() const
void QWaylandPointer::addClient(QWaylandClient *client, uint32_t id, uint32_t version)
{
Q_D(QWaylandPointer);
- d->add(client->client(), id, qMin<uint32_t>(QtWaylandServer::wl_pointer::interfaceVersion(), version));
+ wl_resource *resource = d->add(client->client(), id, qMin<uint32_t>(QtWaylandServer::wl_pointer::interfaceVersion(), version))->handle;
+ QWaylandView *focus = d->seat->mouseFocus();
+ if (focus && client == focus->surface()->client()) {
+ d->send_enter(resource, d->enterSerial, focus->surfaceResource(),
+ wl_fixed_from_double(d->localPosition.x()),
+ wl_fixed_from_double(d->localPosition.y()));
+ }
}
/*!
- * Returns the Wayland resource for this QWaylandPointer.
+ * Returns a Wayland resource for this QWaylandPointer.
+ *
+ * This API doesn't actually make sense, since there may be many pointer resources per client
+ * It's here for compatibility reasons.
*/
struct wl_resource *QWaylandPointer::focusResource() const
{
Q_D(const QWaylandPointer);
- if (!d->focusResource)
- return Q_NULLPTR;
+ QWaylandView *focus = d->seat->mouseFocus();
+ if (!focus)
+ return nullptr;
- return d->focusResource;
+ // Just return the first resource we can find.
+ return d->resourceMap().value(focus->surface()->waylandClient())->handle;
}
/*!
@@ -324,6 +346,8 @@ struct wl_resource *QWaylandPointer::focusResource() const
*/
uint QWaylandPointer::sendButton(struct wl_resource *resource, uint32_t time, Qt::MouseButton button, uint32_t state)
{
+ // This method is here for compatibility reasons only, since it usually doesn't make sense to
+ // send button events to just one of the pointer resources for a client.
Q_D(QWaylandPointer);
uint32_t serial = d->compositor()->nextSerial();
d->send_button(resource, serial, time, toWaylandButton(button), state);
@@ -372,7 +396,6 @@ void QWaylandPointer::focusDestroyed(void *data)
d->focusDestroyListener.reset();
d->seat->setMouseFocus(Q_NULLPTR);
- d->focusResource = 0;
d->buttonCount = 0;
}
@@ -385,13 +408,12 @@ void QWaylandPointer::pointerFocusChanged(QWaylandView *newFocus, QWaylandView *
Q_D(QWaylandPointer);
d->localPosition = QPointF();
d->hasSentEnter = false;
- if (d->focusResource && oldFocus) {
+ if (oldFocus) {
uint32_t serial = d->compositor()->nextSerial();
- d->send_leave(d->focusResource, serial, oldFocus->surfaceResource());
+ for (auto resource : d->resourceMap().values(oldFocus->surfaceResource()->client))
+ d->send_leave(resource->handle, serial, oldFocus->surfaceResource());
d->focusDestroyListener.reset();
- d->focusResource = 0;
}
-
}
QT_END_NAMESPACE
diff --git a/src/compositor/compositor_api/qwaylandpointer_p.h b/src/compositor/compositor_api/qwaylandpointer_p.h
index 32a003f9e..0a9ef2329 100644
--- a/src/compositor/compositor_api/qwaylandpointer_p.h
+++ b/src/compositor/compositor_api/qwaylandpointer_p.h
@@ -84,10 +84,10 @@ public:
protected:
void pointer_set_cursor(Resource *resource, uint32_t serial, wl_resource *surface, int32_t hotspot_x, int32_t hotspot_y) override;
void pointer_release(Resource *resource) override;
- void pointer_destroy_resource(Resource *resource) override;
private:
- void focusDestroyed(void *data);
+ const QList<Resource *> pointerResourcesForFocusedSurface() const;
+ uint sendButton(Qt::MouseButton button, uint32_t state);
QWaylandSeat *seat;
QWaylandOutput *output;
@@ -95,8 +95,8 @@ private:
QPointF localPosition;
QPointF spacePosition;
- struct ::wl_resource *focusResource;
bool hasSentEnter;
+ uint enterSerial;
int buttonCount;
diff --git a/src/compositor/compositor_api/qwaylandtouch.h b/src/compositor/compositor_api/qwaylandtouch.h
index 765a546cb..7269e64e1 100644
--- a/src/compositor/compositor_api/qwaylandtouch.h
+++ b/src/compositor/compositor_api/qwaylandtouch.h
@@ -72,9 +72,6 @@ public:
virtual void sendFullTouchEvent(QWaylandSurface *surface, QTouchEvent *event);
virtual void addClient(QWaylandClient *client, uint32_t id, uint32_t version);
-
-private:
- void focusDestroyed(void *data);
};
QT_END_NAMESPACE
diff --git a/src/compositor/extensions/qwaylandquickshellsurfaceitem.cpp b/src/compositor/extensions/qwaylandquickshellsurfaceitem.cpp
index bc23131be..b43ee957a 100644
--- a/src/compositor/extensions/qwaylandquickshellsurfaceitem.cpp
+++ b/src/compositor/extensions/qwaylandquickshellsurfaceitem.cpp
@@ -95,18 +95,17 @@ QWaylandQuickShellSurfaceItem::QWaylandQuickShellSurfaceItem(QWaylandQuickShellS
/*!
* \qmlproperty object QtWaylandCompositor::ShellSurfaceItem::shellSurface
*
- * This property holds the shell surface rendered by this ShellSurfaceItem.
- * It may either be an XdgSurface or a WlShellSurface depending on which
- * shell protocol is in use.
+ * This property holds the ShellSurface rendered by this ShellSurfaceItem.
+ * It may either be an XdgSurfaceV5, WlShellSurface or IviSurface depending on which shell protocol
+ * is in use.
*/
/*!
* \property QWaylandQuickShellSurfaceItem::shellSurface
*
- * This property holds the shell surface rendered by this
- * QWaylandQuickShellSurfaceItem. It may either be a QWaylandXdgSurface or a
- * QWaylandWlShellSurface depending on which shell protocol is in use.
- *
+ * This property holds the QWaylandShellSurface rendered by this QWaylandQuickShellSurfaceItem.
+ * It may either be a QWaylandXdgSurfaceV5, QWaylandWlShellSurface or QWaylandIviSurface depending
+ * on which shell protocol is in use.
*/
QWaylandShellSurface *QWaylandQuickShellSurfaceItem::shellSurface() const
{
diff --git a/tests/auto/client/client/tst_client.cpp b/tests/auto/client/client/tst_client.cpp
index 0c9c007a2..8acddfbe7 100644
--- a/tests/auto/client/client/tst_client.cpp
+++ b/tests/auto/client/client/tst_client.cpp
@@ -142,6 +142,7 @@ private slots:
void backingStore();
void touchDrag();
void mouseDrag();
+ void dontCrashOnMultipleCommits();
private:
MockCompositor *compositor;
@@ -333,6 +334,32 @@ void tst_WaylandClient::mouseDrag()
QTRY_VERIFY(window.dragStarted);
}
+void tst_WaylandClient::dontCrashOnMultipleCommits()
+{
+ auto window = new TestWindow();
+ window->show();
+
+ QRect rect(QPoint(), window->size());
+
+ QBackingStore backingStore(window);
+ backingStore.resize(rect.size());
+ backingStore.beginPaint(rect);
+ QPainter p(backingStore.paintDevice());
+ p.fillRect(rect, Qt::magenta);
+ p.end();
+ backingStore.endPaint();
+
+ backingStore.flush(rect);
+ backingStore.flush(rect);
+ backingStore.flush(rect);
+
+ compositor->processWaylandEvents();
+
+ delete window;
+
+ QTRY_VERIFY(!compositor->surface());
+}
+
int main(int argc, char **argv)
{
setenv("XDG_RUNTIME_DIR", ".", 1);