diff options
-rw-r--r-- | src/client/qwaylandwindow.cpp | 13 | ||||
-rw-r--r-- | src/client/qwaylandwindow_p.h | 3 | ||||
-rw-r--r-- | tests/auto/client/client/tst_client.cpp | 27 |
3 files changed, 34 insertions, 9 deletions
diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp index 4a60a6616..eeba6c85f 100644 --- a/src/client/qwaylandwindow.cpp +++ b/src/client/qwaylandwindow.cpp @@ -86,7 +86,6 @@ QWaylandWindow::QWaylandWindow(QWindow *window) , mMouseEventsInContentArea(false) , mMousePressedInContentArea(Qt::NoButton) , mWaitingForFrameSync(false) - , mFrameCallback(nullptr) , mRequestResizeSent(false) , mCanResize(true) , mResizeDirty(false) @@ -475,12 +474,14 @@ void QWaylandWindow::requestResize() 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(); @@ -523,8 +524,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; diff --git a/src/client/qwaylandwindow_p.h b/src/client/qwaylandwindow_p.h index 29eb6c596..fa213d07a 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> @@ -222,7 +221,7 @@ protected: WId mWindowId; bool mWaitingForFrameSync; - QAtomicPointer<struct wl_callback> mFrameCallback; + struct ::wl_callback *mFrameCallback = nullptr; QWaitCondition mFrameSyncWait; QMutex mResizeLock; 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); |