diff --git a/.gitignore b/.gitignore index c8d5de0..e19f73c 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/qtwayland-everywhere-src-5.11.1.tar.xz +SOURCES/qtwayland-everywhere-src-5.12.5.tar.xz diff --git a/.qt5-qtwayland.metadata b/.qt5-qtwayland.metadata index c0606e5..a97d8d2 100644 --- a/.qt5-qtwayland.metadata +++ b/.qt5-qtwayland.metadata @@ -1 +1 @@ -1c6a9ee1b8bf8d854703725708d62d53ed73e39f SOURCES/qtwayland-everywhere-src-5.11.1.tar.xz +73ba627ea857598e733721a5a74ef1ff01e88d0b SOURCES/qtwayland-everywhere-src-5.12.5.tar.xz diff --git a/SOURCES/qtwayland-do-not-redraw-decorations-everytime.patch b/SOURCES/qtwayland-do-not-redraw-decorations-everytime.patch new file mode 100644 index 0000000..b5a684e --- /dev/null +++ b/SOURCES/qtwayland-do-not-redraw-decorations-everytime.patch @@ -0,0 +1,33 @@ +diff --git a/src/client/qwaylandshmbackingstore.cpp b/src/client/qwaylandshmbackingstore.cpp +index 3fe2ce80..6d660e64 100644 +--- a/src/client/qwaylandshmbackingstore.cpp ++++ b/src/client/qwaylandshmbackingstore.cpp +@@ -289,11 +289,13 @@ void QWaylandShmBackingStore::resize(const QSize &size) + buffer = getBuffer(sizeWithMargins); + } + +- qsizetype oldSize = mBackBuffer ? mBackBuffer->image()->sizeInBytes() : 0; ++ qsizetype oldSizeInBytes = mBackBuffer ? mBackBuffer->image()->sizeInBytes() : 0; ++ qsizetype newSizeInBytes = buffer->image()->sizeInBytes(); ++ + // mBackBuffer may have been deleted here but if so it means its size was different so we wouldn't copy it anyway +- if (mBackBuffer != buffer && oldSize == buffer->image()->sizeInBytes()) { +- memcpy(buffer->image()->bits(), mBackBuffer->image()->constBits(), buffer->image()->sizeInBytes()); +- } ++ if (mBackBuffer != buffer && oldSizeInBytes == newSizeInBytes) ++ memcpy(buffer->image()->bits(), mBackBuffer->image()->constBits(), newSizeInBytes); ++ + mBackBuffer = buffer; + // ensure the new buffer is at the beginning of the list so next time getBuffer() will pick + // it if possible +@@ -302,8 +304,9 @@ void QWaylandShmBackingStore::resize(const QSize &size) + mBuffers.prepend(buffer); + } + +- if (windowDecoration() && window()->isVisible()) ++ if (windowDecoration() && window()->isVisible() && oldSizeInBytes != newSizeInBytes) { + windowDecoration()->update(); ++ } + } + + QImage *QWaylandShmBackingStore::entireSurface() const diff --git a/SOURCES/qtwayland-fix-100ms-freeze-when-apps-dont-swap-after-deliverupdaterequest.patch b/SOURCES/qtwayland-fix-100ms-freeze-when-apps-dont-swap-after-deliverupdaterequest.patch new file mode 100644 index 0000000..ff4040f --- /dev/null +++ b/SOURCES/qtwayland-fix-100ms-freeze-when-apps-dont-swap-after-deliverupdaterequest.patch @@ -0,0 +1,127 @@ +From 9f5b96225885f927727a57b6123d8550d6c373bb Mon Sep 17 00:00:00 2001 +From: Johan Klokkhammer Helsing +Date: Tue, 15 Oct 2019 09:51:43 +0200 +Subject: [PATCH] Client: Fix 100ms freeze when applications do not swap after deliverUpdateRequest + +[ChangeLog][QPA plugin] Fixed a 100 ms freeze that would occur if applications +did not draw after receiving a deliverUpdateRequest(). + +QtQuick does this at the start of animations. This should get rid of those +backingstore warnings (and also remove a 100ms freeze before animations start +in those instances). + +Fixes: QTBUG-76813 +Change-Id: Id366bf4a14f402fa44530ae46e7b66d9988c14f6 +Reviewed-by: Paul Olav Tvete +Reviewed-by: John Brooks +--- + +diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp +index ae26ba0..8d34afd 100644 +--- a/src/client/qwaylandwindow.cpp ++++ b/src/client/qwaylandwindow.cpp +@@ -1105,25 +1105,6 @@ + + void QWaylandWindow::timerEvent(QTimerEvent *event) + { +- if (event->timerId() == mFallbackUpdateTimerId) { +- killTimer(mFallbackUpdateTimerId); +- mFallbackUpdateTimerId = -1; +- qCDebug(lcWaylandBackingstore) << "mFallbackUpdateTimer timed out"; +- +- if (!isExposed()) { +- qCDebug(lcWaylandBackingstore) << "Fallback update timer: Window not exposed," +- << "not delivering update request."; +- return; +- } +- +- if (mWaitingForUpdate && hasPendingUpdateRequest() && !mWaitingForFrameCallback) { +- qCWarning(lcWaylandBackingstore) << "Delivering update request through fallback timer," +- << "may not be in sync with display"; +- deliverUpdateRequest(); +- } +- } +- +- + if (mFrameCallbackTimerId.testAndSetOrdered(event->timerId(), -1)) { + killTimer(event->timerId()); + qCDebug(lcWaylandBackingstore) << "Didn't receive frame callback in time, window should now be inexposed"; +@@ -1135,6 +1116,7 @@ + + void QWaylandWindow::requestUpdate() + { ++ qCDebug(lcWaylandBackingstore) << "requestUpdate"; + Q_ASSERT(hasPendingUpdateRequest()); // should be set by QPA + + // If we have a frame callback all is good and will be taken care of there +@@ -1142,20 +1124,17 @@ + return; + + // If we've already called deliverUpdateRequest(), but haven't seen any attach+commit/swap yet +- if (mWaitingForUpdate) { +- // Ideally, we should just have returned here, but we're not guaranteed that the client +- // will actually update, so start this timer to deliver another request update after a while +- // *IF* the client doesn't update. +- int fallbackTimeout = 100; +- mFallbackUpdateTimerId = startTimer(fallbackTimeout); +- return; +- } ++ // This is a somewhat redundant behavior and might indicate a bug in the calling code, so log ++ // here so we can get this information when debugging update/frame callback issues. ++ // Continue as nothing happened, though. ++ if (mWaitingForUpdate) ++ qCDebug(lcWaylandBackingstore) << "requestUpdate called twice without committing anything"; + + // Some applications (such as Qt Quick) depend on updates being delivered asynchronously, + // so use invokeMethod to delay the delivery a bit. + QMetaObject::invokeMethod(this, [this] { + // Things might have changed in the meantime +- if (hasPendingUpdateRequest() && !mWaitingForUpdate && !mWaitingForFrameCallback) ++ if (hasPendingUpdateRequest() && !mWaitingForFrameCallback) + deliverUpdateRequest(); + }, Qt::QueuedConnection); + } +@@ -1165,6 +1144,7 @@ + // Can be called from the render thread (without locking anything) so make sure to not make races in this method. + void QWaylandWindow::handleUpdate() + { ++ qCDebug(lcWaylandBackingstore) << "handleUpdate" << QThread::currentThread(); + // TODO: Should sync subsurfaces avoid requesting frame callbacks? + QReadLocker lock(&mSurfaceLock); + if (!isInitialized()) +@@ -1175,15 +1155,6 @@ + mFrameCallback = nullptr; + } + +- if (mFallbackUpdateTimerId != -1) { +- // Ideally, we would stop the fallback timer here, but since we're on another thread, +- // it's not allowed. Instead we set mFallbackUpdateTimer to -1 here, so we'll just +- // ignore it if it times out before it's cleaned up by the invokeMethod call. +- int id = mFallbackUpdateTimerId; +- mFallbackUpdateTimerId = -1; +- QMetaObject::invokeMethod(this, [this, id] { killTimer(id); }, Qt::QueuedConnection); +- } +- + mFrameCallback = frame(); + wl_callback_add_listener(mFrameCallback, &QWaylandWindow::callbackListener, this); + mWaitingForFrameCallback = true; +@@ -1203,6 +1174,7 @@ + + void QWaylandWindow::deliverUpdateRequest() + { ++ qCDebug(lcWaylandBackingstore) << "deliverUpdateRequest"; + mWaitingForUpdate = true; + QPlatformWindow::deliverUpdateRequest(); + } +diff --git a/src/client/qwaylandwindow_p.h b/src/client/qwaylandwindow_p.h +index b03d92e..e4a1124 100644 +--- a/src/client/qwaylandwindow_p.h ++++ b/src/client/qwaylandwindow_p.h +@@ -232,7 +232,6 @@ + + // True when we have called deliverRequestUpdate, but the client has not yet attached a new buffer + bool mWaitingForUpdate = false; +- int mFallbackUpdateTimerId = -1; // Started when waiting for app to commit + + QMutex mResizeLock; + bool mWaitingToApplyConfigure = false; diff --git a/SOURCES/qtwayland-use-gnome-platform-theme-on-gnome-based-desktops.patch b/SOURCES/qtwayland-use-gnome-platform-theme-on-gnome-based-desktops.patch new file mode 100644 index 0000000..d4463bf --- /dev/null +++ b/SOURCES/qtwayland-use-gnome-platform-theme-on-gnome-based-desktops.patch @@ -0,0 +1,39 @@ +diff --git a/src/client/qwaylandintegration.cpp b/src/client/qwaylandintegration.cpp +index 97e0203c..5bee160a 100644 +--- a/src/client/qwaylandintegration.cpp ++++ b/src/client/qwaylandintegration.cpp +@@ -99,20 +99,26 @@ public: + + if (QGuiApplication::desktopSettingsAware()) { + const QByteArray desktopEnvironment = QGuiApplicationPrivate::platformIntegration()->services()->desktopEnvironment(); +- ++ QList gtkBasedEnvironments; ++ gtkBasedEnvironments << "GNOME" ++ << "X-CINNAMON" ++ << "UNITY" ++ << "MATE" ++ << "XFCE" ++ << "LXDE"; + if (desktopEnvironment == QByteArrayLiteral("KDE")) { + #if QT_CONFIG(settings) + result.push_back(QStringLiteral("kde")); + #endif +- } else if (!desktopEnvironment.isEmpty() && +- desktopEnvironment != QByteArrayLiteral("UNKNOWN") && +- desktopEnvironment != QByteArrayLiteral("GNOME") && +- desktopEnvironment != QByteArrayLiteral("UNITY") && +- desktopEnvironment != QByteArrayLiteral("MATE") && +- desktopEnvironment != QByteArrayLiteral("XFCE") && +- desktopEnvironment != QByteArrayLiteral("LXDE")) ++ } else if (gtkBasedEnvironments.contains(desktopEnvironment)) { ++ // prefer the GTK3 theme implementation with native dialogs etc. ++ result.push_back(QStringLiteral("gtk3")); ++ // fallback to the generic Gnome theme if loading the GTK3 theme fails ++ result.push_back(QLatin1String(QGnomeTheme::name)); ++ } else if (!desktopEnvironment.isEmpty() && desktopEnvironment != QByteArrayLiteral("UNKNOWN")) { + // Ignore X11 desktop environments + result.push_back(QString::fromLocal8Bit(desktopEnvironment.toLower())); ++ } + } + + if (result.isEmpty()) diff --git a/SPECS/qt5-qtwayland.spec b/SPECS/qt5-qtwayland.spec index 5ef7868..0844c94 100644 --- a/SPECS/qt5-qtwayland.spec +++ b/SPECS/qt5-qtwayland.spec @@ -1,23 +1,31 @@ %global qt_module qtwayland +%global build_tests 1 + Summary: Qt5 - Wayland platform support and QtCompositor module Name: qt5-%{qt_module} -Version: 5.11.1 -Release: 2%{?dist} +Version: 5.12.5 +Release: 1%{?dist} License: LGPLv3 Url: http://www.qt.io %global majmin %(echo %{version} | cut -d. -f1-2) Source0: https://download.qt.io/official_releases/qt/%{majmin}/%{version}/submodules/%{qt_module}-everywhere-src-%{version}.tar.xz -# Upstream patches +Patch0: qtwayland-do-not-redraw-decorations-everytime.patch +Patch1: qtwayland-fix-100ms-freeze-when-apps-dont-swap-after-deliverupdaterequest.patch + +# Upstreamable patches +# https://fedoraproject.org/wiki/Changes/Qt_Wayland_By_Default_On_Gnome +# https://bugzilla.redhat.com/show_bug.cgi?id=1732129 +Patch50: qtwayland-use-gnome-platform-theme-on-gnome-based-desktops.patch # filter qml provides %global __provides_exclude_from ^%{_qt5_archdatadir}/qml/.*\\.so$ BuildRequires: qt5-qtbase-devel >= %{version} BuildRequires: qt5-qtbase-static -BuildRequires: qt5-qtbase-private-devel +BuildRequires: qt5-qtbase-private-devel %{?_qt5:Requires: %{_qt5}%{?_isa} = %{_qt5_version}} BuildRequires: qt5-qtdeclarative-devel @@ -29,7 +37,6 @@ BuildRequires: pkgconfig(wayland-cursor) BuildRequires: pkgconfig(wayland-egl) BuildRequires: pkgconfig(egl) BuildRequires: pkgconfig(gl) -BuildRequires: pkgconfig(glesv2) BuildRequires: pkgconfig(xcomposite) BuildRequires: pkgconfig(xrender) BuildRequires: pkgconfig(libudev) @@ -51,6 +58,14 @@ Requires: %{name}%{?_isa} = %{version}-%{release} %description examples %{summary}. +%if 0%{?build_tests} +%package tests +Summary: Unit tests for %{name} +Requires: %{name}%{?_isa} = %{version}-%{release} + +%description tests +%{summary}. +%endif %prep %autosetup -n %{qt_module}-everywhere-src-%{version} -p1 @@ -60,10 +75,26 @@ Requires: %{name}%{?_isa} = %{version}-%{release} %make_build +%if 0%{?build_tests} +make sub-tests %{?_smp_mflags} -k ||: +%endif %install make install INSTALL_ROOT=%{buildroot} +%if 0%{?build_tests} +# Install tests for gating +mkdir -p %{buildroot}%{_qt5_libdir}/qt5 +find ./tests -not -path '*/\.*' -type d | while read LINE +do + mkdir -p "%{buildroot}%{_qt5_libdir}/qt5/$LINE" +done +find ./tests -not -path '*/\.*' -not -name '*.h' -not -name '*.cpp' -not -name '*.pro' -not -name 'uic_wrapper.sh' -not -name 'Makefile' -not -name 'target_wrapper.sh' -type f | while read LINE +do + cp -r --parents "$LINE" %{buildroot}%{_qt5_libdir}/qt5/ +done +%endif + ## .prl/.la file love # nuke .prl reference(s) to %%buildroot, excessive (.la-like) libs pushd %{buildroot}%{_qt5_libdir} @@ -112,8 +143,16 @@ popd %files examples %{_qt5_examplesdir}/wayland/ +%if 0%{?build_tests} +%files tests +%{_qt5_libdir}/qt5/tests +%endif %changelog +* Mon Nov 18 2019 Jan Grulich - 5.12.5-1 +- 5.12.5 + Resolves: bz#1733154 + * Mon Dec 10 2018 Jan Grulich - 5.11.1-2 - Rebuild to fix CET notes Resolves: bz#1657224