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 2021-05-20 19:24:23 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/libqt5-qtwayland (Old) and /work/SRC/openSUSE:Factory/.libqt5-qtwayland.new.2988 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "libqt5-qtwayland" Thu May 20 19:24:23 2021 rev:38 rq:893822 version:5.15.2 Changes: -------- --- /work/SRC/openSUSE:Factory/libqt5-qtwayland/libqt5-qtwayland.changes 2021-01-26 14:44:13.587206623 +0100 +++ /work/SRC/openSUSE:Factory/.libqt5-qtwayland.new.2988/libqt5-qtwayland.changes 2021-05-20 19:24:35.058059642 +0200 @@ -1,0 +2,31 @@ +Sun May 16 18:22:15 UTC 2021 - Fabian Vogt <fab...@ritter-vogt.de> + +- Add more commits from KDE's 5.15 branch: + * 0008-Fix-memory-leak-in-QWaylandGLContext.patch (QTBUG-85608) + * 0009-Client-Send-set_window_geometry-only-once-configured.patch + * 0010-Translate-opaque-area-with-frame-margins.patch + * 0011-Client-Send-exposeEvent-to-parent-on-subsurface-posi.patch + (QTBUG-86177) + * 0012-Get-correct-decoration-margins-region.patch + * 0013-xdgshell-Tell-the-compositor-the-screen-we-re-expect.patch + * 0014-Fix-compilation.patch + * 0015-client-Allow-QWaylandInputContext-to-accept-composed.patch + (kde#405388) + * 0016-Client-Announce-an-output-after-receiving-more-compl.patch + (kde#435124) + * 0017-Fix-issue-with-repeated-window-size-changes.patch + * 0018-Include-locale.h-for-setlocale-LC_CTYPE.patch + +------------------------------------------------------------------- +Wed Apr 7 06:55:22 UTC 2021 - Fabian Vogt <fab...@ritter-vogt.de> + +- Add commits from upstream's 5.15 branch: + * 0002-Make-setting-QT_SCALE_FACTOR-work-on-Wayland.patch (QTBUG-87762) + * 0003-Do-not-try-to-eglMakeCurrent-for-unintended-case.patch (QTBUG-88277) + * 0004-Make-setting-QT_SCALE_FACTOR-work-on-Wayland.patch (QTBUG-87762, QTBUG-88064) + * 0005-Ensure-that-grabbing-is-performed-in-correct-context.patch (QTBUG-87597) + * 0006-Fix-leaked-subsurface-wayland-items.patch (QTBUG-88782) +- Add commit from KDE's 5.15 branch: + * 0007-Use-qWarning-and-_exit-instead-of-qFatal-for-wayland.patch + +------------------------------------------------------------------- New: ---- 0002-Make-setting-QT_SCALE_FACTOR-work-on-Wayland.patch 0003-Do-not-try-to-eglMakeCurrent-for-unintended-case.patch 0004-Make-setting-QT_SCALE_FACTOR-work-on-Wayland.patch 0005-Ensure-that-grabbing-is-performed-in-correct-context.patch 0006-Fix-leaked-subsurface-wayland-items.patch 0007-Use-qWarning-and-_exit-instead-of-qFatal-for-wayland.patch 0008-Fix-memory-leak-in-QWaylandGLContext.patch 0009-Client-Send-set_window_geometry-only-once-configured.patch 0010-Translate-opaque-area-with-frame-margins.patch 0011-Client-Send-exposeEvent-to-parent-on-subsurface-posi.patch 0012-Get-correct-decoration-margins-region.patch 0013-xdgshell-Tell-the-compositor-the-screen-we-re-expect.patch 0014-Fix-compilation.patch 0015-client-Allow-QWaylandInputContext-to-accept-composed.patch 0016-Client-Announce-an-output-after-receiving-more-compl.patch 0017-Fix-issue-with-repeated-window-size-changes.patch 0018-Include-locale.h-for-setlocale-LC_CTYPE.patch ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ libqt5-qtwayland.spec ++++++ --- /var/tmp/diff_new_pack.EpbBN4/_old 2021-05-20 19:24:35.786056655 +0200 +++ /var/tmp/diff_new_pack.EpbBN4/_new 2021-05-20 19:24:35.790056640 +0200 @@ -36,7 +36,24 @@ Source: https://download.qt.io/official_releases/qt/5.15/%{real_version}/submodules/%{tar_version}.tar.xz Source1: baselibs.conf # PATCH-FIX-UPSTREAM -Patch0: 0001-Scanner-Avoid-accessing-dangling-pointers-in-destroy.patch +Patch1: 0001-Scanner-Avoid-accessing-dangling-pointers-in-destroy.patch +Patch2: 0002-Make-setting-QT_SCALE_FACTOR-work-on-Wayland.patch +Patch3: 0003-Do-not-try-to-eglMakeCurrent-for-unintended-case.patch +Patch4: 0004-Make-setting-QT_SCALE_FACTOR-work-on-Wayland.patch +Patch5: 0005-Ensure-that-grabbing-is-performed-in-correct-context.patch +Patch6: 0006-Fix-leaked-subsurface-wayland-items.patch +Patch7: 0007-Use-qWarning-and-_exit-instead-of-qFatal-for-wayland.patch +Patch8: 0008-Fix-memory-leak-in-QWaylandGLContext.patch +Patch9: 0009-Client-Send-set_window_geometry-only-once-configured.patch +Patch10: 0010-Translate-opaque-area-with-frame-margins.patch +Patch11: 0011-Client-Send-exposeEvent-to-parent-on-subsurface-posi.patch +Patch12: 0012-Get-correct-decoration-margins-region.patch +Patch13: 0013-xdgshell-Tell-the-compositor-the-screen-we-re-expect.patch +Patch14: 0014-Fix-compilation.patch +Patch15: 0015-client-Allow-QWaylandInputContext-to-accept-composed.patch +Patch16: 0016-Client-Announce-an-output-after-receiving-more-compl.patch +Patch17: 0017-Fix-issue-with-repeated-window-size-changes.patch +Patch18: 0018-Include-locale.h-for-setlocale-LC_CTYPE.patch BuildRequires: fdupes BuildRequires: libqt5-qtbase-private-headers-devel >= %{version} BuildRequires: libqt5-qtdeclarative-private-headers-devel >= %{version} ++++++ 0002-Make-setting-QT_SCALE_FACTOR-work-on-Wayland.patch ++++++ >From a825fb5f714fd79d16cc3ebbdd327e7961b07d0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= <morten.sor...@qt.io> Date: Mon, 16 Nov 2020 19:37:33 +0100 Subject: [PATCH 2/7] Make setting QT_SCALE_FACTOR work on Wayland Follow-up to 8cb1b07aea12d50b4fecc45c903705dfd368022a, fixes one additional case (Use of minimum/maximum size). Fixes: QTBUG-87762 Change-Id: I73e0df2529b0cadf25ad50ea7459cdbb92caf424 Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfe...@qt.io> (cherry picked from commit 6ed363e3665f17d935f8636d9c958154c898f5c5) Reviewed-by: Qt Cherry-pick Bot <cherrypick_...@qt-project.org> --- src/client/qwaylandwindow.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp index bc031ed5..eb053406 100644 --- a/src/client/qwaylandwindow.cpp +++ b/src/client/qwaylandwindow.cpp @@ -332,9 +332,11 @@ void QWaylandWindow::setWindowIcon(const QIcon &icon) void QWaylandWindow::setGeometry_helper(const QRect &rect) { + QSize minimum = windowMinimumSize(); + QSize maximum = windowMaximumSize(); QPlatformWindow::setGeometry(QRect(rect.x(), rect.y(), - qBound(window()->minimumWidth(), rect.width(), window()->maximumWidth()), - qBound(window()->minimumHeight(), rect.height(), window()->maximumHeight()))); + qBound(minimum.width(), rect.width(), maximum.width()), + qBound(minimum.height(), rect.height(), maximum.height()))); if (mSubSurfaceWindow) { QMargins m = QPlatformWindow::parent()->frameMargins(); -- 2.25.1 ++++++ 0003-Do-not-try-to-eglMakeCurrent-for-unintended-case.patch ++++++ >From 2c0a03e9aea13831d05ac03996949f888afd5085 Mon Sep 17 00:00:00 2001 From: Jaehak Lee <jaehak....@mobis.co.kr> Date: Sun, 8 Nov 2020 11:40:06 +0900 Subject: [PATCH 3/7] Do not try to eglMakeCurrent for unintended case The QSGThreadedRenderLoop::hide can be called at twice, when the QWindowPrivate::setVisible(false) is called. The eglSurface is EGL_NO_SURFACE when the second QSGThreadedRenderLoop::hide is called. And if EGL_KHR_surfaceless_context is supported, the eglMakeCurrent don't return the false. But this case is not intended. So, add the defence code for above case. Fixes: QTBUG-88277 Change-Id: Ia9e5990303e98f0eedc48531e5af62ff9961f419 Reviewed-by: Laszlo Agocs <laszlo.ag...@qt.io> Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfe...@qt.io> --- .../client/wayland-egl/qwaylandglcontext.cpp | 6 ++++++ .../client/wayland-egl/qwaylandglcontext.h | 1 + 2 files changed, 7 insertions(+) diff --git a/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp b/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp index ccebf43d..681f82f4 100644 --- a/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp +++ b/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp @@ -336,6 +336,8 @@ QWaylandGLContext::QWaylandGLContext(EGLDisplay eglDisplay, QWaylandDisplay *dis << "It may also cause the event loop to freeze in some situations"; } + m_supportSurfaceLessContext = q_hasEglExtension(m_eglDisplay, "EGL_KHR_surfaceless_context"); + updateGLFormat(); } @@ -439,6 +441,10 @@ bool QWaylandGLContext::makeCurrent(QPlatformSurface *surface) eglSurface = window->eglSurface(); } + if (eglSurface == EGL_NO_SURFACE && m_supportSurfaceLessContext) { + return false; + } + if (!eglMakeCurrent(m_eglDisplay, eglSurface, eglSurface, m_context)) { qWarning("QWaylandGLContext::makeCurrent: eglError: %x, this: %p \n", eglGetError(), this); window->setCanResize(true); diff --git a/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.h b/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.h index 46c7bb76..93edaec0 100644 --- a/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.h +++ b/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.h @@ -93,6 +93,7 @@ private: DecorationsBlitter *m_blitter = nullptr; uint m_api; bool m_supportNonBlockingSwap = true; + bool m_supportSurfaceLessContext = false; }; } -- 2.25.1 ++++++ 0004-Make-setting-QT_SCALE_FACTOR-work-on-Wayland.patch ++++++ >From 10005185e06857ce119c50fe710f9eedde06ec5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= <morten.sor...@qt.io> Date: Fri, 13 Nov 2020 11:21:50 +0100 Subject: [PATCH 4/7] Make setting QT_SCALE_FACTOR work on Wayland QWindow geometry accessors return geometry in device independent pixels. Normally this coordinate system is equivalent to the Wayland native coordinate system, but this is not the case when QT_SCALE_FACTOR is set. Replace QWindow geometry calls with the helpers from QPlatformWindow which return geometry in the native coordinate system: QWindow::geometry() -> QPlatformWindow::windowGeometry() QWindow::frameGeometry() -> QPlatformWindow::windowFrameGeometry() Task-number: QTBUG-87762 Fixes: QTBUG-88064 (cherry-picked from commit 8cb1b07aea12d50b4fecc45c903705dfd368022a) Change-Id: I6e2029bc6210f12441ae7c9d8b678271e9922dde Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfe...@qt.io> --- src/client/qwaylandwindow.cpp | 7 ++++--- .../shellintegration/wl-shell/qwaylandwlshellsurface.cpp | 2 +- .../shellintegration/xdg-shell-v5/qwaylandxdgsurfacev5.cpp | 2 +- .../shellintegration/xdg-shell-v6/qwaylandxdgshellv6.cpp | 2 +- .../shellintegration/xdg-shell/qwaylandxdgshell.cpp | 2 +- 5 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp index eb053406..9b343702 100644 --- a/src/client/qwaylandwindow.cpp +++ b/src/client/qwaylandwindow.cpp @@ -194,10 +194,11 @@ void QWaylandWindow::initWindow() if (QScreen *s = window()->screen()) setOrientationMask(s->orientationUpdateMask()); setWindowFlags(window()->flags()); - if (window()->geometry().isEmpty()) + QRect geometry = windowGeometry(); + if (geometry.isEmpty()) setGeometry_helper(QRect(QPoint(), QSize(500,500))); else - setGeometry_helper(window()->geometry()); + setGeometry_helper(geometry); setMask(window()->mask()); if (mShellSurface) mShellSurface->requestWindowStates(window()->windowStates()); @@ -431,7 +432,7 @@ void QWaylandWindow::setVisible(bool visible) initWindow(); mDisplay->flushRequests(); - setGeometry(window()->geometry()); + setGeometry(windowGeometry()); // Don't flush the events here, or else the newly visible window may start drawing, but since // there was no frame before it will be stuck at the waitForFrameSync() in // QWaylandShmBackingStore::beginPaint(). diff --git a/src/plugins/shellintegration/wl-shell/qwaylandwlshellsurface.cpp b/src/plugins/shellintegration/wl-shell/qwaylandwlshellsurface.cpp index 245fec19..8f41118d 100644 --- a/src/plugins/shellintegration/wl-shell/qwaylandwlshellsurface.cpp +++ b/src/plugins/shellintegration/wl-shell/qwaylandwlshellsurface.cpp @@ -134,7 +134,7 @@ void QWaylandWlShellSurface::applyConfigure() { if ((m_pending.states & (Qt::WindowMaximized|Qt::WindowFullScreen)) && !(m_applied.states & (Qt::WindowMaximized|Qt::WindowFullScreen))) { - m_normalSize = m_window->window()->frameGeometry().size(); + m_normalSize = m_window->windowFrameGeometry().size(); } if (m_pending.states != m_applied.states) diff --git a/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgsurfacev5.cpp b/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgsurfacev5.cpp index 770fad7e..73aba1ee 100644 --- a/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgsurfacev5.cpp +++ b/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgsurfacev5.cpp @@ -157,7 +157,7 @@ void QWaylandXdgSurfaceV5::applyConfigure() if (m_pending.isResizing) m_normalSize = m_pending.size; else if (!(m_acked.states & (Qt::WindowMaximized|Qt::WindowFullScreen))) - m_normalSize = m_window->window()->frameGeometry().size(); + m_normalSize = m_window->windowFrameGeometry().size(); if ((m_pending.states & Qt::WindowActive) && !(m_acked.states & Qt::WindowActive)) m_window->display()->handleWindowActivated(m_window); diff --git a/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6.cpp b/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6.cpp index c137b308..8c371661 100644 --- a/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6.cpp +++ b/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6.cpp @@ -72,7 +72,7 @@ QWaylandXdgSurfaceV6::Toplevel::~Toplevel() void QWaylandXdgSurfaceV6::Toplevel::applyConfigure() { if (!(m_applied.states & (Qt::WindowMaximized|Qt::WindowFullScreen))) - m_normalSize = m_xdgSurface->m_window->window()->frameGeometry().size(); + m_normalSize = m_xdgSurface->m_window->windowFrameGeometry().size(); if ((m_pending.states & Qt::WindowActive) && !(m_applied.states & Qt::WindowActive)) m_xdgSurface->m_window->display()->handleWindowActivated(m_xdgSurface->m_window); diff --git a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp index b6d23ac1..1c762944 100644 --- a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp +++ b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp @@ -83,7 +83,7 @@ QWaylandXdgSurface::Toplevel::~Toplevel() void QWaylandXdgSurface::Toplevel::applyConfigure() { if (!(m_applied.states & (Qt::WindowMaximized|Qt::WindowFullScreen))) - m_normalSize = m_xdgSurface->m_window->window()->frameGeometry().size(); + m_normalSize = m_xdgSurface->m_window->windowFrameGeometry().size(); if ((m_pending.states & Qt::WindowActive) && !(m_applied.states & Qt::WindowActive)) m_xdgSurface->m_window->display()->handleWindowActivated(m_xdgSurface->m_window); -- 2.25.1 ++++++ 0005-Ensure-that-grabbing-is-performed-in-correct-context.patch ++++++ >From dba4bc4f1d6dfee9fe9433c55b15653d703bed4f Mon Sep 17 00:00:00 2001 From: Andreas Cord-Landwehr <cordlandw...@kde.org> Date: Wed, 2 Dec 2020 20:55:52 +0100 Subject: [PATCH 5/7] Ensure that grabbing is performed in correct context For multi-display rendering on EGL, it is mandatory that the grabbing of the surface happens in the same EGL context as the surface belongs to. By adding the grabbing to the rendering stage of the image, this relation is forced. Task-number: QTBUG-87597 Change-Id: I50f40df1215aa771d714065e942c5a738ba6269f Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfe...@qt.io> (cherry picked from commit ab3a1a07f3d1e0d5a9e9d97b6b3b587180e2f4c8) Reviewed-by: Qt Cherry-pick Bot <cherrypick_...@qt-project.org> --- src/compositor/compositor_api/qwaylandquickcompositor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compositor/compositor_api/qwaylandquickcompositor.cpp b/src/compositor/compositor_api/qwaylandquickcompositor.cpp index 49f0860e..db1cf00f 100644 --- a/src/compositor/compositor_api/qwaylandquickcompositor.cpp +++ b/src/compositor/compositor_api/qwaylandquickcompositor.cpp @@ -161,7 +161,7 @@ void QWaylandQuickCompositor::grabSurface(QWaylandSurfaceGrabber *grabber, const GrabState *state = new GrabState; state->grabber = grabber; state->buffer = buffer; - static_cast<QQuickWindow *>(output->window())->scheduleRenderJob(state, QQuickWindow::NoStage); + static_cast<QQuickWindow *>(output->window())->scheduleRenderJob(state, QQuickWindow::AfterRenderingStage); #else emit grabber->failed(QWaylandSurfaceGrabber::UnknownBufferType); #endif -- 2.25.1 ++++++ 0006-Fix-leaked-subsurface-wayland-items.patch ++++++ >From a8d35b3c18bdb05a0da3ed50a554a7b7bd4ebed3 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfe...@qt.io> Date: Mon, 30 Nov 2020 13:13:18 +0100 Subject: [PATCH 6/7] Fix leaked subsurface wayland items Whenever a subsurface was added we would create a QWaylandQuickItem, but this was never deleted. It is one-to-one with the surface, so it should be deleted at the same time. [ChangeLog][QtWaylandCompositor] Fixed a memory leak when creating subsurfaces. Task-number: QTBUG-88782 Change-Id: If4b3f15200ce3bd123ff73847d3593d174a39229 Reviewed-by: Paul Olav Tvete <paul.tv...@qt.io> (cherry picked from commit 38fc568b30bf916165324c2cd2db127d2a9aa68c) Reviewed-by: Qt Cherry-pick Bot <cherrypick_...@qt-project.org> --- src/compositor/compositor_api/qwaylandquickitem.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/compositor/compositor_api/qwaylandquickitem.cpp b/src/compositor/compositor_api/qwaylandquickitem.cpp index 15f0195c..2218f43a 100644 --- a/src/compositor/compositor_api/qwaylandquickitem.cpp +++ b/src/compositor/compositor_api/qwaylandquickitem.cpp @@ -737,6 +737,7 @@ void QWaylandQuickItem::handleSubsurfaceAdded(QWaylandSurface *childSurface) childItem->setVisible(true); childItem->setParentItem(this); connect(childSurface, &QWaylandSurface::subsurfacePositionChanged, childItem, &QWaylandQuickItem::handleSubsurfacePosition); + connect(childSurface, &QWaylandSurface::destroyed, childItem, &QObject::deleteLater); } else { bool success = QMetaObject::invokeMethod(d->subsurfaceHandler, "handleSubsurfaceAdded", Q_ARG(QWaylandSurface *, childSurface)); if (!success) -- 2.25.1 ++++++ 0007-Use-qWarning-and-_exit-instead-of-qFatal-for-wayland.patch ++++++ >From 9ee2ea141adc7765f6c212e63839ef23a4494b30 Mon Sep 17 00:00:00 2001 From: Weng Xuetian <wen...@gmail.com> Date: Tue, 9 Mar 2021 10:43:59 -0800 Subject: [PATCH 7/7] Use qWarning and _exit() instead of qFatal for wayland error This type of error is likely to happen upon system logout. qFatal would trigger sigabrt and leave unnecessary coredump on the system. Using qWarning here would make it consistent with xcb's io error. Pick-to: 5.15 6.0 6.1 Change-Id: I571ba007bf2453486b81837cccdbefa5f181b63d Reviewed-by: David Edmundson <davidedmund...@kde.org> --- src/client/qwaylanddisplay.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/client/qwaylanddisplay.cpp b/src/client/qwaylanddisplay.cpp index fe094f6f..f10c1f79 100644 --- a/src/client/qwaylanddisplay.cpp +++ b/src/client/qwaylanddisplay.cpp @@ -206,10 +206,11 @@ void QWaylandDisplay::checkError() const int ecode = wl_display_get_error(mDisplay); if ((ecode == EPIPE || ecode == ECONNRESET)) { // special case this to provide a nicer error - qFatal("The Wayland connection broke. Did the Wayland compositor die?"); + qWarning("The Wayland connection broke. Did the Wayland compositor die?"); } else { - qFatal("The Wayland connection experienced a fatal error: %s", strerror(ecode)); + qWarning("The Wayland connection experienced a fatal error: %s", strerror(ecode)); } + _exit(1); } void QWaylandDisplay::flushRequests() -- 2.25.1 ++++++ 0008-Fix-memory-leak-in-QWaylandGLContext.patch ++++++ >From 9df11e79b46c77d8c83f765b2a8e85b639fd55a2 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfe...@qt.io> Date: Tue, 5 Jan 2021 09:08:50 +0100 Subject: [PATCH 08/18] Fix memory leak in QWaylandGLContext We were leaking an EGL context with every GL context created, which lead to rapid OOM errors in stress tests. [ChangeLog][Qt Wayland Client] Fixed a memory leak when creating QOpenGLContexts on Wayland and using the wayland-egl backend. Fixes: QTBUG-85608 Pick-to: 5.15 Pick-to: 6.0 Change-Id: I8426b5df36ec7ab9e66ce15f9e02edad3aca60b9 Reviewed-by: David Edmundson <davidedmund...@kde.org> --- .../client/wayland-egl/qwaylandglcontext.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp b/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp index 681f82f4..befadedc 100644 --- a/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp +++ b/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp @@ -406,7 +406,9 @@ void QWaylandGLContext::updateGLFormat() QWaylandGLContext::~QWaylandGLContext() { delete m_blitter; - eglDestroyContext(m_eglDisplay, m_context); + m_blitter = nullptr; + if (m_decorationsContext != EGL_NO_CONTEXT) + eglDestroyContext(eglDisplay(), m_decorationsContext); } bool QWaylandGLContext::makeCurrent(QPlatformSurface *surface) -- 2.25.1 ++++++ 0009-Client-Send-set_window_geometry-only-once-configured.patch ++++++ >From 7db4f83c39d2a0c709bc0b9c0de3946d3b4ebfd5 Mon Sep 17 00:00:00 2001 From: David Edmundson <davidedmund...@kde.org> Date: Mon, 16 Nov 2020 14:57:36 +0000 Subject: [PATCH 09/18] Client: Send set_window_geometry only once configured The geometry only makes sense when a buffer exists, our currently send value is somewhat meaningless, but till now harmless. A specification clarification implies that it is an error if the calculated effective window geometry is null, rather than just checking the sent value. This is the case if set_window_geometry is sent before a buffer is attached. On our first configure call we enter resizeFromApplyConfigure which will hit this path and send the initial state. Pick-to: 5.15 Pick-to: 6.1 Pick-to: 6.0 Change-Id: Ib57ebe8b64210eae86e79dfdd6b5cb8a986b020b Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfe...@qt.io> --- src/client/qwaylandwindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp index 9b343702..e875af3a 100644 --- a/src/client/qwaylandwindow.cpp +++ b/src/client/qwaylandwindow.cpp @@ -365,7 +365,7 @@ void QWaylandWindow::setGeometry(const QRect &rect) if (isExposed() && !mInResizeFromApplyConfigure && exposeGeometry != mLastExposeGeometry) sendExposeEvent(exposeGeometry); - if (mShellSurface) + if (mShellSurface && isExposed()) mShellSurface->setWindowGeometry(windowContentGeometry()); if (isOpaque() && mMask.isEmpty()) -- 2.25.1 ++++++ 0010-Translate-opaque-area-with-frame-margins.patch ++++++ >From a3e3ac1c86a956b25b1dc24f14518b6e6c96bcfc Mon Sep 17 00:00:00 2001 From: Jan Grulich <jgrul...@redhat.com> Date: Wed, 10 Feb 2021 17:11:27 +0100 Subject: [PATCH 10/18] Translate opaque area with frame margins The opaque area doesn't take window decorations into account, which may result into possible graphical artefacts. Pick-to: 5.15 6.0 6.1 Change-Id: I1606e8256e7e204dad927931eb1221b576e227fd Reviewed-by: David Edmundson <davidedmund...@kde.org> --- src/client/qwaylandwindow.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp index e875af3a..2af39977 100644 --- a/src/client/qwaylandwindow.cpp +++ b/src/client/qwaylandwindow.cpp @@ -1234,12 +1234,14 @@ bool QWaylandWindow::isOpaque() const void QWaylandWindow::setOpaqueArea(const QRegion &opaqueArea) { - if (opaqueArea == mOpaqueArea || !mSurface) + const QRegion translatedOpaqueArea = opaqueArea.translated(frameMargins().left(), frameMargins().top()); + + if (translatedOpaqueArea == mOpaqueArea || !mSurface) return; - mOpaqueArea = opaqueArea; + mOpaqueArea = translatedOpaqueArea; - struct ::wl_region *region = mDisplay->createRegion(opaqueArea); + struct ::wl_region *region = mDisplay->createRegion(translatedOpaqueArea); mSurface->set_opaque_region(region); wl_region_destroy(region); } -- 2.25.1 ++++++ 0011-Client-Send-exposeEvent-to-parent-on-subsurface-posi.patch ++++++ >From 2073ff99e62d4f99ed3f1f45559c5b68a61c5f66 Mon Sep 17 00:00:00 2001 From: David Edmundson <davidedmund...@kde.org> Date: Mon, 14 Sep 2020 17:08:39 +0100 Subject: [PATCH 11/18] Client: Send exposeEvent to parent on subsurface position changes When a subsurface is moved, we need the parent window to commit to apply that move. Ideally we want this in sync with any potential rendering on the parent window. Currently the code calls requestUpdate() which acts more like a frame callback; it will only do something if the main QWindow considers itself dirty. We want to force a repaint, which is semantically more similar to an ExposeEvent. Fixes: QTBUG-86177 Pick-to: 5.15 Change-Id: I30bdfa357beee860ce2b00a256eaea6d040dd55c Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfe...@qt.io> --- src/client/qwaylandwindow.cpp | 7 ++++- tests/auto/client/surface/tst_surface.cpp | 33 +++++++++++++++++++---- 2 files changed, 34 insertions(+), 6 deletions(-) diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp index 2af39977..e96d8fe9 100644 --- a/src/client/qwaylandwindow.cpp +++ b/src/client/qwaylandwindow.cpp @@ -342,7 +342,12 @@ void QWaylandWindow::setGeometry_helper(const QRect &rect) if (mSubSurfaceWindow) { QMargins m = QPlatformWindow::parent()->frameMargins(); mSubSurfaceWindow->set_position(rect.x() + m.left(), rect.y() + m.top()); - mSubSurfaceWindow->parent()->window()->requestUpdate(); + + QWaylandWindow *parentWindow = mSubSurfaceWindow->parent(); + if (parentWindow && parentWindow->isExposed()) { + QRect parentExposeGeometry(QPoint(), parentWindow->geometry().size()); + parentWindow->sendExposeEvent(parentExposeGeometry); + } } } diff --git a/tests/auto/client/surface/tst_surface.cpp b/tests/auto/client/surface/tst_surface.cpp index b8a65f15..95e4e609 100644 --- a/tests/auto/client/surface/tst_surface.cpp +++ b/tests/auto/client/surface/tst_surface.cpp @@ -167,17 +167,40 @@ void tst_surface::negotiateShmFormat() void tst_surface::createSubsurface() { QRasterWindow window; - window.resize(64, 64); - window.show(); - QCOMPOSITOR_TRY_VERIFY(xdgToplevel()); - exec([=] { xdgToplevel()->sendCompleteConfigure(); }); - QCOMPOSITOR_TRY_VERIFY(xdgSurface()->m_committedConfigureSerial); + window.setObjectName("main"); + window.resize(200, 200); QRasterWindow subWindow; + subWindow.setObjectName("subwindow"); subWindow.setParent(&window); subWindow.resize(64, 64); + + window.show(); subWindow.show(); + QCOMPOSITOR_TRY_VERIFY(subSurface()); + QCOMPOSITOR_TRY_VERIFY(xdgToplevel()); + exec([=] { xdgToplevel()->sendCompleteConfigure(); }); + QCOMPOSITOR_TRY_VERIFY(xdgSurface()->m_committedConfigureSerial); + + const Surface *mainSurface = exec([=] {return surface(0);}); + const Surface *childSurface = exec([=] {return surface(1);}); + QSignalSpy mainSurfaceCommitSpy(mainSurface, &Surface::commit); + QSignalSpy childSurfaceCommitSpy(childSurface, &Surface::commit); + + // Move subsurface. The parent should redraw and commit + subWindow.setGeometry(100, 100, 64, 64); + // the toplevel should commit to indicate the subsurface moved + QCOMPOSITOR_TRY_COMPARE(mainSurfaceCommitSpy.count(), 1); + mainSurfaceCommitSpy.clear(); + childSurfaceCommitSpy.clear(); + + // Move and resize the subSurface. The parent should redraw and commit + // The child should also redraw + subWindow.setGeometry(50, 50, 80, 80); + QCOMPOSITOR_TRY_COMPARE(mainSurfaceCommitSpy.count(), 1); + QCOMPOSITOR_TRY_COMPARE(childSurfaceCommitSpy.count(), 1); + } // Used to cause a crash in libwayland (QTBUG-79674) -- 2.25.1 ++++++ 0012-Get-correct-decoration-margins-region.patch ++++++ >From 6810b0f66a34056bfe0da7299d7a768e700e58f5 Mon Sep 17 00:00:00 2001 From: Jan Grulich <jgrul...@redhat.com> Date: Thu, 11 Feb 2021 15:12:32 +0100 Subject: [PATCH 12/18] Get correct decoration margins region Size we use to calculate margins region already contains size including margins. This resulted into bigger region and not properly damaging region we need to update. Pick-to: 5.15 6.0 6.1 Change-Id: Id1b7f4cd2a7b894b82db09c5af2b2d1f1f43fa2a Reviewed-by: David Edmundson <davidedmund...@kde.org> --- src/client/qwaylandabstractdecoration.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/client/qwaylandabstractdecoration.cpp b/src/client/qwaylandabstractdecoration.cpp index 87dd6cea..b6ee43c9 100644 --- a/src/client/qwaylandabstractdecoration.cpp +++ b/src/client/qwaylandabstractdecoration.cpp @@ -108,11 +108,11 @@ void QWaylandAbstractDecoration::setWaylandWindow(QWaylandWindow *window) static QRegion marginsRegion(const QSize &size, const QMargins &margins) { QRegion r; - const int widthWithMargins = margins.left() + size.width() + margins.right(); - r += QRect(0, 0, widthWithMargins, margins.top()); // top - r += QRect(0, size.height()+margins.top(), widthWithMargins, margins.bottom()); //bottom + + r += QRect(0, 0, size.width(), margins.top()); // top + r += QRect(0, size.height()-margins.bottom(), size.width(), margins.bottom()); //bottom r += QRect(0, margins.top(), margins.left(), size.height()); //left - r += QRect(size.width()+margins.left(), margins.top(), margins.right(), size.height()); // right + r += QRect(size.width()-margins.left(), margins.top(), margins.right(), size.height()-margins.top()); // right return r; } -- 2.25.1 ++++++ 0013-xdgshell-Tell-the-compositor-the-screen-we-re-expect.patch ++++++ >From cea69b8adec1e61adc1fa04cbf46b77c0d72c75e Mon Sep 17 00:00:00 2001 From: Aleix Pol <aleix...@kde.org> Date: Mon, 23 Nov 2020 20:07:02 +0100 Subject: [PATCH 13/18] xdgshell: Tell the compositor the screen we're expecting to fill The xdgshell protocol allows us to tell the output to fill. This makes it possible to use fullscreen confidently on systems with multiple screens knowing that our windows won't be overlapping one another by calling setScreen accordingly before QWindow::showFullScreen. Pick-to: 6.1 6.0 5.15 Change-Id: I757854c3698639472f3a25ef298ddcca031e1ed5 Reviewed-by: David Edmundson <davidedmund...@kde.org> --- .../shellintegration/xdg-shell/qwaylandxdgshell.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp index 1c762944..3a1569f7 100644 --- a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp +++ b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp @@ -178,9 +178,12 @@ void QWaylandXdgSurface::Toplevel::requestWindowStates(Qt::WindowStates states) } if (changedStates & Qt::WindowFullScreen) { - if (states & Qt::WindowFullScreen) - set_fullscreen(nullptr); - else + if (states & Qt::WindowFullScreen) { + auto screen = m_xdgSurface->window()->waylandScreen(); + if (screen) { + set_fullscreen(screen->output()); + } + } else unset_fullscreen(); } -- 2.25.1 ++++++ 0014-Fix-compilation.patch ++++++ >From 2f84a874da064069461284db1da36dc818949ec1 Mon Sep 17 00:00:00 2001 From: Albert Astals Cid <aa...@kde.org> Date: Sat, 10 Apr 2021 12:10:16 +0200 Subject: [PATCH 14/18] Fix compilation 9df11e79b46c77d8c83f765b2a8e85b639fd55a2 can't be backported 1:1 --- .../client/wayland-egl/qwaylandglcontext.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp b/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp index befadedc..95d1049c 100644 --- a/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp +++ b/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp @@ -408,7 +408,7 @@ QWaylandGLContext::~QWaylandGLContext() delete m_blitter; m_blitter = nullptr; if (m_decorationsContext != EGL_NO_CONTEXT) - eglDestroyContext(eglDisplay(), m_decorationsContext); + eglDestroyContext(m_eglDisplay, m_decorationsContext); } bool QWaylandGLContext::makeCurrent(QPlatformSurface *surface) -- 2.25.1 ++++++ 0015-client-Allow-QWaylandInputContext-to-accept-composed.patch ++++++ >From 91c48320633e493b4cd519e5d73b836a878b2b77 Mon Sep 17 00:00:00 2001 From: Aleix Pol <aleix...@kde.org> Date: Wed, 10 Mar 2021 01:09:13 +0100 Subject: [PATCH 15/18] client: Allow QWaylandInputContext to accept composed key combinations At the moment, we are forcing user to choose to either compose or use the text-input channel. This patch brings some of the QComposeInputContext functionality in order to let applications understand dead key combinations like they are supposed to. Having it in QWaylandInputContext rather than in QWaylandInputDevice should solve the problems 3aedd01271dc4f4a13103d632df224971ab2b6df had with 57c4af2b18c0fb1d266b245a107fa6cb876b9d9e, because we are doing it in the input context rather than before. This way, if the user is overriding the input method (e.g. by setting QT_IM_MODULE), all the key strokes will still be properly forwarded to the module to use. This in turn allows us to solve https://bugs.kde.org/show_bug.cgi?id=411729 and https://bugs.kde.org/show_bug.cgi?id=405388 since we don't need to choose anymore between physical and virual keyboards anymore. Pick-to: 5.15 Change-Id: I8601f5d7ae21edf4b3a1191fa75877286e505588 Reviewed-by: David Edmundson <davidedmund...@kde.org> --- src/client/qwaylanddisplay_p.h | 3 - src/client/qwaylandinputcontext.cpp | 95 ++++++++++++++++++++++++++++- src/client/qwaylandinputcontext_p.h | 21 +++++++ src/client/qwaylandinputdevice.cpp | 2 +- src/client/qwaylandintegration.cpp | 8 +-- 5 files changed, 119 insertions(+), 10 deletions(-) diff --git a/src/client/qwaylanddisplay_p.h b/src/client/qwaylanddisplay_p.h index 188e9131..3b092bc8 100644 --- a/src/client/qwaylanddisplay_p.h +++ b/src/client/qwaylanddisplay_p.h @@ -175,8 +175,6 @@ public: QWaylandHardwareIntegration *hardwareIntegration() const { return mHardwareIntegration.data(); } QWaylandXdgOutputManagerV1 *xdgOutputManager() const { return mXdgOutputManager.data(); } - bool usingInputContextFromCompositor() const { return mUsingInputContextFromCompositor; } - struct RegistryGlobal { uint32_t id; QString interface; @@ -282,7 +280,6 @@ private: QReadWriteLock m_frameQueueLock; bool mClientSideInputContextRequested = !QPlatformInputContextFactory::requested().isNull(); - bool mUsingInputContextFromCompositor = false; void registry_global(uint32_t id, const QString &interface, uint32_t version) override; void registry_global_remove(uint32_t id) override; diff --git a/src/client/qwaylandinputcontext.cpp b/src/client/qwaylandinputcontext.cpp index e9afe05e..ef5aa375 100644 --- a/src/client/qwaylandinputcontext.cpp +++ b/src/client/qwaylandinputcontext.cpp @@ -406,6 +406,8 @@ bool QWaylandInputContext::isValid() const void QWaylandInputContext::reset() { qCDebug(qLcQpaInputMethods) << Q_FUNC_INFO; + if (m_composeState) + xkb_compose_state_reset(m_composeState); QPlatformInputContext::reset(); @@ -526,9 +528,14 @@ Qt::LayoutDirection QWaylandInputContext::inputDirection() const return textInput()->inputDirection(); } -void QWaylandInputContext::setFocusObject(QObject *) +void QWaylandInputContext::setFocusObject(QObject *object) { qCDebug(qLcQpaInputMethods) << Q_FUNC_INFO; +#if QT_CONFIG(xkbcommon) + m_focusObject = object; +#else + Q_UNUSED(object); +#endif if (!textInput()) return; @@ -561,6 +568,92 @@ QWaylandTextInput *QWaylandInputContext::textInput() const return mDisplay->defaultInputDevice()->textInput(); } +#if QT_CONFIG(xkbcommon) + +void QWaylandInputContext::ensureInitialized() +{ + if (m_initialized) + return; + + if (!m_XkbContext) { + qCWarning(qLcQpaInputMethods) << "error: xkb context has not been set on" << metaObject()->className(); + return; + } + + m_initialized = true; + const char *locale = setlocale(LC_CTYPE, ""); + if (!locale) + locale = setlocale(LC_CTYPE, nullptr); + qCDebug(qLcQpaInputMethods) << "detected locale (LC_CTYPE):" << locale; + + m_composeTable = xkb_compose_table_new_from_locale(m_XkbContext, locale, XKB_COMPOSE_COMPILE_NO_FLAGS); + if (m_composeTable) + m_composeState = xkb_compose_state_new(m_composeTable, XKB_COMPOSE_STATE_NO_FLAGS); + + if (!m_composeTable) { + qCWarning(qLcQpaInputMethods, "failed to create compose table"); + return; + } + if (!m_composeState) { + qCWarning(qLcQpaInputMethods, "failed to create compose state"); + return; + } +} + +bool QWaylandInputContext::filterEvent(const QEvent *event) +{ + auto keyEvent = static_cast<const QKeyEvent *>(event); + if (keyEvent->type() != QEvent::KeyPress) + return false; + + if (!inputMethodAccepted()) + return false; + + // lazy initialization - we don't want to do this on an app startup + ensureInitialized(); + + if (!m_composeTable || !m_composeState) + return false; + + xkb_compose_state_feed(m_composeState, keyEvent->nativeVirtualKey()); + + switch (xkb_compose_state_get_status(m_composeState)) { + case XKB_COMPOSE_COMPOSING: + return true; + case XKB_COMPOSE_CANCELLED: + reset(); + return false; + case XKB_COMPOSE_COMPOSED: + { + const int size = xkb_compose_state_get_utf8(m_composeState, nullptr, 0); + QVarLengthArray<char, 32> buffer(size + 1); + xkb_compose_state_get_utf8(m_composeState, buffer.data(), buffer.size()); + QString composedText = QString::fromUtf8(buffer.constData()); + + QInputMethodEvent event; + event.setCommitString(composedText); + + if (!m_focusObject && qApp) + m_focusObject = qApp->focusObject(); + + if (m_focusObject) + QCoreApplication::sendEvent(m_focusObject, &event); + else + qCWarning(qLcQpaInputMethods, "no focus object"); + + reset(); + return true; + } + case XKB_COMPOSE_NOTHING: + return false; + default: + Q_UNREACHABLE(); + return false; + } +} + +#endif + } QT_END_NAMESPACE diff --git a/src/client/qwaylandinputcontext_p.h b/src/client/qwaylandinputcontext_p.h index 10132dfe..50db6344 100644 --- a/src/client/qwaylandinputcontext_p.h +++ b/src/client/qwaylandinputcontext_p.h @@ -61,6 +61,10 @@ #include <QtWaylandClient/private/qwayland-text-input-unstable-v2.h> #include <qwaylandinputmethodeventbuilder_p.h> +#include <qtwaylandclientglobal_p.h> +#if QT_CONFIG(xkbcommon) +#include <xkbcommon/xkbcommon-compose.h> +#endif struct wl_callback; struct wl_callback_listener; @@ -155,11 +159,28 @@ public: void setFocusObject(QObject *object) override; +#if QT_CONFIG(xkbcommon) + bool filterEvent(const QEvent *event) override; + + // This invokable is called from QXkbCommon::setXkbContext(). + Q_INVOKABLE void setXkbContext(struct xkb_context *context) { m_XkbContext = context; } +#endif + private: QWaylandTextInput *textInput() const; QWaylandDisplay *mDisplay = nullptr; QPointer<QWindow> mCurrentWindow; + +#if QT_CONFIG(xkbcommon) + void ensureInitialized(); + + bool m_initialized = false; + QObject *m_focusObject = nullptr; + xkb_compose_table *m_composeTable = nullptr; + xkb_compose_state *m_composeState = nullptr; + struct xkb_context *m_XkbContext = nullptr; +#endif }; } diff --git a/src/client/qwaylandinputdevice.cpp b/src/client/qwaylandinputdevice.cpp index ed4a0eb4..ae045f4f 100644 --- a/src/client/qwaylandinputdevice.cpp +++ b/src/client/qwaylandinputdevice.cpp @@ -1201,7 +1201,7 @@ void QWaylandInputDevice::Keyboard::handleKey(ulong timestamp, QEvent::Type type QPlatformInputContext *inputContext = QGuiApplicationPrivate::platformIntegration()->inputContext(); bool filtered = false; - if (inputContext && !mParent->mQDisplay->usingInputContextFromCompositor()) { + if (inputContext) { QKeyEvent event(type, key, modifiers, nativeScanCode, nativeVirtualKey, nativeModifiers, text, autorepeat, count); event.setTimestamp(timestamp); diff --git a/src/client/qwaylandintegration.cpp b/src/client/qwaylandintegration.cpp index 7ad8e05e..c53ccb78 100644 --- a/src/client/qwaylandintegration.cpp +++ b/src/client/qwaylandintegration.cpp @@ -474,13 +474,11 @@ void QWaylandIntegration::reconfigureInputContext() #if QT_CONFIG(xkbcommon) QXkbCommon::setXkbContext(mInputContext.data(), mDisplay->xkbContext()); + if (QWaylandInputContext* waylandInput = qobject_cast<QWaylandInputContext*>(mInputContext.get())) { + waylandInput->setXkbContext(mDisplay->xkbContext()); + } #endif - // Even if compositor-side input context handling has been requested, we fallback to - // client-side handling if compositor does not provide the text-input extension. This - // is why we need to check here which input context actually is being used. - mDisplay->mUsingInputContextFromCompositor = qobject_cast<QWaylandInputContext *>(mInputContext.data()); - qCDebug(lcQpaWayland) << "using input method:" << inputContext()->metaObject()->className(); } -- 2.25.1 ++++++ 0016-Client-Announce-an-output-after-receiving-more-compl.patch ++++++ >From d5186701e27ad6f09f3944809cec2a25c5328026 Mon Sep 17 00:00:00 2001 From: Vlad Zahorodnii <vlad.zahorod...@kde.org> Date: Wed, 5 May 2021 20:49:26 +0300 Subject: [PATCH 16/18] Client: Announce an output after receiving more complete state Output initialization is not atomic, meaning that the compositor may process a wl_output bind request in one event loop cycle, and the xdg_output_manager.get_xdg_output in another event loop cycle. This means that xdg_output properties may arrive in another wl_output done frame. Prior to xdg-output v3, that wasn't an issue because the compositor is required to send an xdg_output.done event after sending xdg_output properties. Starting with v3, the compositor may choose not to send an xdg_output.done event after sending xdg_output properties. Therefore, as is, QtWayland may announce an output with bad logical geometry or even worse without name assigned by the compositor. Unfortunately, that breaks applications such as plasmashell. Plasma uses output names as a criterion to determine what kind of contents should be displayed on a particular output. In order to fix the initialization sequence, this change makes every QWaylandScreen track processed events. After all required events have been received, the screen can be announced to the rest of Qt. Change-Id: If5da747edd7af277ec1364cbea105c6994f47402 Reviewed-by: David Edmundson <davidedmund...@kde.org> (cherry picked from commit 69ea480f2e53ad4a5bbca78cde044eb8d4c48896) Original Ticket: https://codereview.qt-project.org/c/qt/qtwayland/+/347774 CCBUG: 435124 --- src/client/qwaylandscreen.cpp | 32 +++++++++++++++++++++++--------- src/client/qwaylandscreen_p.h | 10 ++++++++-- 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/src/client/qwaylandscreen.cpp b/src/client/qwaylandscreen.cpp index 6cb337de..7c2d9be3 100644 --- a/src/client/qwaylandscreen.cpp +++ b/src/client/qwaylandscreen.cpp @@ -72,7 +72,7 @@ QWaylandScreen::QWaylandScreen(QWaylandDisplay *waylandDisplay, int version, uin qCWarning(lcQpaWayland) << "wl_output done event not supported by compositor," << "QScreen may not work correctly"; mWaylandDisplay->forceRoundTrip(); // Give the compositor a chance to send geometry etc. - mOutputDone = true; // Fake the done event + mProcessedEvents |= OutputDoneEvent; // Fake the done event maybeInitialize(); } } @@ -83,14 +83,25 @@ QWaylandScreen::~QWaylandScreen() zxdg_output_v1::destroy(); } +uint QWaylandScreen::requiredEvents() const +{ + uint ret = OutputDoneEvent; + + if (mWaylandDisplay->xdgOutputManager()) { + ret |= XdgOutputNameEvent; + + if (mWaylandDisplay->xdgOutputManager()->version() < 3) + ret |= XdgOutputDoneEvent; + } + return ret; +} + void QWaylandScreen::maybeInitialize() { Q_ASSERT(!mInitialized); - if (!mOutputDone) - return; - - if (mWaylandDisplay->xdgOutputManager() && !mXdgOutputDone) + const uint requiredEvents = this->requiredEvents(); + if ((mProcessedEvents & requiredEvents) != requiredEvents) return; mInitialized = true; @@ -276,9 +287,8 @@ void QWaylandScreen::output_scale(int32_t factor) void QWaylandScreen::output_done() { - mOutputDone = true; - if (zxdg_output_v1::isInitialized() && mWaylandDisplay->xdgOutputManager()->version() >= 3) - mXdgOutputDone = true; + mProcessedEvents |= OutputDoneEvent; + if (mInitialized) { updateOutputProperties(); if (zxdg_output_v1::isInitialized()) @@ -339,7 +349,7 @@ void QWaylandScreen::zxdg_output_v1_done() if (Q_UNLIKELY(mWaylandDisplay->xdgOutputManager()->version() >= 3)) qWarning(lcQpaWayland) << "zxdg_output_v1.done received on version 3 or newer, this is most likely a bug in the compositor"; - mXdgOutputDone = true; + mProcessedEvents |= XdgOutputDoneEvent; if (mInitialized) updateXdgOutputProperties(); else @@ -348,7 +358,11 @@ void QWaylandScreen::zxdg_output_v1_done() void QWaylandScreen::zxdg_output_v1_name(const QString &name) { + if (Q_UNLIKELY(mInitialized)) + qWarning(lcQpaWayland) << "zxdg_output_v1.name received after output has been initialized, this is most likely a bug in the compositor"; + mOutputName = name; + mProcessedEvents |= XdgOutputNameEvent; } void QWaylandScreen::updateXdgOutputProperties() diff --git a/src/client/qwaylandscreen_p.h b/src/client/qwaylandscreen_p.h index df1c94f2..050cfdc0 100644 --- a/src/client/qwaylandscreen_p.h +++ b/src/client/qwaylandscreen_p.h @@ -116,6 +116,13 @@ public: static QWaylandScreen *fromWlOutput(::wl_output *output); private: + enum Event : uint { + XdgOutputDoneEvent = 0x1, + OutputDoneEvent = 0x2, + XdgOutputNameEvent = 0x4, + }; + uint requiredEvents() const; + void output_mode(uint32_t flags, int width, int height, int refresh) override; void output_geometry(int32_t x, int32_t y, int32_t width, int32_t height, @@ -148,8 +155,7 @@ private: QSize mPhysicalSize; QString mOutputName; Qt::ScreenOrientation m_orientation = Qt::PrimaryOrientation; - bool mOutputDone = false; - bool mXdgOutputDone = false; + uint mProcessedEvents = 0; bool mInitialized = false; #if QT_CONFIG(cursor) -- 2.25.1 ++++++ 0017-Fix-issue-with-repeated-window-size-changes.patch ++++++ >From 62494312db0f58053d1342bfacc7984186fdf3a6 Mon Sep 17 00:00:00 2001 From: Jaeyoon Jung <jaeyoon.j...@lge.com> Date: Mon, 15 Feb 2021 08:31:06 +0900 Subject: [PATCH 17/18] Fix issue with repeated window size changes Check if the new window size is different from the size requested previously before calling wl_egl_window_resize. It addresses the issue where repeated setGeometry calls between two sizes might not work as expected. The problem occurs when wl_egl_window_get_attached_size does not get the same size that was requested by the previous setGeometry call. If the returned size happened to match the new size instead, we would mistakenly skip the resize. Change-Id: Iafe4a91cc707f854b9099b6109b6be1423d7bd29 Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfe...@qt.io> (cherry picked from commit 14d066c61025e548227ccd8d655e80ffa31fa15e) --- .../client/wayland-egl/qwaylandeglwindow.cpp | 4 +++- .../client/wayland-egl/qwaylandeglwindow.h | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp b/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp index 7889f575..201b583b 100644 --- a/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp +++ b/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp @@ -131,14 +131,16 @@ void QWaylandEglWindow::updateSurface(bool create) if (!disableResizeCheck) { wl_egl_window_get_attached_size(m_waylandEglWindow, ¤t_width, ¤t_height); } - if (disableResizeCheck || (current_width != sizeWithMargins.width() || current_height != sizeWithMargins.height())) { + if (disableResizeCheck || (current_width != sizeWithMargins.width() || current_height != sizeWithMargins.height()) || m_requestedSize != sizeWithMargins) { wl_egl_window_resize(m_waylandEglWindow, sizeWithMargins.width(), sizeWithMargins.height(), mOffset.x(), mOffset.y()); + m_requestedSize = sizeWithMargins; mOffset = QPoint(); m_resize = true; } } else if (create && wlSurface()) { m_waylandEglWindow = wl_egl_window_create(wlSurface(), sizeWithMargins.width(), sizeWithMargins.height()); + m_requestedSize = sizeWithMargins; } if (!m_eglSurface && m_waylandEglWindow && create) { diff --git a/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.h b/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.h index 5b1f4d56..0079dfef 100644 --- a/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.h +++ b/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.h @@ -88,6 +88,7 @@ private: mutable QOpenGLFramebufferObject *m_contentFBO = nullptr; QSurfaceFormat m_format; + QSize m_requestedSize; }; } -- 2.25.1 ++++++ 0018-Include-locale.h-for-setlocale-LC_CTYPE.patch ++++++ >From 1ccebbab3a42690a0812e2c4c76016799bf6cf1f Mon Sep 17 00:00:00 2001 From: Albert Astals Cid <albert.astals....@kdab.com> Date: Mon, 10 May 2021 14:38:49 +0200 Subject: [PATCH 18/18] Include locale.h for setlocale/LC_CTYPE Pick-to: 5.15 Change-Id: Iced32a31a63cec71008549c1e0961d59ffc45a37 Reviewed-by: Aleix Pol Gonzalez <aleix...@kde.org> (cherry picked from commit e9522eda46028f351d87311d898ab985856970b0) --- src/client/qwaylandinputcontext.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/client/qwaylandinputcontext.cpp b/src/client/qwaylandinputcontext.cpp index ef5aa375..503fd735 100644 --- a/src/client/qwaylandinputcontext.cpp +++ b/src/client/qwaylandinputcontext.cpp @@ -51,6 +51,10 @@ #include "qwaylandinputmethodeventbuilder_p.h" #include "qwaylandwindow_p.h" +#if QT_CONFIG(xkbcommon) +#include <locale.h> +#endif + QT_BEGIN_NAMESPACE Q_LOGGING_CATEGORY(qLcQpaInputMethods, "qt.qpa.input.methods") -- 2.25.1