Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package libqt5-qtwayland for openSUSE:Factory checked in at 2022-09-27 20:09:46 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/libqt5-qtwayland (Old) and /work/SRC/openSUSE:Factory/.libqt5-qtwayland.new.2275 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "libqt5-qtwayland" Tue Sep 27 20:09:46 2022 rev:46 rq:1006242 version:5.15.6+kde49 Changes: -------- --- /work/SRC/openSUSE:Factory/libqt5-qtwayland/libqt5-qtwayland.changes 2022-06-29 16:01:27.388630548 +0200 +++ /work/SRC/openSUSE:Factory/.libqt5-qtwayland.new.2275/libqt5-qtwayland.changes 2022-09-27 20:10:18.785348309 +0200 @@ -1,0 +2,22 @@ +Mon Sep 26 12:03:24 UTC 2022 - Fabian Vogt <fab...@ritter-vogt.de> + +- Update to version 5.15.6+kde49, rebased upstream: + * Call `finishDrag()` in `QWaylandDataDevice::dragSourceCancelled()` + * Client: support high-dpi mode for window icon + * Avoid calling requestUpdate from wrong thread + * Fix missing update when toggling client-side decorations + * Use CRLF line delimiter for text/uri-list data + * Fix compile tests + * client: Synthesize enter/leave event for popup in xdg-shell + * Guard mResizeDirty by the correctMutex + * Client: clear focus on touch cancel + * Build fixes for GCC 11 + * Only close popup in the the hierchary + * Cleanup up all subsurface QQuickItems correctly + * linux-dmabuf-unstable-v1: Fix importing dmabuf buffers with modifiers + * Add BlankCursor for cursor names map + * client: Gracefully handle shutdown and window hiding +- Drop patches, now upstream: + * 0002-Guard-mResizeDirty-by-the-correctMutex.patch + +------------------------------------------------------------------- Old: ---- 0002-Guard-mResizeDirty-by-the-correctMutex.patch qtwayland-everywhere-src-5.15.5+kde39.obscpio New: ---- qtwayland-everywhere-src-5.15.6+kde49.obscpio ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ libqt5-qtwayland.spec ++++++ --- /var/tmp/diff_new_pack.NQQh0U/_old 2022-09-27 20:10:19.481349844 +0200 +++ /var/tmp/diff_new_pack.NQQh0U/_new 2022-09-27 20:10:19.489349861 +0200 @@ -22,11 +22,11 @@ %define qt5_snapshot 1 %define libname libQt5WaylandCompositor5 %define base_name libqt5 -%define real_version 5.15.5 -%define so_version 5.15.5 +%define real_version 5.15.6 +%define so_version 5.15.6 %define tar_version qtwayland-everywhere-src-%{version} Name: libqt5-qtwayland -Version: 5.15.5+kde39 +Version: 5.15.6+kde49 Release: 0 Summary: Qt 5 Wayland Addon # The wayland compositor files are GPL-3.0-or-later @@ -35,8 +35,6 @@ URL: https://www.qt.io Source: %{tar_version}.tar.xz Source1: baselibs.conf -# https://codereview.qt-project.org/c/qt/qtwayland/+/393828/1 -Patch3: 0002-Guard-mResizeDirty-by-the-correctMutex.patch BuildRequires: fdupes BuildRequires: libqt5-qtbase-private-headers-devel >= %{real_version} BuildRequires: libqt5-qtdeclarative-private-headers-devel >= %{real_version} ++++++ _service ++++++ --- /var/tmp/diff_new_pack.NQQh0U/_old 2022-09-27 20:10:19.525349940 +0200 +++ /var/tmp/diff_new_pack.NQQh0U/_new 2022-09-27 20:10:19.525349940 +0200 @@ -1,12 +1,12 @@ <services> <service name="obs_scm" mode="disabled"> <param name="changesgenerate">enable</param> - <param name="versionformat">5.15.5+kde@TAG_OFFSET@</param> + <param name="versionformat">5.15.6+kde@TAG_OFFSET@</param> <param name="url">https://invent.kde.org/qt/qt/qtwayland.git</param> <param name="scm">git</param> <param name="filename">qtwayland-everywhere-src</param> <param name="revision">kde/5.15</param> - <param name="parent-tag">v5.15.5-lts-lgpl</param> + <param name="parent-tag">v5.15.6-lts-lgpl</param> <param name="changesgenerate">enable</param> </service> <service name="set_version" mode="disabled"/> ++++++ qtwayland-everywhere-src-5.15.5+kde39.obscpio -> qtwayland-everywhere-src-5.15.6+kde49.obscpio ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtwayland-everywhere-src-5.15.5+kde39/.qmake.conf new/qtwayland-everywhere-src-5.15.6+kde49/.qmake.conf --- old/qtwayland-everywhere-src-5.15.5+kde39/.qmake.conf 2022-06-20 22:17:21.000000000 +0200 +++ new/qtwayland-everywhere-src-5.15.6+kde49/.qmake.conf 2022-09-22 13:58:55.000000000 +0200 @@ -4,4 +4,4 @@ DEFINES += QT_NO_JAVA_STYLE_ITERATORS DEFINES += QT_NO_LINKED_LIST -MODULE_VERSION = 5.15.5 +MODULE_VERSION = 5.15.6 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtwayland-everywhere-src-5.15.5+kde39/src/client/qwaylandcursor.cpp new/qtwayland-everywhere-src-5.15.6+kde49/src/client/qwaylandcursor.cpp --- old/qtwayland-everywhere-src-5.15.5+kde39/src/client/qwaylandcursor.cpp 2022-06-20 22:17:21.000000000 +0200 +++ new/qtwayland-everywhere-src-5.15.6+kde49/src/client/qwaylandcursor.cpp 2022-09-22 13:58:55.000000000 +0200 @@ -120,6 +120,8 @@ {SizeAllCursor, "size_all"}, + {BlankCursor, "blank"}, + {SplitVCursor, "split_v"}, {SplitVCursor, "row-resize"}, {SplitVCursor, "sb_v_double_arrow"}, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtwayland-everywhere-src-5.15.5+kde39/src/client/qwaylanddatadevice.cpp new/qtwayland-everywhere-src-5.15.6+kde49/src/client/qwaylanddatadevice.cpp --- old/qtwayland-everywhere-src-5.15.5+kde39/src/client/qwaylanddatadevice.cpp 2022-06-20 22:17:21.000000000 +0200 +++ new/qtwayland-everywhere-src-5.15.6+kde49/src/client/qwaylanddatadevice.cpp 2022-09-22 13:58:55.000000000 +0200 @@ -296,6 +296,7 @@ #if QT_CONFIG(draganddrop) void QWaylandDataDevice::dragSourceCancelled() { + static_cast<QWaylandDrag *>(QGuiApplicationPrivate::platformIntegration()->drag())->finishDrag(); m_dragSource.reset(); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtwayland-everywhere-src-5.15.5+kde39/src/client/qwaylandinputdevice.cpp new/qtwayland-everywhere-src-5.15.6+kde49/src/client/qwaylandinputdevice.cpp --- old/qtwayland-everywhere-src-5.15.5+kde39/src/client/qwaylandinputdevice.cpp 2022-06-20 22:17:21.000000000 +0200 +++ new/qtwayland-everywhere-src-5.15.6+kde49/src/client/qwaylandinputdevice.cpp 2022-09-22 13:58:55.000000000 +0200 @@ -1388,6 +1388,7 @@ if (touchExt) touchExt->touchCanceled(); + mFocus = nullptr; QWindowSystemInterface::handleTouchCancelEvent(nullptr, mParent->mTouchDevice); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtwayland-everywhere-src-5.15.5+kde39/src/client/qwaylandwindow.cpp new/qtwayland-everywhere-src-5.15.6+kde49/src/client/qwaylandwindow.cpp --- old/qtwayland-everywhere-src-5.15.5+kde39/src/client/qwaylandwindow.cpp 2022-06-20 22:17:21.000000000 +0200 +++ new/qtwayland-everywhere-src-5.15.6+kde49/src/client/qwaylandwindow.cpp 2022-09-22 13:58:55.000000000 +0200 @@ -239,6 +239,7 @@ void QWaylandWindow::reset() { + closeChildPopups(); delete mShellSurface; mShellSurface = nullptr; delete mSubSurfaceWindow; @@ -357,11 +358,12 @@ if (mWindowDecoration) mWindowDecoration->update(); - if (mResizeAfterSwap && windowType() == Egl && mSentInitialResize) + if (mResizeAfterSwap && windowType() == Egl && mSentInitialResize) { + QMutexLocker lock(&mResizeLock); mResizeDirty = true; - else + } else { QWindowSystemInterface::handleGeometryChange(window(), geometry()); - + } mSentInitialResize = true; } QRect exposeGeometry(QPoint(), geometry().size()); @@ -397,23 +399,9 @@ mLastExposeGeometry = 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(); - } -} - QPlatformScreen *QWaylandWindow::calculateScreenFromSurfaceEvents() const { + QReadLocker lock(&mSurfaceLock); if (mSurface) { if (auto *screen = mSurface->oldestEnteredScreen()) return screen; @@ -430,8 +418,6 @@ lastVisible = visible; if (visible) { - if (window()->type() == Qt::Popup || window()->type() == Qt::ToolTip) - activePopups << this; initWindow(); setGeometry(windowGeometry()); @@ -440,7 +426,6 @@ // QWaylandShmBackingStore::beginPaint(). } else { sendExposeEvent(QRect()); - closePopups(this); reset(); } } @@ -552,6 +537,10 @@ void QWaylandWindow::attach(QWaylandBuffer *buffer, int x, int y) { + QReadLocker locker(&mSurfaceLock); + if (mSurface == nullptr) + return; + if (buffer) { Q_ASSERT(!buffer->committed()); handleUpdate(); @@ -571,6 +560,10 @@ void QWaylandWindow::damage(const QRect &rect) { + QReadLocker locker(&mSurfaceLock); + if (mSurface == nullptr) + return; + const int s = scale(); if (mDisplay->compositorVersion() >= 4) mSurface->damage_buffer(s * rect.x(), s * rect.y(), s * rect.width(), s * rect.height()); @@ -605,6 +598,8 @@ qCDebug(lcWaylandBackingstore) << "Buffer already committed, ignoring."; return; } + + QReadLocker locker(&mSurfaceLock); if (!mSurface) return; @@ -624,7 +619,9 @@ void QWaylandWindow::commit() { - mSurface->commit(); + QReadLocker locker(&mSurfaceLock); + if (mSurface != nullptr) + mSurface->commit(); } const wl_callback_listener QWaylandWindow::callbackListener = { @@ -723,6 +720,7 @@ wl_surface *QWaylandWindow::wlSurface() { + QReadLocker locker(&mSurfaceLock); return mSurface ? mSurface->object() : nullptr; } @@ -747,7 +745,8 @@ void QWaylandWindow::handleContentOrientationChange(Qt::ScreenOrientation orientation) { - if (mDisplay->compositorVersion() < 2) + QReadLocker locker(&mSurfaceLock); + if (mDisplay->compositorVersion() < 2 || mSurface == nullptr) return; wl_output_transform transform; @@ -868,6 +867,17 @@ subsurf->set_position(pos.x() + m.left(), pos.y() + m.top()); } sendExposeEvent(QRect(QPoint(), geometry().size())); + + // This is a special case where the buffer is recreated, but since + // the content rect remains the same, the widgets remain the same + // size and are not redrawn, leaving the new buffer empty. As a simple + // work-around, we trigger a full extra update whenever the client-side + // window decorations are toggled while the window is showing. + // Note: createDecoration() is sometimes called from the render thread + // of Qt Quick. This is essentially wrong and could potentially cause problems, + // but until the underlying issue has been fixed, we have to use invokeMethod() + // here to avoid asserts. + QMetaObject::invokeMethod(window(), &QWindow::requestUpdate); } return mWindowDecoration; @@ -1285,6 +1295,20 @@ wl_region_destroy(region); } +void QWaylandWindow::addChildPopup(QWaylandWindow *surface) { + mChildPopups.append(surface); +} + +void QWaylandWindow::removeChildPopup(QWaylandWindow *surface) { + mChildPopups.removeAll(surface); +} + +void QWaylandWindow::closeChildPopups() { + while (!mChildPopups.isEmpty()) { + auto popup = mChildPopups.takeLast(); + popup->reset(); + } +} } QT_END_NAMESPACE diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtwayland-everywhere-src-5.15.5+kde39/src/client/qwaylandwindow_p.h new/qtwayland-everywhere-src-5.15.6+kde49/src/client/qwaylandwindow_p.h --- old/qtwayland-everywhere-src-5.15.5+kde39/src/client/qwaylandwindow_p.h 2022-06-20 22:17:21.000000000 +0200 +++ new/qtwayland-everywhere-src-5.15.6+kde49/src/client/qwaylandwindow_p.h 2022-09-22 13:58:55.000000000 +0200 @@ -207,6 +207,10 @@ void handleUpdate(); void deliverUpdateRequest() override; + void addChildPopup(QWaylandWindow* child); + void removeChildPopup(QWaylandWindow* child); + void closeChildPopups(); + public slots: void applyConfigure(); @@ -262,6 +266,8 @@ QWaylandBuffer *mQueuedBuffer = nullptr; QRegion mQueuedBufferDamage; + QList<QPointer<QWaylandWindow>> mChildPopups; + private: void setGeometry_helper(const QRect &rect); void initWindow(); @@ -288,7 +294,7 @@ static QWaylandWindow *mMouseGrab; - QReadWriteLock mSurfaceLock; + mutable QReadWriteLock mSurfaceLock; friend class QWaylandSubSurface; }; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtwayland-everywhere-src-5.15.5+kde39/src/compositor/compositor_api/qwaylandquickitem.cpp new/qtwayland-everywhere-src-5.15.6+kde49/src/compositor/compositor_api/qwaylandquickitem.cpp --- old/qtwayland-everywhere-src-5.15.5+kde39/src/compositor/compositor_api/qwaylandquickitem.cpp 2022-06-20 22:17:21.000000000 +0200 +++ new/qtwayland-everywhere-src-5.15.6+kde49/src/compositor/compositor_api/qwaylandquickitem.cpp 2022-09-22 13:58:55.000000000 +0200 @@ -737,6 +737,7 @@ childItem->setSurface(childSurface); childItem->setVisible(true); childItem->setParentItem(this); + childItem->setParent(this); connect(childSurface, &QWaylandSurface::subsurfacePositionChanged, childItem, &QWaylandQuickItem::handleSubsurfacePosition); connect(childSurface, &QWaylandSurface::destroyed, childItem, &QObject::deleteLater); } else { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtwayland-everywhere-src-5.15.5+kde39/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp new/qtwayland-everywhere-src-5.15.6+kde49/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp --- old/qtwayland-everywhere-src-5.15.5+kde39/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp 2022-06-20 22:17:21.000000000 +0200 +++ new/qtwayland-everywhere-src-5.15.6+kde49/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp 2022-09-22 13:58:55.000000000 +0200 @@ -192,7 +192,6 @@ } void blit(QWaylandEglWindow *window) { - Q_ASSERT(window->wlSurface()); QOpenGLTextureCache *cache = QOpenGLTextureCache::cacheForContext(m_context->context()); QSize surfaceSize = window->surfaceSize(); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtwayland-everywhere-src-5.15.5+kde39/src/hardwareintegration/compositor/linux-dmabuf-unstable-v1/linuxdmabufclientbufferintegration.cpp new/qtwayland-everywhere-src-5.15.6+kde49/src/hardwareintegration/compositor/linux-dmabuf-unstable-v1/linuxdmabufclientbufferintegration.cpp --- old/qtwayland-everywhere-src-5.15.5+kde39/src/hardwareintegration/compositor/linux-dmabuf-unstable-v1/linuxdmabufclientbufferintegration.cpp 2022-06-20 22:17:21.000000000 +0200 +++ new/qtwayland-everywhere-src-5.15.6+kde49/src/hardwareintegration/compositor/linux-dmabuf-unstable-v1/linuxdmabufclientbufferintegration.cpp 2022-09-22 13:58:55.000000000 +0200 @@ -105,6 +105,11 @@ } } +// Initialize the EGLImage for a dmabuf buffer which conceptually consists of a +// single plane. Note that depending on the modifiers, the buffer may be actually +// transported as multiple dmabuf planes which must be combined into a single +// EGLImage. For formats where the buffer needs to be represented as multiple +// EGLImages (e.g., various YUV formats) a different approach is required. bool LinuxDmabufClientBufferIntegration::initSimpleTexture(LinuxDmabufWlBuffer *dmabufBuffer) { bool success = true; @@ -118,79 +123,67 @@ success = false; } - for (uint32_t i = 0; i < dmabufBuffer->planesNumber(); ++i) { - QVarLengthArray<EGLint, 17> attribs; - switch (i) { - case 0: - attribs = { - EGL_WIDTH, dmabufBuffer->size().width(), - EGL_HEIGHT, dmabufBuffer->size().height(), - EGL_LINUX_DRM_FOURCC_EXT, EGLint(dmabufBuffer->drmFormat()), - EGL_DMA_BUF_PLANE0_FD_EXT, dmabufBuffer->plane(i).fd, - EGL_DMA_BUF_PLANE0_OFFSET_EXT, EGLint(dmabufBuffer->plane(i).offset), - EGL_DMA_BUF_PLANE0_PITCH_EXT, EGLint(dmabufBuffer->plane(i).stride), - EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT, EGLint(dmabufBuffer->plane(i).modifiers & 0xffffffff), - EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT, EGLint(dmabufBuffer->plane(i).modifiers >> 32), - EGL_NONE - }; - break; - case 1: - attribs = { - EGL_WIDTH, dmabufBuffer->size().width(), - EGL_HEIGHT, dmabufBuffer->size().height(), - EGL_LINUX_DRM_FOURCC_EXT, EGLint(dmabufBuffer->drmFormat()), - EGL_DMA_BUF_PLANE1_FD_EXT, dmabufBuffer->plane(i).fd, - EGL_DMA_BUF_PLANE1_OFFSET_EXT, EGLint(dmabufBuffer->plane(i).offset), - EGL_DMA_BUF_PLANE1_PITCH_EXT, EGLint(dmabufBuffer->plane(i).stride), - EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT, EGLint(dmabufBuffer->plane(i).modifiers & 0xffffffff), - EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT, EGLint(dmabufBuffer->plane(i).modifiers >> 32), - EGL_NONE - }; - break; - case 2: - attribs = { - EGL_WIDTH, dmabufBuffer->size().width(), - EGL_HEIGHT, dmabufBuffer->size().height(), - EGL_LINUX_DRM_FOURCC_EXT, EGLint(dmabufBuffer->drmFormat()), - EGL_DMA_BUF_PLANE2_FD_EXT, dmabufBuffer->plane(i).fd, - EGL_DMA_BUF_PLANE2_OFFSET_EXT, EGLint(dmabufBuffer->plane(i).offset), - EGL_DMA_BUF_PLANE2_PITCH_EXT, EGLint(dmabufBuffer->plane(i).stride), - EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT, EGLint(dmabufBuffer->plane(i).modifiers & 0xffffffff), - EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT, EGLint(dmabufBuffer->plane(i).modifiers >> 32), - EGL_NONE - }; - break; - case 3: - attribs = { - EGL_WIDTH, dmabufBuffer->size().width(), - EGL_HEIGHT, dmabufBuffer->size().height(), - EGL_LINUX_DRM_FOURCC_EXT, EGLint(dmabufBuffer->drmFormat()), - EGL_DMA_BUF_PLANE3_FD_EXT, dmabufBuffer->plane(i).fd, - EGL_DMA_BUF_PLANE3_OFFSET_EXT, EGLint(dmabufBuffer->plane(i).offset), - EGL_DMA_BUF_PLANE3_PITCH_EXT, EGLint(dmabufBuffer->plane(i).stride), - EGL_DMA_BUF_PLANE3_MODIFIER_LO_EXT, EGLint(dmabufBuffer->plane(i).modifiers & 0xffffffff), - EGL_DMA_BUF_PLANE3_MODIFIER_HI_EXT, EGLint(dmabufBuffer->plane(i).modifiers >> 32), - EGL_NONE - }; + // 6 entries for the common attribs plus 10 per possible plane, plus 1 for + // the final EGL_NONE sentinel. + QVarLengthArray<EGLint, 6 + 10 * 4 + 1> attribs; + + attribs.append(EGL_WIDTH); + attribs.append(dmabufBuffer->size().width()); + attribs.append(EGL_HEIGHT); + attribs.append(dmabufBuffer->size().height()); + attribs.append(EGL_LINUX_DRM_FOURCC_EXT); + attribs.append(EGLint(dmabufBuffer->drmFormat())); + +#define ADD_PLANE_ATTRIBS(plane_idx) { \ + attribs.append(EGL_DMA_BUF_PLANE ## plane_idx ## _FD_EXT); \ + attribs.append(dmabufBuffer->plane(plane_idx).fd); \ + attribs.append(EGL_DMA_BUF_PLANE ## plane_idx ## _OFFSET_EXT); \ + attribs.append(EGLint(dmabufBuffer->plane(plane_idx).offset)); \ + attribs.append(EGL_DMA_BUF_PLANE ## plane_idx ## _PITCH_EXT); \ + attribs.append(EGLint(dmabufBuffer->plane(plane_idx).stride)); \ + if (dmabufBuffer->plane(plane_idx).modifiers != DRM_FORMAT_MOD_INVALID) { \ + attribs.append(EGL_DMA_BUF_PLANE ## plane_idx ## _MODIFIER_LO_EXT); \ + attribs.append(EGLint(dmabufBuffer->plane(plane_idx).modifiers & 0xffffffff)); \ + attribs.append(EGL_DMA_BUF_PLANE ## plane_idx ## _MODIFIER_HI_EXT); \ + attribs.append(EGLint(dmabufBuffer->plane(plane_idx).modifiers >> 32)); \ + } \ +} + + switch (dmabufBuffer->planesNumber()) { + case 4: + ADD_PLANE_ATTRIBS(3); + Q_FALLTHROUGH(); + case 3: + ADD_PLANE_ATTRIBS(2); + Q_FALLTHROUGH(); + case 2: + ADD_PLANE_ATTRIBS(1); + Q_FALLTHROUGH(); + case 1: + ADD_PLANE_ATTRIBS(0); break; - default: - return false; - } - - // note: EGLImageKHR does NOT take ownership of the file descriptors - EGLImageKHR image = egl_create_image(m_eglDisplay, - EGL_NO_CONTEXT, - EGL_LINUX_DMA_BUF_EXT, - (EGLClientBuffer) nullptr, - attribs.constData()); - - if (image == EGL_NO_IMAGE_KHR) { - qCWarning(qLcWaylandCompositorHardwareIntegration) << "failed to create EGL image for plane" << i; - success = false; - } + default: + qCWarning(qLcWaylandCompositorHardwareIntegration) << "Buffer uses invalid number of planes:" << dmabufBuffer->planesNumber(); + return false; + } + + attribs.append(EGL_NONE); - dmabufBuffer->initImage(i, image); + // note: EGLImageKHR does NOT take ownership of the file descriptors + EGLImageKHR image = egl_create_image(m_eglDisplay, + EGL_NO_CONTEXT, + EGL_LINUX_DMA_BUF_EXT, + (EGLClientBuffer) nullptr, + attribs.constData()); + + if (image == EGL_NO_IMAGE_KHR) { + qCWarning(qLcWaylandCompositorHardwareIntegration) << "failed to create EGL image from" << + dmabufBuffer->planesNumber() << "plane(s)"; + success = false; } + + dmabufBuffer->initImage(0, image); + return success; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtwayland-everywhere-src-5.15.5+kde39/src/plugins/decorations/bradient/main.cpp new/qtwayland-everywhere-src-5.15.6+kde49/src/plugins/decorations/bradient/main.cpp --- old/qtwayland-everywhere-src-5.15.5+kde39/src/plugins/decorations/bradient/main.cpp 2022-06-20 22:17:21.000000000 +0200 +++ new/qtwayland-everywhere-src-5.15.6+kde49/src/plugins/decorations/bradient/main.cpp 2022-09-22 13:58:55.000000000 +0200 @@ -164,13 +164,10 @@ // Window icon QIcon icon = waylandWindow()->windowIcon(); if (!icon.isNull()) { - QPixmap pixmap = icon.pixmap(QSize(128, 128)); - QPixmap scaled = pixmap.scaled(22, 22, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); - QRectF iconRect(0, 0, 22, 22); - p.drawPixmap(iconRect.adjusted(margins().left() + BUTTON_SPACING, 4, - margins().left() + BUTTON_SPACING, 4), - scaled, iconRect); + iconRect.adjust(margins().left() + BUTTON_SPACING, 4, + margins().left() + BUTTON_SPACING, 4), + icon.paint(&p, iconRect.toRect()); } // Window title diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtwayland-everywhere-src-5.15.5+kde39/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp new/qtwayland-everywhere-src-5.15.6+kde49/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp --- old/qtwayland-everywhere-src-5.15.5+kde39/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp 2022-06-20 22:17:21.000000000 +0200 +++ new/qtwayland-everywhere-src-5.15.6+kde49/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp 2022-09-22 13:58:55.000000000 +0200 @@ -195,12 +195,17 @@ | ((edges & Qt::RightEdge) ? resize_edge_right : 0)); } -QWaylandXdgSurface::Popup::Popup(QWaylandXdgSurface *xdgSurface, QWaylandXdgSurface *parent, +QWaylandXdgSurface::Popup::Popup(QWaylandXdgSurface *xdgSurface, QWaylandWindow *parent, QtWayland::xdg_positioner *positioner) - : xdg_popup(xdgSurface->get_popup(parent->object(), positioner->object())) - , m_xdgSurface(xdgSurface) + : m_xdgSurface(xdgSurface) + , m_parentXdgSurface(qobject_cast<QWaylandXdgSurface *>(parent->shellSurface())) , m_parent(parent) { + + init(xdgSurface->get_popup(m_parentXdgSurface ? m_parentXdgSurface->object() : nullptr, positioner->object())); + if (m_parent) { + m_parent->addChildPopup(m_xdgSurface->window()); + } } QWaylandXdgSurface::Popup::~Popup() @@ -208,10 +213,24 @@ if (isInitialized()) destroy(); + if (m_parent) { + m_parent->removeChildPopup(m_xdgSurface->window()); + } + if (m_grabbing) { auto *shell = m_xdgSurface->m_shell; Q_ASSERT(shell->m_topmostGrabbingPopup == this); - shell->m_topmostGrabbingPopup = m_parent->m_popup; + shell->m_topmostGrabbingPopup = m_parentXdgSurface ? m_parentXdgSurface->m_popup : nullptr; + m_grabbing = false; + + // Synthesize Qt enter/leave events for popup + QWindow *leave = nullptr; + if (m_xdgSurface && m_xdgSurface->window()) + leave = m_xdgSurface->window()->window(); + QWindowSystemInterface::handleLeaveEvent(leave); + + if (QWindow *enter = QGuiApplication::topLevelAt(QCursor::pos())) + QWindowSystemInterface::handleEnterEvent(enter, enter->mapFromGlobal(QCursor::pos()), QCursor::pos()); } } @@ -392,8 +411,6 @@ { Q_ASSERT(!m_toplevel && !m_popup); - auto parentXdgSurface = static_cast<QWaylandXdgSurface *>(parent->shellSurface()); - auto positioner = new QtWayland::xdg_positioner(m_shell->create_positioner()); // set_popup expects a position relative to the parent QPoint transientPos = m_window->geometry().topLeft(); // this is absolute @@ -406,8 +423,9 @@ positioner->set_anchor(QtWayland::xdg_positioner::anchor_top_left); positioner->set_gravity(QtWayland::xdg_positioner::gravity_bottom_right); positioner->set_size(m_window->geometry().width(), m_window->geometry().height()); - m_popup = new Popup(this, parentXdgSurface, positioner); + m_popup = new Popup(this, parent, positioner); positioner->destroy(); + delete positioner; } @@ -429,6 +447,23 @@ } setPopup(parent); m_popup->grab(device, serial); + + // Synthesize Qt enter/leave events for popup + if (!parent) + return; + QWindow *current = QGuiApplication::topLevelAt(QCursor::pos()); + QWindow *leave = parent->window(); + if (current != leave) + return; + + QWindowSystemInterface::handleLeaveEvent(leave); + + QWindow *enter = nullptr; + if (m_popup && m_popup->m_xdgSurface && m_popup->m_xdgSurface->window()) + enter = m_popup->m_xdgSurface->window()->window(); + + if (enter) + QWindowSystemInterface::handleEnterEvent(enter, enter->mapFromGlobal(QCursor::pos()), QCursor::pos()); } void QWaylandXdgSurface::xdg_surface_configure(uint32_t serial) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtwayland-everywhere-src-5.15.5+kde39/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h new/qtwayland-everywhere-src-5.15.6+kde49/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h --- old/qtwayland-everywhere-src-5.15.5+kde39/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h 2022-06-20 22:17:21.000000000 +0200 +++ new/qtwayland-everywhere-src-5.15.6+kde49/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h 2022-09-22 13:58:55.000000000 +0200 @@ -131,14 +131,15 @@ class Popup : public QtWayland::xdg_popup { public: - Popup(QWaylandXdgSurface *xdgSurface, QWaylandXdgSurface *parent, QtWayland::xdg_positioner *positioner); + Popup(QWaylandXdgSurface *xdgSurface, QWaylandWindow *parent, QtWayland::xdg_positioner *positioner); ~Popup() override; void grab(QWaylandInputDevice *seat, uint serial); void xdg_popup_popup_done() override; QWaylandXdgSurface *m_xdgSurface = nullptr; - QWaylandXdgSurface *m_parent = nullptr; + QWaylandXdgSurface *m_parentXdgSurface = nullptr; + QWaylandWindow *m_parent = nullptr; bool m_grabbing = false; }; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtwayland-everywhere-src-5.15.5+kde39/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5.cpp new/qtwayland-everywhere-src-5.15.6+kde49/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5.cpp --- old/qtwayland-everywhere-src-5.15.5+kde39/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5.cpp 2022-06-20 22:17:21.000000000 +0200 +++ new/qtwayland-everywhere-src-5.15.6+kde49/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5.cpp 2022-09-22 13:58:55.000000000 +0200 @@ -47,18 +47,21 @@ namespace QtWaylandClient { -QWaylandXdgPopupV5::QWaylandXdgPopupV5(struct ::xdg_popup_v5 *popup, QWaylandWindow *window) +QWaylandXdgPopupV5::QWaylandXdgPopupV5(struct ::xdg_popup_v5 *popup, QWaylandWindow* parent, QWaylandWindow *window) : QWaylandShellSurface(window) , QtWayland::xdg_popup_v5(popup) + , m_parent(parent) , m_window(window) { if (window->display()->windowExtension()) m_extendedWindow = new QWaylandExtendedSurface(window); + m_parent->addChildPopup(m_window); } QWaylandXdgPopupV5::~QWaylandXdgPopupV5() { xdg_popup_destroy(object()); + m_parent->removeChildPopup(m_window); delete m_extendedWindow; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtwayland-everywhere-src-5.15.5+kde39/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5_p.h new/qtwayland-everywhere-src-5.15.6+kde49/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5_p.h --- old/qtwayland-everywhere-src-5.15.5+kde39/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5_p.h 2022-06-20 22:17:21.000000000 +0200 +++ new/qtwayland-everywhere-src-5.15.6+kde49/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5_p.h 2022-09-22 13:58:55.000000000 +0200 @@ -70,7 +70,7 @@ { Q_OBJECT public: - QWaylandXdgPopupV5(struct ::xdg_popup_v5 *popup, QWaylandWindow *window); + QWaylandXdgPopupV5(struct ::xdg_popup_v5 *popup, QWaylandWindow* parent, QWaylandWindow *window); ~QWaylandXdgPopupV5() override; protected: @@ -78,6 +78,7 @@ private: QWaylandExtendedSurface *m_extendedWindow = nullptr; + QWaylandWindow *m_parent = nullptr; QWaylandWindow *m_window = nullptr; }; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtwayland-everywhere-src-5.15.5+kde39/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5.cpp new/qtwayland-everywhere-src-5.15.6+kde49/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5.cpp --- old/qtwayland-everywhere-src-5.15.5+kde39/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5.cpp 2022-06-20 22:17:21.000000000 +0200 +++ new/qtwayland-everywhere-src-5.15.6+kde49/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5.cpp 2022-09-22 13:58:55.000000000 +0200 @@ -84,7 +84,7 @@ int x = position.x() + parentWindow->frameMargins().left(); int y = position.y() + parentWindow->frameMargins().top(); - auto popup = new QWaylandXdgPopupV5(get_xdg_popup(window->wlSurface(), parentSurface, seat, m_popupSerial, x, y), window); + auto popup = new QWaylandXdgPopupV5(get_xdg_popup(window->wlSurface(), parentSurface, seat, m_popupSerial, x, y), parentWindow, window); m_popups.append(window); QObject::connect(popup, &QWaylandXdgPopupV5::destroyed, [this, window](){ m_popups.removeOne(window); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtwayland-everywhere-src-5.15.5+kde39/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6.cpp new/qtwayland-everywhere-src-5.15.6+kde49/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6.cpp --- old/qtwayland-everywhere-src-5.15.5+kde39/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6.cpp 2022-06-20 22:17:21.000000000 +0200 +++ new/qtwayland-everywhere-src-5.15.6+kde49/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6.cpp 2022-09-22 13:58:55.000000000 +0200 @@ -174,6 +174,7 @@ , m_xdgSurface(xdgSurface) , m_parent(parent) { + m_parent->window()->addChildPopup(m_xdgSurface->window()); } QWaylandXdgSurfaceV6::Popup::~Popup() @@ -181,6 +182,8 @@ if (isInitialized()) destroy(); + m_parent->window()->removeChildPopup(m_xdgSurface->window()); + if (m_grabbing) { auto *shell = m_xdgSurface->m_shell; Q_ASSERT(shell->m_topmostGrabbingPopup == this); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtwayland-everywhere-src-5.15.5+kde39/src/shared/qwaylandmimehelper.cpp new/qtwayland-everywhere-src-5.15.6+kde49/src/shared/qwaylandmimehelper.cpp --- old/qtwayland-everywhere-src-5.15.5+kde39/src/shared/qwaylandmimehelper.cpp 2022-06-20 22:17:21.000000000 +0200 +++ new/qtwayland-everywhere-src-5.15.6+kde49/src/shared/qwaylandmimehelper.cpp 2022-09-22 13:58:55.000000000 +0200 @@ -74,7 +74,7 @@ QList<QUrl> urls = mimeData->urls(); for (int i = 0; i < urls.count(); ++i) { content.append(urls.at(i).toEncoded()); - content.append('\n'); + content.append("\r\n"); } } else { content = mimeData->data(mimeType); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtwayland-everywhere-src-5.15.5+kde39/tests/auto/client/seatv5/tst_seatv5.cpp new/qtwayland-everywhere-src-5.15.6+kde49/tests/auto/client/seatv5/tst_seatv5.cpp --- old/qtwayland-everywhere-src-5.15.5+kde39/tests/auto/client/seatv5/tst_seatv5.cpp 2022-06-20 22:17:21.000000000 +0200 +++ new/qtwayland-everywhere-src-5.15.6+kde49/tests/auto/client/seatv5/tst_seatv5.cpp 2022-09-22 13:58:55.000000000 +0200 @@ -73,6 +73,7 @@ void multiTouch(); void multiTouchUpAndMotionFrame(); void tapAndMoveInSameFrame(); + void cancelTouch(); }; void tst_seatv5::bindsToSeat() @@ -646,5 +647,34 @@ QTRY_COMPARE(window.m_events.last().touchPoints.first().state(), Qt::TouchPointState::TouchPointReleased); } +void tst_seatv5::cancelTouch() +{ + TouchWindow window; + QCOMPOSITOR_TRY_VERIFY(xdgSurface() && xdgSurface()->m_committedConfigureSerial); + + exec([=] { + auto *t = touch(); + auto *c = client(); + t->sendDown(xdgToplevel()->surface(), {32, 32}, 1); + t->sendFrame(c); + t->sendCancel(c); + t->sendFrame(c); + }); + + QTRY_VERIFY(!window.m_events.empty()); + { + auto e = window.m_events.takeFirst(); + QCOMPARE(e.type, QEvent::TouchBegin); + QCOMPARE(e.touchPointStates, Qt::TouchPointPressed); + QCOMPARE(e.touchPoints.length(), 1); + QCOMPARE(e.touchPoints.first().pos(), QPointF(32-window.frameMargins().left(), 32-window.frameMargins().top())); + } + { + auto e = window.m_events.takeFirst(); + QCOMPARE(e.type, QEvent::TouchCancel); + QCOMPARE(e.touchPoints.length(), 0); + } +} + QCOMPOSITOR_TEST_MAIN(tst_seatv5) #include "tst_seatv5.moc" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtwayland-everywhere-src-5.15.5+kde39/tests/auto/client/shared/corecompositor.cpp new/qtwayland-everywhere-src-5.15.6+kde49/tests/auto/client/shared/corecompositor.cpp --- old/qtwayland-everywhere-src-5.15.5+kde39/tests/auto/client/shared/corecompositor.cpp 2022-06-20 22:17:21.000000000 +0200 +++ new/qtwayland-everywhere-src-5.15.6+kde49/tests/auto/client/shared/corecompositor.cpp 2022-09-22 13:58:55.000000000 +0200 @@ -27,6 +27,7 @@ ****************************************************************************/ #include "corecompositor.h" +#include <thread> namespace MockCompositor { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtwayland-everywhere-src-5.15.5+kde39/tests/auto/client/shared/coreprotocol.cpp new/qtwayland-everywhere-src-5.15.6+kde49/tests/auto/client/shared/coreprotocol.cpp --- old/qtwayland-everywhere-src-5.15.5+kde39/tests/auto/client/shared/coreprotocol.cpp 2022-06-20 22:17:21.000000000 +0200 +++ new/qtwayland-everywhere-src-5.15.6+kde49/tests/auto/client/shared/coreprotocol.cpp 2022-09-22 13:58:55.000000000 +0200 @@ -451,6 +451,13 @@ send_frame(r->handle); } +void Touch::sendCancel(wl_client *client) +{ + const auto touchResources = resourceMap().values(client); + for (auto *r : touchResources) + send_cancel(r->handle); +} + uint Keyboard::sendEnter(Surface *surface) { auto serial = m_seat->m_compositor->nextSerial(); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtwayland-everywhere-src-5.15.5+kde39/tests/auto/client/shared/coreprotocol.h new/qtwayland-everywhere-src-5.15.6+kde49/tests/auto/client/shared/coreprotocol.h --- old/qtwayland-everywhere-src-5.15.5+kde39/tests/auto/client/shared/coreprotocol.h 2022-06-20 22:17:21.000000000 +0200 +++ new/qtwayland-everywhere-src-5.15.6+kde49/tests/auto/client/shared/coreprotocol.h 2022-09-22 13:58:55.000000000 +0200 @@ -364,6 +364,7 @@ uint sendUp(wl_client *client, int id); void sendMotion(wl_client *client, const QPointF &position, int id); void sendFrame(wl_client *client); + void sendCancel(wl_client *client); Seat *m_seat = nullptr; }; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtwayland-everywhere-src-5.15.5+kde39/tests/auto/client/surface/tst_surface.cpp new/qtwayland-everywhere-src-5.15.6+kde49/tests/auto/client/surface/tst_surface.cpp --- old/qtwayland-everywhere-src-5.15.5+kde39/tests/auto/client/surface/tst_surface.cpp 2022-06-20 22:17:21.000000000 +0200 +++ new/qtwayland-everywhere-src-5.15.6+kde49/tests/auto/client/surface/tst_surface.cpp 2022-09-22 13:58:55.000000000 +0200 @@ -129,6 +129,10 @@ // Make sure we follow frame callbacks for some frames for (int i = 0; i < 5; ++i) { xdgPingAndWaitForPong(); // Make sure things have happened on the client + if (!qEnvironmentVariableIntValue("QT_WAYLAND_DISABLE_WINDOWDECORATION") && i == 0) { + QCOMPARE(bufferSpy.count(), 1); + bufferSpy.removeFirst(); + } exec([&] { QVERIFY(bufferSpy.empty()); // Make sure no extra buffers have arrived QVERIFY(!xdgToplevel()->surface()->m_waitingFrameCallbacks.empty()); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtwayland-everywhere-src-5.15.5+kde39/tests/auto/client/xdgshell/tst_xdgshell.cpp new/qtwayland-everywhere-src-5.15.6+kde49/tests/auto/client/xdgshell/tst_xdgshell.cpp --- old/qtwayland-everywhere-src-5.15.5+kde39/tests/auto/client/xdgshell/tst_xdgshell.cpp 2022-06-20 22:17:21.000000000 +0200 +++ new/qtwayland-everywhere-src-5.15.6+kde49/tests/auto/client/xdgshell/tst_xdgshell.cpp 2022-09-22 13:58:55.000000000 +0200 @@ -46,6 +46,7 @@ void configureStates(); void popup(); void tooltipOnPopup(); + void tooltipAndSiblingPopup(); void switchPopups(); void hidePopupParent(); void pongs(); @@ -345,6 +346,92 @@ QCOMPOSITOR_TRY_COMPARE(xdgPopup(1), nullptr); QCOMPOSITOR_TRY_COMPARE(xdgPopup(0), nullptr); } + +void tst_xdgshell::tooltipAndSiblingPopup() +{ + class ToolTip : public QRasterWindow { + public: + explicit ToolTip(QWindow *parent) { + setTransientParent(parent); + setFlags(Qt::ToolTip); + resize(100, 100); + show(); + } + void mousePressEvent(QMouseEvent *event) override { + QRasterWindow::mousePressEvent(event); + m_popup = new QRasterWindow; + m_popup->setTransientParent(transientParent()); + m_popup->setFlags(Qt::Popup); + m_popup->resize(100, 100); + m_popup->show(); + } + + QRasterWindow *m_popup = nullptr; + }; + + class Window : public QRasterWindow { + public: + void mousePressEvent(QMouseEvent *event) override { + QRasterWindow::mousePressEvent(event); + m_tooltip = new ToolTip(this); + } + ToolTip *m_tooltip = nullptr; + }; + + Window window; + window.resize(200, 200); + window.show(); + + QCOMPOSITOR_TRY_VERIFY(xdgToplevel()); + exec([=] { xdgToplevel()->sendCompleteConfigure(); }); + QCOMPOSITOR_TRY_VERIFY(xdgToplevel()->m_xdgSurface->m_committedConfigureSerial); + + exec([=] { + auto *surface = xdgToplevel()->surface(); + auto *p = pointer(); + auto *c = client(); + p->sendEnter(surface, {100, 100}); + p->sendFrame(c); + p->sendButton(client(), BTN_LEFT, Pointer::button_state_pressed); + p->sendButton(client(), BTN_LEFT, Pointer::button_state_released); + p->sendFrame(c); + p->sendLeave(surface); + p->sendFrame(c); + }); + + QCOMPOSITOR_TRY_VERIFY(xdgPopup()); + exec([=] { xdgPopup()->sendCompleteConfigure(QRect(100, 100, 100, 100)); }); + QCOMPOSITOR_TRY_VERIFY(xdgPopup()->m_xdgSurface->m_committedConfigureSerial); + QCOMPOSITOR_TRY_VERIFY(!xdgPopup()->m_grabbed); + + exec([=] { + auto *surface = xdgPopup()->surface(); + auto *p = pointer(); + auto *c = client(); + p->sendEnter(surface, {100, 100}); + p->sendFrame(c); + p->sendButton(client(), BTN_LEFT, Pointer::button_state_pressed); + p->sendButton(client(), BTN_LEFT, Pointer::button_state_released); + p->sendFrame(c); + }); + + QCOMPOSITOR_TRY_VERIFY(xdgPopup(1)); + exec([=] { xdgPopup(1)->sendCompleteConfigure(QRect(100, 100, 100, 100)); }); + QCOMPOSITOR_TRY_VERIFY(xdgPopup(1)->m_xdgSurface->m_committedConfigureSerial); + QCOMPOSITOR_TRY_VERIFY(xdgPopup(1)->m_grabbed); + + // Close the middle tooltip (it should not close the sibling popup) + window.m_tooltip->close(); + + QCOMPOSITOR_TRY_COMPARE(xdgPopup(1), nullptr); + // Verify the remaining xdg surface is a grab popup.. + QCOMPOSITOR_TRY_VERIFY(xdgPopup(0)); + QCOMPOSITOR_TRY_VERIFY(xdgPopup(0)->m_grabbed); + + window.m_tooltip->m_popup->close(); + QCOMPOSITOR_TRY_COMPARE(xdgPopup(1), nullptr); + QCOMPOSITOR_TRY_COMPARE(xdgPopup(0), nullptr); +} // QTBUG-65680 void tst_xdgshell::switchPopups() ++++++ qtwayland-everywhere-src.obsinfo ++++++ --- /var/tmp/diff_new_pack.NQQh0U/_old 2022-09-27 20:10:19.917350805 +0200 +++ /var/tmp/diff_new_pack.NQQh0U/_new 2022-09-27 20:10:19.921350814 +0200 @@ -1,5 +1,5 @@ name: qtwayland-everywhere-src -version: 5.15.5+kde39 -mtime: 1655756241 -commit: 64fa557eb30fc1219bec50a45107ea1a983411ed +version: 5.15.6+kde49 +mtime: 1663847935 +commit: 31241d7fb6a7ffb8f56bc8ac35ed9f3bc61735b5