diff options
author | Liang Qi <liang.qi@qt.io> | 2017-09-20 11:38:52 +0200 |
---|---|---|
committer | Liang Qi <liang.qi@qt.io> | 2017-09-20 11:38:52 +0200 |
commit | 20ebb685e0fef048e56ed19403575634ce4b3435 (patch) | |
tree | 6ad6fedfbe4d361e40a0307f1f0cdc39044b53b6 | |
parent | e1f89e15cf00420bd77ac16a867a1cadc9b942fc (diff) | |
parent | 3cb09edd71745edda4bbe8de3a6d7ad8e4ea5f58 (diff) | |
download | qtwayland-20ebb685e0fef048e56ed19403575634ce4b3435.tar.gz |
Merge remote-tracking branch 'origin/5.9' into 5.10
Change-Id: I76bfc271efcf75c75bf38f4bf58503e1d2a00839
-rw-r--r-- | dist/changes-5.6.3 | 31 | ||||
-rw-r--r-- | src/client/qwaylandintegration.cpp | 2 | ||||
-rw-r--r-- | src/client/qwaylandscreen.cpp | 6 | ||||
-rw-r--r-- | src/client/qwaylandscreen_p.h | 1 | ||||
-rw-r--r-- | src/client/qwaylandwindow.cpp | 97 | ||||
-rw-r--r-- | src/client/qwaylandwindow_p.h | 15 | ||||
-rw-r--r-- | src/compositor/compositor_api/qwaylandpointer.cpp | 90 | ||||
-rw-r--r-- | src/compositor/compositor_api/qwaylandpointer_p.h | 6 | ||||
-rw-r--r-- | src/compositor/compositor_api/qwaylandtouch.h | 3 | ||||
-rw-r--r-- | src/compositor/extensions/qwaylandquickshellsurfaceitem.cpp | 13 | ||||
-rw-r--r-- | tests/auto/client/client/tst_client.cpp | 27 |
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 00000000..9312b636 --- /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 400f3517..bffadf29 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 7f12a421..5b43428d 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 526c9487..674e1a91 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 9cc673c0..cac92a7e 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 9f6ff5b4..961b7881 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 267b5d98..d1ca174d 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 32a003f9..0a9ef232 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 765a546c..7269e64e 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 bc23131b..b43ee957 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 0c9c007a..8acddfbe 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); |