diff --git a/dev-qt/qtwayland/files/qtwayland-5.15.7-QTBUG-85297.patch b/dev-qt/qtwayland/files/qtwayland-5.15.7-QTBUG-85297.patch new file mode 100644 index 000000000..df190d97e --- /dev/null +++ b/dev-qt/qtwayland/files/qtwayland-5.15.7-QTBUG-85297.patch @@ -0,0 +1,89 @@ +From c48e4e472e02410f1ebca52be98f9c99fe18b551 Mon Sep 17 00:00:00 2001 +From: David Redondo +Date: Wed, 8 Jun 2022 11:25:59 +0200 +Subject: [PATCH] Keep toplevel windows in the top left corner of the screen + +We can't know the actual position of a window on the screen. This causes +an issue when Widgets try to position a popup/menu absolutely and keep +it on the screen when the screen geometry doesn't include (0,0). +Instead report their positions always as the top left corner of +the screen that they are on. +This new behavior can be disabled for qt-shell or via an environment +variable by users that rely on the old behavior. + +Fixes: QTBUG-85297 +Change-Id: Iacb91cb03a0df87af950115760d2f41124ac06a3 +Reviewed-by: Qt CI Bot +Reviewed-by: David Edmundson +Reviewed-by: Aleix Pol Gonzalez +--- + src/client/qwaylandintegration.cpp | 4 ++++ + src/client/qwaylandwindow.cpp | 14 +++++++++++++- + src/client/qwaylandwindow_p.h | 3 +++ + 3 files changed, 20 insertions(+), 1 deletion(-) + +diff --git a/src/client/qwaylandintegration.cpp b/src/client/qwaylandintegration.cpp +index fbf00c6b..5cd414e5 100644 +--- a/src/client/qwaylandintegration.cpp ++++ b/src/client/qwaylandintegration.cpp +@@ -117,6 +117,10 @@ QWaylandIntegration::QWaylandIntegration() + mFailed = true; + return; + } ++ ++ QWaylandWindow::fixedToplevelPositions = ++ !qEnvironmentVariableIsSet("QT_WAYLAND_DISABLE_FIXED_POSITIONS"); ++ + #if QT_CONFIG(clipboard) + mClipboard.reset(new QWaylandClipboard(mDisplay.data())); + #endif +diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp +index 771c96cc..d4083121 100644 +--- a/src/client/qwaylandwindow.cpp ++++ b/src/client/qwaylandwindow.cpp +@@ -350,8 +350,13 @@ void QWaylandWindow::setGeometry_helper(const QRect &rect) + } + } + +-void QWaylandWindow::setGeometry(const QRect &rect) ++void QWaylandWindow::setGeometry(const QRect &r) + { ++ auto rect = r; ++ if (fixedToplevelPositions && !QPlatformWindow::parent() && window()->type() != Qt::Popup ++ && window()->type() != Qt::ToolTip) { ++ rect.moveTo(screen()->geometry().topLeft()); ++ } + setGeometry_helper(rect); + + if (window()->isVisible() && rect.isValid()) { +@@ -1033,6 +1038,13 @@ void QWaylandWindow::handleScreensChanged() + + QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->QPlatformScreen::screen()); + mLastReportedScreen = newScreen; ++ if (fixedToplevelPositions && !QPlatformWindow::parent() && window()->type() != Qt::Popup ++ && window()->type() != Qt::ToolTip ++ && geometry().topLeft() != newScreen->geometry().topLeft()) { ++ auto geometry = this->geometry(); ++ geometry.moveTo(newScreen->geometry().topLeft()); ++ setGeometry(geometry); ++ } + + int scale = newScreen->isPlaceholder() ? 1 : static_cast(newScreen)->scale(); + if (scale != mScale) { +diff --git a/src/client/qwaylandwindow_p.h b/src/client/qwaylandwindow_p.h +index ea3d1995..487a91a6 100644 +--- a/src/client/qwaylandwindow_p.h ++++ b/src/client/qwaylandwindow_p.h +@@ -98,6 +98,9 @@ public: + QWaylandWindow(QWindow *window, QWaylandDisplay *display); + ~QWaylandWindow() override; + ++ // Keep Toplevels position on the top left corner of their screen ++ static inline bool fixedToplevelPositions = true; ++ + virtual WindowType windowType() const = 0; + virtual void ensureSize(); + WId winId() const override; +-- +GitLab + diff --git a/dev-qt/qtwayland/files/qtwayland-5.15.7-ensure-wl_surface-longevity.patch b/dev-qt/qtwayland/files/qtwayland-5.15.7-ensure-wl_surface-longevity.patch new file mode 100644 index 000000000..273e78fdf --- /dev/null +++ b/dev-qt/qtwayland/files/qtwayland-5.15.7-ensure-wl_surface-longevity.patch @@ -0,0 +1,109 @@ +From 81a7702a87f386a60a0ac8c902e203daae044d81 Mon Sep 17 00:00:00 2001 +From: Vlad Zahorodnii +Date: Tue, 8 Nov 2022 16:10:18 +0200 +Subject: [PATCH] Client: Ensure that wl_surface lives as long as qtquick + render thread needs it + +wl_surface can be destroyed while qtquick render thread still uses it. +That can end up in eglSwapBuffers() using defunct wl_surface, which will +eventually lead to a crash due to the compositor posting an error. + +This is partially cherry-pick of dff579147b07cd15888a47c303e36684e9930f9f + +Change-Id: I044f40dd64e6672027a833379b57ccd9973d8305 +--- + src/client/qwaylandwindow.cpp | 13 ++++++++++++- + src/client/qwaylandwindow_p.h | 3 +++ + .../client/wayland-egl/qwaylandglcontext.cpp | 6 +++++- + 3 files changed, 20 insertions(+), 2 deletions(-) + +diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp +index 771c96cc..5b97cd55 100644 +--- a/src/client/qwaylandwindow.cpp ++++ b/src/client/qwaylandwindow.cpp +@@ -76,6 +76,7 @@ QWaylandWindow *QWaylandWindow::mMouseGrab = nullptr; + QWaylandWindow::QWaylandWindow(QWindow *window, QWaylandDisplay *display) + : QPlatformWindow(window) + , mDisplay(display) ++ , mSurfaceLock(QReadWriteLock::Recursive) + , mResizeAfterSwap(qEnvironmentVariableIsSet("QT_WAYLAND_RESIZE_AFTER_SWAP")) + { + { +@@ -237,6 +238,16 @@ bool QWaylandWindow::shouldCreateSubSurface() const + return QPlatformWindow::parent() != nullptr; + } + ++void QWaylandWindow::beginFrame() ++{ ++ mSurfaceLock.lockForRead(); ++} ++ ++void QWaylandWindow::endFrame() ++{ ++ mSurfaceLock.unlock(); ++} ++ + void QWaylandWindow::reset() + { + closeChildPopups(); +@@ -245,10 +256,10 @@ void QWaylandWindow::reset() + delete mSubSurfaceWindow; + mSubSurfaceWindow = nullptr; + +- invalidateSurface(); + if (mSurface) { + emit wlSurfaceDestroyed(); + QWriteLocker lock(&mSurfaceLock); ++ invalidateSurface(); + mSurface.reset(); + } + +diff --git a/src/client/qwaylandwindow_p.h b/src/client/qwaylandwindow_p.h +index ea3d1995..e18609d9 100644 +--- a/src/client/qwaylandwindow_p.h ++++ b/src/client/qwaylandwindow_p.h +@@ -207,6 +207,9 @@ public: + void handleUpdate(); + void deliverUpdateRequest() override; + ++ void beginFrame(); ++ void endFrame(); ++ + void addChildPopup(QWaylandWindow* child); + void removeChildPopup(QWaylandWindow* child); + void closeChildPopups(); +diff --git a/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp b/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp +index c1f45fa6..5d6fb2bf 100644 +--- a/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp ++++ b/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp +@@ -432,8 +432,10 @@ bool QWaylandGLContext::makeCurrent(QPlatformSurface *surface) + return true; + } + +- if (window->isExposed()) ++ if (window->isExposed()) { ++ window->beginFrame(); + window->setCanResize(false); ++ } + if (m_decorationsContext != EGL_NO_CONTEXT && !window->decoration()) + window->createDecoration(); + +@@ -449,6 +451,7 @@ bool QWaylandGLContext::makeCurrent(QPlatformSurface *surface) + if (!eglMakeCurrent(m_eglDisplay, eglSurface, eglSurface, m_context)) { + qWarning("QWaylandGLContext::makeCurrent: eglError: %x, this: %p \n", eglGetError(), this); + window->setCanResize(true); ++ window->endFrame(); + return false; + } + +@@ -502,6 +505,7 @@ void QWaylandGLContext::swapBuffers(QPlatformSurface *surface) + eglSwapBuffers(m_eglDisplay, eglSurface); + + window->setCanResize(true); ++ window->endFrame(); + } + + GLuint QWaylandGLContext::defaultFramebufferObject(QPlatformSurface *surface) const +-- +GitLab + diff --git a/dev-qt/qtwayland/qtwayland-5.15.7.ebuild b/dev-qt/qtwayland/qtwayland-5.15.7.ebuild index 1f287004d..64a1ea280 100644 --- a/dev-qt/qtwayland/qtwayland-5.15.7.ebuild +++ b/dev-qt/qtwayland/qtwayland-5.15.7.ebuild @@ -31,6 +31,14 @@ DEPEND=" RDEPEND="${DEPEND}" BDEPEND="dev-util/wayland-scanner" +PATCHES=( + # Pending upstream: + # https://invent.kde.org/qt/qt/qtwayland/-/merge_requests/47 + "${FILESDIR}/${P}-QTBUG-85297.patch" + # https://invent.kde.org/qt/qt/qtwayland/-/merge_requests/57/commits + "${FILESDIR}/${P}-ensure-wl_surface-longevity.patch" +) + src_configure() { local myqmakeargs=( --