diff --git a/.gitignore b/.gitignore index 41a8a9f..5b3b45f 100644 --- a/.gitignore +++ b/.gitignore @@ -26,16 +26,3 @@ /qtbase-everywhere-src-6.6.0.tar.xz /qtbase-everywhere-src-6.6.1.tar.xz /qtbase-everywhere-src-6.6.2.tar.xz -/qtbase-everywhere-src-6.7.0.tar.xz -/qtbase-everywhere-src-6.7.1.tar.xz -/qtbase-everywhere-src-6.7.2.tar.xz -/qtbase-everywhere-src-6.8.0.tar.xz -/qtbase-everywhere-src-6.8.1.tar.xz -/qtbase-everywhere-src-6.8.2.tar.xz -/qtbase-everywhere-src-6.9.0-rc.tar.xz -/qtbase-everywhere-src-6.9.0.tar.xz -/qtbase-everywhere-src-6.9.1.tar.xz -/qtbase-everywhere-src-6.9.2.tar.xz -/qtbase-everywhere-src-6.10.0-rc.tar.xz -/qtbase-everywhere-src-6.10.0.tar.xz -/qtbase-everywhere-src-6.10.1.tar.xz diff --git a/CVE-2024-39936.patch b/CVE-2024-39936.patch new file mode 100644 index 0000000..c97f2f6 --- /dev/null +++ b/CVE-2024-39936.patch @@ -0,0 +1,232 @@ +From b1e75376cc3adfc7da5502a277dfe9711f3e0536 Mon Sep 17 00:00:00 2001 +From: Mårten Nordheim +Date: Tue, 25 Jun 2024 17:09:35 +0200 +Subject: [PATCH] HTTP2: Delay any communication until encrypted() can be responded to + +We have the encrypted() signal that lets users do extra checks on the +established connection. It is emitted as BlockingQueued, so the HTTP +thread stalls until it is done emitting. Users can potentially call +abort() on the QNetworkReply at that point, which is passed as a Queued +call back to the HTTP thread. That means that any currently queued +signal emission will be processed before the abort() call is processed. + +In the case of HTTP2 it is a little special since it is multiplexed and +the code is built to start requests as they are available. This means +that, while the code worked fine for HTTP1, since one connection only +has one request, it is not working for HTTP2, since we try to send more +requests in-between the encrypted() signal and the abort() call. + +This patch changes the code to delay any communication until the +encrypted() signal has been emitted and processed, for HTTP2 only. +It's done by adding a few booleans, both to know that we have to return +early and so we can keep track of what events arose and what we need to +resume once enough time has passed that any abort() call must have been +processed. + +Fixes: QTBUG-126610 +Pick-to: 6.8 6.7 6.5 6.2 5.15 5.12 +Change-Id: Ic25a600c278203256e35f541026f34a8783235ae +Reviewed-by: Marc Mutz +Reviewed-by: Volker Hilsheimer +--- + +diff --git a/src/network/access/qhttp2protocolhandler.cpp b/src/network/access/qhttp2protocolhandler.cpp +index 484f18de..d62529a3 100644 +--- a/src/network/access/qhttp2protocolhandler.cpp ++++ b/src/network/access/qhttp2protocolhandler.cpp +@@ -339,12 +339,12 @@ bool QHttp2ProtocolHandler::sendRequest() + } + } + +- if (!prefaceSent && !sendClientPreface()) +- return false; +- + if (!requests.size()) + return true; + ++ if (!prefaceSent && !sendClientPreface()) ++ return false; ++ + m_channel->state = QHttpNetworkConnectionChannel::WritingState; + // Check what was promised/pushed, maybe we do not have to send a request + // and have a response already? +diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp +index 14b5b861..c01d4623 100644 +--- a/src/network/access/qhttpnetworkconnectionchannel.cpp ++++ b/src/network/access/qhttpnetworkconnectionchannel.cpp +@@ -209,6 +209,10 @@ void QHttpNetworkConnectionChannel::abort() + bool QHttpNetworkConnectionChannel::sendRequest() + { + Q_ASSERT(protocolHandler); ++ if (waitingForPotentialAbort) { ++ needInvokeSendRequest = true; ++ return false; // this return value is unused ++ } + return protocolHandler->sendRequest(); + } + +@@ -221,21 +225,28 @@ bool QHttpNetworkConnectionChannel::sendRequest() + void QHttpNetworkConnectionChannel::sendRequestDelayed() + { + QMetaObject::invokeMethod(this, [this] { +- Q_ASSERT(protocolHandler); + if (reply) +- protocolHandler->sendRequest(); ++ sendRequest(); + }, Qt::ConnectionType::QueuedConnection); + } + + void QHttpNetworkConnectionChannel::_q_receiveReply() + { + Q_ASSERT(protocolHandler); ++ if (waitingForPotentialAbort) { ++ needInvokeReceiveReply = true; ++ return; ++ } + protocolHandler->_q_receiveReply(); + } + + void QHttpNetworkConnectionChannel::_q_readyRead() + { + Q_ASSERT(protocolHandler); ++ if (waitingForPotentialAbort) { ++ needInvokeReadyRead = true; ++ return; ++ } + protocolHandler->_q_readyRead(); + } + +@@ -1241,7 +1252,18 @@ void QHttpNetworkConnectionChannel::_q_encrypted() + // Similar to HTTP/1.1 counterpart below: + const auto &h2Pairs = h2RequestsToSend.values(); // (request, reply) + const auto &pair = h2Pairs.first(); ++ waitingForPotentialAbort = true; + emit pair.second->encrypted(); ++ ++ // We don't send or handle any received data until any effects from ++ // emitting encrypted() have been processed. This is necessary ++ // because the user may have called abort(). We may also abort the ++ // whole connection if the request has been aborted and there is ++ // no more requests to send. ++ QMetaObject::invokeMethod(this, ++ &QHttpNetworkConnectionChannel::checkAndResumeCommunication, ++ Qt::QueuedConnection); ++ + // In case our peer has sent us its settings (window size, max concurrent streams etc.) + // let's give _q_receiveReply a chance to read them first ('invokeMethod', QueuedConnection). + } +@@ -1259,6 +1281,28 @@ void QHttpNetworkConnectionChannel::_q_encrypted() + QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection); + } + ++ ++void QHttpNetworkConnectionChannel::checkAndResumeCommunication() ++{ ++ Q_ASSERT(connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP2 ++ || connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP2Direct); ++ ++ // Because HTTP/2 requires that we send a SETTINGS frame as the first thing we do, and respond ++ // to a SETTINGS frame with an ACK, we need to delay any handling until we can ensure that any ++ // effects from emitting encrypted() have been processed. ++ // This function is called after encrypted() was emitted, so check for changes. ++ ++ if (!reply && h2RequestsToSend.isEmpty()) ++ abort(); ++ waitingForPotentialAbort = false; ++ if (needInvokeReadyRead) ++ _q_readyRead(); ++ if (needInvokeReceiveReply) ++ _q_receiveReply(); ++ if (needInvokeSendRequest) ++ sendRequest(); ++} ++ + void QHttpNetworkConnectionChannel::requeueHttp2Requests() + { + QList h2Pairs = h2RequestsToSend.values(); +diff --git a/src/network/access/qhttpnetworkconnectionchannel_p.h b/src/network/access/qhttpnetworkconnectionchannel_p.h +index 0772a445..2a5336ca 100644 +--- a/src/network/access/qhttpnetworkconnectionchannel_p.h ++++ b/src/network/access/qhttpnetworkconnectionchannel_p.h +@@ -73,6 +73,10 @@ public: + QAbstractSocket *socket; + bool ssl; + bool isInitialized; ++ bool waitingForPotentialAbort = false; ++ bool needInvokeReceiveReply = false; ++ bool needInvokeReadyRead = false; ++ bool needInvokeSendRequest = false; + ChannelState state; + QHttpNetworkRequest request; // current request, only used for HTTP + QHttpNetworkReply *reply; // current reply for this request, only used for HTTP +@@ -145,6 +149,8 @@ public: + void closeAndResendCurrentRequest(); + void resendCurrentRequest(); + ++ void checkAndResumeCommunication(); ++ + bool isSocketBusy() const; + bool isSocketWriting() const; + bool isSocketWaiting() const; +diff --git a/tests/auto/network/access/http2/tst_http2.cpp b/tests/auto/network/access/http2/tst_http2.cpp +index b6f66942..7f135bf6 100644 +--- a/tests/auto/network/access/http2/tst_http2.cpp ++++ b/tests/auto/network/access/http2/tst_http2.cpp +@@ -103,6 +103,8 @@ private slots: + + void duplicateRequestsWithAborts(); + ++ void abortOnEncrypted(); ++ + protected slots: + // Slots to listen to our in-process server: + void serverStarted(quint16 port); +@@ -1393,6 +1395,48 @@ void tst_Http2::duplicateRequestsWithAborts() + QCOMPARE(finishedCount, ExpectedSuccessfulRequests); + } + ++void tst_Http2::abortOnEncrypted() ++{ ++#if !QT_CONFIG(ssl) ++ QSKIP("TLS support is needed for this test"); ++#else ++ clearHTTP2State(); ++ serverPort = 0; ++ ++ ServerPtr targetServer(newServer(defaultServerSettings, H2Type::h2Direct)); ++ ++ QMetaObject::invokeMethod(targetServer.data(), "startServer", Qt::QueuedConnection); ++ runEventLoop(); ++ ++ nRequests = 1; ++ nSentRequests = 0; ++ ++ const auto url = requestUrl(H2Type::h2Direct); ++ QNetworkRequest request(url); ++ request.setAttribute(QNetworkRequest::Http2DirectAttribute, true); ++ ++ std::unique_ptr reply{manager->get(request)}; ++ reply->ignoreSslErrors(); ++ connect(reply.get(), &QNetworkReply::encrypted, reply.get(), [reply = reply.get()](){ ++ reply->abort(); ++ }); ++ connect(reply.get(), &QNetworkReply::errorOccurred, this, &tst_Http2::replyFinishedWithError); ++ ++ runEventLoop(); ++ STOP_ON_FAILURE ++ ++ QCOMPARE(nRequests, 0); ++ QCOMPARE(reply->error(), QNetworkReply::OperationCanceledError); ++ ++ const bool res = QTest::qWaitFor( ++ [this, server = targetServer.get()]() { ++ return serverGotSettingsACK || prefaceOK || nSentRequests > 0; ++ }, ++ 500); ++ QVERIFY(!res); ++#endif // QT_CONFIG(ssl) ++} ++ + void tst_Http2::serverStarted(quint16 port) + { + serverPort = port; diff --git a/qt6-qtbase.spec b/qt6-qtbase.spec index 382a945..fa507f8 100644 --- a/qt6-qtbase.spec +++ b/qt6-qtbase.spec @@ -2,7 +2,7 @@ %global multilib_archs x86_64 %{ix86} %{?mips} ppc64 ppc s390x s390 sparc64 sparcv9 %global multilib_basearchs x86_64 %{?mips64} ppc64 s390x sparc64 -%ifarch s390x ppc64le aarch64 armv7hl riscv64 +%ifarch s390x ppc64le aarch64 armv7hl %global no_sse2 1 %endif @@ -12,14 +12,6 @@ %endif %endif -%if 0%{?rhel} >= 10 -# Use mutter on RHEL 10+ since it's the only shipped compositor -%global wlheadless_compositor mutter -%else -# Use the simple reference compositor to simplify dependencies -%global wlheadless_compositor weston -%endif - %global platform linux-g++ %if 0%{?use_clang} @@ -41,14 +33,12 @@ BuildRequires: pkgconfig(libsystemd) #global tests 1 #global unstable 0 -%if 0%{?unstable} -%global prerelease rc -%endif +%global prerelease rc2 Name: qt6-qtbase Summary: Qt6 - QtBase components -Version: 6.10.1 -Release: 3%{?dist} +Version: 6.6.2 +Release: 2%{?dist} License: LGPL-3.0-only OR GPL-3.0-only WITH Qt-GPL-exception-1.0 Url: http://qt-project.org/ @@ -75,8 +65,8 @@ Source6: 10-qt6-check-opengl2.sh # macros Source10: macros.qt6-qtbase -Patch1: qtbase-CMake-Install-objects-files-into-ARCHDATADIR.patch -Patch2: qtbase-use-only-major-minor-for-private-api-tag.patch +Patch1: qtbase-tell-the-truth-about-private-API.patch +Patch2: qtbase-CMake-Install-objects-files-into-ARCHDATADIR.patch # upstreamable patches # namespace QT_VERSION_CHECK to workaround major/minor being pre-defined (#1396755) @@ -97,12 +87,17 @@ Patch56: qtbase-mysql.patch # fix FTBFS against libglvnd-1.3.4+ Patch58: qtbase-libglvnd.patch -# upstream patches -Patch100: qtbase-wayland-convey-preference-for-server-side-decorations.patch -Patch101: qtbase-wayland-compress-high-frequency-mouse-events.patch -Patch102: qtbase-wayland-optimize-scroll-operations.patch -Patch103: qtbase-wayland-enable-event-compression-and-fix-scroll-end-event.patch -Patch104: qtbase-wayland-fix-crash-in-qwaylandshmbackingstore-scroll.patch +# Bug 1954359 - Many emoji don't show up in Qt apps because qt does not handle 'emoji' font family +# FIXME: this change seems to completely break font rendering for some people +# Patch60: qtbase-cache-emoji-font.patch + +%if 0%{?fedora} < 39 +# Latest QGnomePlatform needs to be specified to be used +Patch100: qtbase-use-qgnomeplatform-as-default-platform-theme-on-gnome.patch +%endif + +## upstream patches +Patch200: CVE-2024-39936.patch # Do not check any files in %%{_qt6_plugindir}/platformthemes/ for requires. # Those themes are there for platform integration. If the required libraries are @@ -123,17 +118,12 @@ BuildRequires: ninja-build BuildRequires: cups-devel BuildRequires: desktop-file-utils BuildRequires: findutils -%if 0%{?fedora} || 0%{?epel} BuildRequires: double-conversion-devel -%else -Provides: bundled(double-conversion) -%endif %if 0%{?fedora} || 0%{?epel} BuildRequires: libb2-devel %else Provides: bundled(libb2) %endif -Provides: bundled(emoji-segmenter) BuildRequires: libjpeg-devel BuildRequires: libmng-devel BuildRequires: libtiff-devel @@ -170,16 +160,13 @@ BuildRequires: pkgconfig(xkeyboard-config) %global vulkan 1 BuildRequires: pkgconfig(vulkan) %global egl 1 +BuildRequires: mesa-libEGL-devel BuildRequires: pkgconfig(egl) BuildRequires: pkgconfig(gbm) BuildRequires: pkgconfig(libglvnd) -BuildRequires: pkgconfig(xrender) BuildRequires: pkgconfig(x11) -BuildRequires: pkgconfig(wayland-scanner) -BuildRequires: pkgconfig(wayland-server) -BuildRequires: pkgconfig(wayland-client) -BuildRequires: pkgconfig(wayland-cursor) -BuildRequires: pkgconfig(wayland-egl) +# only needed for GLES2 and GLES3 builds +#BuildRequires: pkgconfig(glesv2) %global sqlite 1 BuildRequires: pkgconfig(sqlite3) >= 3.7 @@ -192,6 +179,7 @@ BuildRequires: pkgconfig(xcb) pkgconfig(xcb-glx) pkgconfig(xcb-icccm) pkgconfig( BuildRequires: pkgconfig(zlib) BuildRequires: perl BuildRequires: perl-generators +# see patch68 BuildRequires: python3 BuildRequires: qt6-rpm-macros @@ -199,11 +187,9 @@ BuildRequires: qt6-rpm-macros BuildRequires: dbus-x11 BuildRequires: mesa-dri-drivers BuildRequires: time -BuildRequires: (wlheadless-run and %{wlheadless_compositor}) +BuildRequires: xorg-x11-server-Xvfb %endif -Requires: qt6-filesystem - Requires: %{name}-common = %{version}-%{release} ## Sql drivers @@ -221,8 +207,6 @@ handling. %package common Summary: Common files for Qt6 Requires: %{name} = %{version}-%{release} -Obsoletes: qgnomeplatform-common <= 0.9.3 -Provides: qgnomeplatform-common = %{version}-%{release} BuildArch: noarch %description common %{summary}. @@ -232,7 +216,7 @@ Summary: Development files for %{name} Requires: %{name}%{?_isa} = %{version}-%{release} Requires: %{name}-gui%{?_isa} %if 0%{?egl} -Requires: pkgconfig(egl) +Requires: libEGL-devel %endif Requires: pkgconfig(gl) %if 0%{?vulkan} @@ -319,12 +303,9 @@ Requires: %{name}%{?_isa} = %{version}-%{release} Summary: Qt6 GUI-related libraries Requires: %{name}%{?_isa} = %{version}-%{release} Recommends: mesa-dri-drivers%{?_isa} +Recommends: qt6-qtwayland%{?_isa} # Required for some locales: https://pagure.io/fedora-kde/SIG/issue/311 Recommends: qt6-qttranslations -Obsoletes: adwaita-qt6 <= 1.4.2 -Obsoletes: libadwaita-qt6 <= 1.4.2 -Obsoletes: qgnomeplatform-qt6 <= 0.9.3 -Provides: qgnomeplatform-qt6 = %{version}-%{release} # for Source6: 10-qt6-check-opengl2.sh: # glxinfo Requires: glx-utils @@ -374,41 +355,41 @@ export LDFLAGS="$LDFLAGS $RPM_LD_FLAGS" export MAKEFLAGS="%{?_smp_mflags}" %cmake_qt6 \ - -DFEATURE_accessibility=ON \ - -DFEATURE_fontconfig=ON \ - -DFEATURE_glib=ON \ - -DFEATURE_sse2=%{?no_sse2:OFF}%{!?no_sse2:ON} \ - -DFEATURE_icu=ON \ - -DFEATURE_enable_new_dtags=ON \ - -DFEATURE_emojisegmenter=ON \ - -DFEATURE_journald=%{?journald:ON}%{!?journald:OFF} \ - -DFEATURE_openssl_linked=ON \ - -DFEATURE_openssl_hash=ON \ - -DFEATURE_libproxy=ON \ - -DFEATURE_sctp=ON \ - -DFEATURE_separate_debug_info=OFF \ - -DFEATURE_reduce_relocations=OFF \ - -DFEATURE_relocatable=OFF \ - -DFEATURE_system_jpeg=ON \ - -DFEATURE_system_png=ON \ - -DFEATURE_system_zlib=ON \ - %{?ibase:-DFEATURE_sql_ibase=ON} \ - -DFEATURE_sql_odbc=ON \ - -DFEATURE_sql_mysql=ON \ - -DFEATURE_sql_psql=ON \ - -DFEATURE_sql_sqlite=ON \ - -DFEATURE_rpath=OFF \ - -DFEATURE_zstd=ON \ - -DFEATURE_elf_private_full_version=ON \ - %{?dbus_linked:-DFEATURE_dbus_linked=ON} \ - %{?pcre:-DFEATURE_system_pcre2=ON} \ - %{?sqlite:-DFEATURE_system_sqlite=ON} \ + -DQT_FEATURE_accessibility=ON \ + -DQT_FEATURE_fontconfig=ON \ + -DQT_FEATURE_glib=ON \ + -DQT_FEATURE_sse2=%{?no_sse2:OFF}%{!?no_sse2:ON} \ + -DQT_FEATURE_icu=ON \ + -DQT_FEATURE_enable_new_dtags=ON \ + -DQT_FEATURE_journald=%{?journald:ON}%{!?journald:OFF} \ + -DQT_FEATURE_openssl_linked=ON \ + -DQT_FEATURE_openssl_hash=ON \ + -DQT_FEATURE_libproxy=ON \ + -DQT_FEATURE_sctp=ON \ + -DQT_FEATURE_separate_debug_info=OFF \ + -DQT_FEATURE_reduce_relocations=OFF \ + -DQT_FEATURE_relocatable=OFF \ + -DQT_FEATURE_system_jpeg=ON \ + -DQT_FEATURE_system_png=ON \ + -DQT_FEATURE_system_zlib=ON \ + %{?ibase:-DQT_FEATURE_sql_ibase=ON} \ + -DQT_FEATURE_sql_odbc=ON \ + -DQT_FEATURE_sql_mysql=ON \ + -DQT_FEATURE_sql_psql=ON \ + -DQT_FEATURE_sql_sqlite=ON \ + -DQT_FEATURE_rpath=OFF \ + -DQT_FEATURE_zstd=ON \ + %{?dbus_linked:-DQT_FEATURE_dbus_linked=ON} \ + %{?pcre:-DQT_FEATURE_system_pcre2=ON} \ + %{?sqlite:-DQT_FEATURE_system_sqlite=ON} \ -DBUILD_SHARED_LIBS=ON \ -DQT_BUILD_EXAMPLES=%{?examples:ON}%{!?examples:OFF} \ - -DQT_INSTALL_EXAMPLES_SOURCES=%{?examples:ON}%{!?examples:OFF} \ -DQT_BUILD_TESTS=%{?tests:ON}%{!?tests:OFF} \ -DQT_QMAKE_TARGET_MKSPEC=%{platform} +# FIXME +# -DQT_FEATURE_directfb=ON \ + %cmake_build @@ -440,7 +421,7 @@ translationdir=%{_qt6_translationdir} Name: Qt6 Description: Qt6 Configuration -Version: 6.10.1 +Version: 6.6.2 EOF # rpm macros @@ -454,7 +435,7 @@ sed -i \ %{buildroot}%{_rpmmacrodir}/macros.qt6-qtbase # create/own dirs -mkdir -p %{buildroot}%{_qt6_plugindir}/{designer,iconengines,script,styles} +mkdir -p %{buildroot}{%{_qt6_archdatadir}/mkspecs/modules,%{_qt6_importdir},%{_qt6_libexecdir},%{_qt6_plugindir}/{designer,iconengines,script,styles},%{_qt6_translationdir}} mkdir -p %{buildroot}%{_sysconfdir}/xdg/QtProject # hardlink files to {_bindir}, add -qt6 postfix to not conflict @@ -498,27 +479,10 @@ install -p -m755 -D %{SOURCE6} %{buildroot}%{_sysconfdir}/X11/xinit/xinitrc.d/10 mkdir -p %{buildroot}%{_qt6_headerdir}/QtXcb install -m 644 src/plugins/platforms/xcb/*.h %{buildroot}%{_qt6_headerdir}/QtXcb/ -# Copied from OpenSUSE packages - -# These files are only useful for the Qt continuous integration -rm %{buildroot}%{_qt6_libexecdir}/ensure_pro_file.cmake -rm %{buildroot}%{_qt6_libexecdir}/qt-android-runner.py -rm %{buildroot}%{_qt6_libexecdir}/qt-testrunner.py -rm %{buildroot}%{_qt6_libexecdir}/sanitizer-testrunner.py - -# Not useful for desktop installs -rm -r %{buildroot}%{_qt6_libdir}/cmake/Qt6ExamplesAssetDownloaderPrivate -rm -r %{buildroot}%{_qt6_headerdir}/QtExamplesAssetDownloader -rm %{buildroot}%{_qt6_descriptionsdir}/ExamplesAssetDownloaderPrivate.json -rm %{buildroot}%{_qt6_libdir}/libQt6ExamplesAssetDownloader.* -rm %{buildroot}%{_qt6_libdir}/qt6/metatypes/qt6examplesassetdownloaderprivate_metatypes.json - -# These shouldn't be probably installed -rm -r %{buildroot}%{_qt6_libdir}/cmake/Qt6/3rdparty/extra-cmake-modules/*.patch - -# This is only for Apple platforms and has a python2 dep -rm -r %{buildroot}%{_qt6_mkspecsdir}/features/uikit +rm %{buildroot}/%{_qt6_libexecdir}/qt-cmake-private-install.cmake +# Use better location for some new scripts in qtbase-6.0.1 +mv %{buildroot}/%{_qt6_libexecdir}/ensure_pro_file.cmake %{buildroot}/%{_qt6_libdir}/cmake/Qt6/ensure_pro_file.cmake %check # verify Qt6.pc @@ -533,7 +497,7 @@ export LD_LIBRARY_PATH=%{buildroot}%{_qt6_libdir} # dbus tests error out when building if session bus is not available dbus-launch --exit-with-session \ %make_build sub-tests -k ||: -wlheadless-run -c %{wlheadless_compositor} -- \ +xvfb-run -a --server-args="-screen 0 1280x1024x32" \ dbus-launch --exit-with-session \ time \ make check -k ||: @@ -545,7 +509,6 @@ make check -k ||: %license LICENSES/GPL* %license LICENSES/LGPL* %dir %{_sysconfdir}/xdg/QtProject/ -%{_qt6_archdatadir}/sbom/qtbase-%{qt_version}.spdx %{_qt6_libdir}/libQt6Concurrent.so.6* %{_qt6_libdir}/libQt6Core.so.6* %{_qt6_libdir}/libQt6DBus.so.6* @@ -553,14 +516,23 @@ make check -k ||: %{_qt6_libdir}/libQt6Sql.so.6* %{_qt6_libdir}/libQt6Test.so.6* %{_qt6_libdir}/libQt6Xml.so.6* +%dir %{_qt6_docdir}/ %{_qt6_docdir}/global/ %{_qt6_docdir}/config/ +%{_qt6_importdir}/ +%{_qt6_translationdir}/ +%if "%{_qt6_prefix}" != "%{_prefix}" +%dir %{_qt6_prefix}/ +%endif +%dir %{_qt6_archdatadir}/ +%dir %{_qt6_datadir}/ %{_qt6_datadir}/qtlogging.ini +%dir %{_qt6_libexecdir}/ +%dir %{_qt6_plugindir}/ %dir %{_qt6_plugindir}/designer/ %dir %{_qt6_plugindir}/generic/ %dir %{_qt6_plugindir}/iconengines/ %dir %{_qt6_plugindir}/imageformats/ -%dir %{_qt6_plugindir}/networkinformation/ %dir %{_qt6_plugindir}/platforminputcontexts/ %dir %{_qt6_plugindir}/platforms/ %dir %{_qt6_plugindir}/platformthemes/ @@ -568,61 +540,61 @@ make check -k ||: %dir %{_qt6_plugindir}/script/ %dir %{_qt6_plugindir}/sqldrivers/ %dir %{_qt6_plugindir}/styles/ -%dir %{_qt6_plugindir}/tls/ %{_qt6_plugindir}/networkinformation/libqglib.so %{_qt6_plugindir}/networkinformation/libqnetworkmanager.so %{_qt6_plugindir}/sqldrivers/libqsqlite.so %{_qt6_plugindir}/tls/libqcertonlybackend.so %{_qt6_plugindir}/tls/libqopensslbackend.so -%{_bindir}/qtpaths* -%{_qt6_bindir}/qtpaths* %files common # mostly empty for now, consider: filesystem/dir ownership, licenses %{_rpmmacrodir}/macros.qt6-qtbase %files devel +%dir %{_qt6_libdir}/qt6/modules +%dir %{_qt6_libdir}/qt6/metatypes %dir %{_qt6_libdir}/cmake/Qt6 -%dir %{_qt6_libdir}/cmake/Qt6/libexec %dir %{_qt6_libdir}/cmake/Qt6/platforms %dir %{_qt6_libdir}/cmake/Qt6/platforms/Platform %dir %{_qt6_libdir}/cmake/Qt6/config.tests -%dir %{_qt6_libdir}/cmake/Qt6/3rdparty %dir %{_qt6_libdir}/cmake/Qt6/3rdparty/extra-cmake-modules -%dir %{_qt6_libdir}/cmake/Qt6/3rdparty/extra-cmake-modules/find-modules -%dir %{_qt6_libdir}/cmake/Qt6/3rdparty/extra-cmake-modules/modules %dir %{_qt6_libdir}/cmake/Qt6/3rdparty/kwin %dir %{_qt6_libdir}/cmake/Qt6BuildInternals %dir %{_qt6_libdir}/cmake/Qt6BuildInternals/StandaloneTests -%dir %{_qt6_libdir}/cmake/Qt6BuildInternals/QtStandaloneTestTemplateProject %dir %{_qt6_libdir}/cmake/Qt6Concurrent %dir %{_qt6_libdir}/cmake/Qt6Core %dir %{_qt6_libdir}/cmake/Qt6CoreTools %dir %{_qt6_libdir}/cmake/Qt6DBus %dir %{_qt6_libdir}/cmake/Qt6DBusTools +%dir %{_qt6_libdir}/cmake/Qt6DeviceDiscoverySupportPrivate +%dir %{_qt6_libdir}/cmake/Qt6EglFSDeviceIntegrationPrivate +%dir %{_qt6_libdir}/cmake/Qt6EglFsKmsGbmSupportPrivate +%dir %{_qt6_libdir}/cmake/Qt6EglFsKmsSupportPrivate +%dir %{_qt6_libdir}/cmake/Qt6ExampleIconsPrivate +%dir %{_qt6_libdir}/cmake/Qt6FbSupportPrivate %dir %{_qt6_libdir}/cmake/Qt6Gui %dir %{_qt6_libdir}/cmake/Qt6GuiTools %dir %{_qt6_libdir}/cmake/Qt6HostInfo +%dir %{_qt6_libdir}/cmake/Qt6KmsSupportPrivate %dir %{_qt6_libdir}/cmake/Qt6Network %dir %{_qt6_libdir}/cmake/Qt6OpenGL %dir %{_qt6_libdir}/cmake/Qt6OpenGLWidgets %dir %{_qt6_libdir}/cmake/Qt6PrintSupport %dir %{_qt6_libdir}/cmake/Qt6Sql %dir %{_qt6_libdir}/cmake/Qt6Test -%dir %{_qt6_libdir}/cmake/Qt6WaylandClient/ -%dir %{_qt6_libdir}/cmake/Qt6WaylandClientPrivate -%dir %{_qt6_libdir}/cmake/Qt6WaylandGlobalPrivate/ -%dir %{_qt6_libdir}/cmake/Qt6WaylandScannerTools/ -%dir %{_qt6_libdir}/cmake/Qt6WlShellIntegrationPrivate/ %dir %{_qt6_libdir}/cmake/Qt6Widgets %dir %{_qt6_libdir}/cmake/Qt6WidgetsTools %dir %{_qt6_libdir}/cmake/Qt6Xml +%if "%{_qt6_bindir}" != "%{_bindir}" +%dir %{_qt6_bindir} +%endif %{_bindir}/androiddeployqt %{_bindir}/androiddeployqt6 %{_bindir}/androidtestrunner %{_bindir}/qdbuscpp2xml* %{_bindir}/qdbusxml2cpp* %{_bindir}/qmake* +%{_bindir}/qtpaths* %{_bindir}/qt-cmake %{_bindir}/qt-cmake-create %{_bindir}/qt-configure-module @@ -633,16 +605,17 @@ make check -k ||: %{_qt6_bindir}/qdbuscpp2xml %{_qt6_bindir}/qdbusxml2cpp %{_qt6_bindir}/qmake +%{_qt6_bindir}/qtpaths* %{_qt6_bindir}/qt-cmake %{_qt6_bindir}/qt-cmake-create %{_qt6_bindir}/qt-configure-module %{_qt6_libexecdir}/qt-cmake-private -%{_qt6_libexecdir}/qt-cmake-private-install.cmake %{_qt6_libexecdir}/qt-cmake-standalone-test %{_qt6_libexecdir}/cmake_automoc_parser -%{_qt6_libexecdir}/qt-internal-configure-examples %{_qt6_libexecdir}/qt-internal-configure-tests +%{_qt6_libexecdir}/sanitizer-testrunner.py %{_qt6_libexecdir}/syncqt +%{_qt6_libexecdir}/android_emulator_launcher.sh %{_qt6_libexecdir}/moc %{_qt6_libexecdir}/tracegen %{_qt6_libexecdir}/tracepointgen @@ -650,10 +623,16 @@ make check -k ||: %{_qt6_libexecdir}/qvkgen %{_qt6_libexecdir}/rcc %{_qt6_libexecdir}/uic -%{_qt6_libexecdir}/qtwaylandscanner +%{_qt6_libexecdir}/qt-testrunner.py +%{_qt6_libdir}/qt6/modules/*.json +%if "%{_qt6_headerdir}" != "%{_includedir}" +%dir %{_qt6_headerdir} +%endif %{_qt6_headerdir}/QtConcurrent/ %{_qt6_headerdir}/QtCore/ %{_qt6_headerdir}/QtDBus/ +%{_qt6_headerdir}/QtInputSupport +%{_qt6_headerdir}/QtExampleIcons %{_qt6_headerdir}/QtGui/ %{_qt6_headerdir}/QtNetwork/ %{_qt6_headerdir}/QtOpenGL/ @@ -661,12 +640,13 @@ make check -k ||: %{_qt6_headerdir}/QtPrintSupport/ %{_qt6_headerdir}/QtSql/ %{_qt6_headerdir}/QtTest/ -%{_qt6_headerdir}/QtWaylandClient/ -%{_qt6_headerdir}/QtWaylandGlobal/ -%{_qt6_headerdir}/QtWlShellIntegration/ %{_qt6_headerdir}/QtWidgets/ %{_qt6_headerdir}/QtXcb/ %{_qt6_headerdir}/QtXml/ +%{_qt6_headerdir}/QtEglFSDeviceIntegration +%{_qt6_headerdir}/QtEglFsKmsGbmSupport +%{_qt6_headerdir}/QtEglFsKmsSupport +%{_qt6_mkspecsdir}/ %{_qt6_libdir}/libQt6Concurrent.prl %{_qt6_libdir}/libQt6Concurrent.so %{_qt6_libdir}/libQt6Core.prl @@ -687,19 +667,16 @@ make check -k ||: %{_qt6_libdir}/libQt6Sql.so %{_qt6_libdir}/libQt6Test.prl %{_qt6_libdir}/libQt6Test.so -%{_qt6_libdir}/libQt6WaylandClient.so -%{_qt6_libdir}/libQt6WlShellIntegration.so -%{_qt6_libdir}/libQt6WaylandClient.prl -%{_qt6_libdir}/libQt6WlShellIntegration.prl %{_qt6_libdir}/libQt6Widgets.prl %{_qt6_libdir}/libQt6Widgets.so %{_qt6_libdir}/libQt6XcbQpa.prl -%{_qt6_libdir}/libQt6XcbQpa.so +%{_qt6_libdir}/libQt6XcbQpa.so %{_qt6_libdir}/libQt6Xml.prl %{_qt6_libdir}/libQt6Xml.so -%{_qt6_libdir}/cmake/Qt6/3rdparty/extra-cmake-modules/REUSE.toml -%{_qt6_libdir}/cmake/Qt6/3rdparty/kwin/REUSE.toml -%{_qt6_libdir}/cmake/Qt6/*.in +%{_qt6_libdir}/libQt6EglFSDeviceIntegration.prl +%{_qt6_libdir}/libQt6EglFSDeviceIntegration.so +%{_qt6_libdir}/libQt6EglFsKmsGbmSupport.prl +%{_qt6_libdir}/libQt6EglFsKmsGbmSupport.so %{_qt6_libdir}/cmake/Qt6/*.h.in %{_qt6_libdir}/cmake/Qt6/*.cmake %{_qt6_libdir}/cmake/Qt6/*.cmake.in @@ -726,14 +703,21 @@ make check -k ||: %{_qt6_libdir}/cmake/Qt6BuildInternals/QtStandaloneTestTemplateProject/Main.cmake %{_qt6_libdir}/cmake/Qt6Concurrent/*.cmake %{_qt6_libdir}/cmake/Qt6Core/*.cmake -%{_qt6_libdir}/cmake/Qt6Core/Qt6CoreResourceInit.in.cpp %{_qt6_libdir}/cmake/Qt6Core/Qt6CoreConfigureFileTemplate.in %{_qt6_libdir}/cmake/Qt6CoreTools/*.cmake %{_qt6_libdir}/cmake/Qt6DBus/*.cmake %{_qt6_libdir}/cmake/Qt6DBusTools/*.cmake +%{_qt6_libdir}/cmake/Qt6DeviceDiscoverySupportPrivate/*.cmake +%{_qt6_libdir}/cmake/Qt6EglFSDeviceIntegrationPrivate/*.cmake +%{_qt6_libdir}/cmake/Qt6EglFsKmsGbmSupportPrivate/*.cmake +%{_qt6_libdir}/cmake/Qt6EglFsKmsSupportPrivate/*.cmake +%{_qt6_libdir}/cmake/Qt6ExampleIconsPrivate/*.cmake +%{_qt6_libdir}/cmake/Qt6FbSupportPrivate/*.cmake %{_qt6_libdir}/cmake/Qt6Gui/*.cmake %{_qt6_libdir}/cmake/Qt6GuiTools/*.cmake %{_qt6_libdir}/cmake/Qt6HostInfo/*.cmake +%{_qt6_libdir}/cmake/Qt6InputSupportPrivate/*.cmake +%{_qt6_libdir}/cmake/Qt6KmsSupportPrivate/*.cmake %{_qt6_libdir}/cmake/Qt6Network/*.cmake %{_qt6_libdir}/cmake/Qt6OpenGL/*.cmake %{_qt6_libdir}/cmake/Qt6OpenGLWidgets/*.cmake @@ -741,142 +725,38 @@ make check -k ||: %{_qt6_libdir}/cmake/Qt6Sql/Qt6Sql*.cmake %{_qt6_libdir}/cmake/Qt6Sql/Qt6QSQLiteDriverPlugin*.cmake %{_qt6_libdir}/cmake/Qt6Test/*.cmake -%{_qt6_libdir}/cmake/Qt6WaylandClient/*.cmake -%{_qt6_libdir}/cmake/Qt6WaylandClientPrivate/*.cmake -%{_qt6_libdir}/cmake/Qt6WaylandGlobalPrivate/*.cmake -%{_qt6_libdir}/cmake/Qt6WaylandScannerTools/*.cmake -%{_qt6_libdir}/cmake/Qt6WlShellIntegrationPrivate/ %{_qt6_libdir}/cmake/Qt6Widgets/*.cmake %{_qt6_libdir}/cmake/Qt6WidgetsTools/*.cmake -%{_qt6_libdir}/cmake/Qt6Xml/*.cmake -%{_qt6_descriptionsdir}/Concurrent.json -%{_qt6_descriptionsdir}/Core.json -%{_qt6_descriptionsdir}/DBus.json -%{_qt6_descriptionsdir}/Gui.json -%{_qt6_descriptionsdir}/Network.json -%{_qt6_descriptionsdir}/OpenGL.json -%{_qt6_descriptionsdir}/OpenGLWidgets.json -%{_qt6_descriptionsdir}/PrintSupport.json -%{_qt6_descriptionsdir}/Sql.json -%{_qt6_descriptionsdir}/Test.json -%{_qt6_descriptionsdir}/WaylandClient.json -%{_qt6_descriptionsdir}/WaylandGlobalPrivate.json -%{_qt6_descriptionsdir}/WlShellIntegrationPrivate.json -%{_qt6_descriptionsdir}/Widgets.json -%{_qt6_descriptionsdir}/Xml.json -%{_qt6_metatypesdir}/qt6concurrent_metatypes.json -%{_qt6_metatypesdir}/qt6core_metatypes.json -%{_qt6_metatypesdir}/qt6dbus_metatypes.json -%{_qt6_metatypesdir}/qt6gui_metatypes.json -%{_qt6_metatypesdir}/qt6network_metatypes.json -%{_qt6_metatypesdir}/qt6opengl_metatypes.json -%{_qt6_metatypesdir}/qt6openglwidgets_metatypes.json -%{_qt6_metatypesdir}/qt6printsupport_metatypes.json -%{_qt6_metatypesdir}/qt6sql_metatypes.json -%{_qt6_metatypesdir}/qt6test_metatypes.json -%{_qt6_metatypesdir}/qt6widgets_metatypes.json -%{_qt6_metatypesdir}/qt6xml_metatypes.json -%{_qt6_libdir}/pkgconfig/*.pc -%{_qt6_mkspecsdir}/* -## private-devel globs -%exclude %{_qt6_headerdir}/*/%{qt_version}/ - -%files private-devel -%{_qt6_headerdir}/QtEglFSDeviceIntegration -%{_qt6_headerdir}/QtEglFsKmsGbmSupport -%{_qt6_headerdir}/QtEglFsKmsSupport -%dir %{_qt6_libdir}/cmake/Qt6CorePrivate -%dir %{_qt6_libdir}/cmake/Qt6DBusPrivate -%dir %{_qt6_libdir}/cmake/Qt6GuiPrivate -%dir %{_qt6_libdir}/cmake/Qt6NetworkPrivate -%dir %{_qt6_libdir}/cmake/Qt6OpenGLPrivate -%dir %{_qt6_libdir}/cmake/Qt6PrintSupportPrivate -%dir %{_qt6_libdir}/cmake/Qt6SqlPrivate -%dir %{_qt6_libdir}/cmake/Qt6TestInternalsPrivate -%dir %{_qt6_libdir}/cmake/Qt6TestInternalsPrivate/3rdparty/cmake -%dir %{_qt6_libdir}/cmake/Qt6TestPrivate -%dir %{_qt6_libdir}/cmake/Qt6WidgetsPrivate -%dir %{_qt6_libdir}/cmake/Qt6XmlPrivate -%dir %{_qt6_libdir}/cmake/Qt6EglFSDeviceIntegrationPrivate -%dir %{_qt6_libdir}/cmake/Qt6EglFsKmsGbmSupportPrivate -%dir %{_qt6_libdir}/cmake/Qt6EglFsKmsSupportPrivate -%dir %{_qt6_libdir}/cmake/Qt6XcbQpaPrivate -%{_qt6_libdir}/cmake/Qt6CorePrivate/*.cmake -%{_qt6_libdir}/cmake/Qt6DBusPrivate/*.cmake -%{_qt6_libdir}/cmake/Qt6GuiPrivate/*.cmake -%{_qt6_libdir}/cmake/Qt6NetworkPrivate/*.cmake -%{_qt6_libdir}/cmake/Qt6OpenGLPrivate/*.cmake -%{_qt6_libdir}/cmake/Qt6PrintSupportPrivate/*.cmake -%{_qt6_libdir}/cmake/Qt6SqlPrivate/*.cmake -%{_qt6_libdir}/cmake/Qt6TestInternalsPrivate/*.cmake -%{_qt6_libdir}/cmake/Qt6TestInternalsPrivate/3rdparty/cmake/*.cmake -%{_qt6_libdir}/cmake/Qt6TestPrivate/*.cmake -%{_qt6_libdir}/cmake/Qt6WidgetsPrivate/*.cmake -%{_qt6_libdir}/cmake/Qt6XmlPrivate/*.cmake -%{_qt6_libdir}/cmake/Qt6EglFSDeviceIntegrationPrivate/*.cmake -%{_qt6_libdir}/cmake/Qt6EglFsKmsGbmSupportPrivate/*.cmake -%{_qt6_libdir}/cmake/Qt6EglFsKmsSupportPrivate/*.cmake %{_qt6_libdir}/cmake/Qt6XcbQpaPrivate/*.cmake +%{_qt6_libdir}/cmake/Qt6Xml/*.cmake +%{_qt6_libdir}/qt6/metatypes/*.json +%{_qt6_libdir}/qt6/objects-RelWithDebInfo/ExampleIconsPrivate_resources_1/.rcc/qrc_example_icons.cpp.o +%{_qt6_libdir}/pkgconfig/*.pc + %if 0%{?egl} %{_qt6_libdir}/libQt6EglFsKmsSupport.prl %{_qt6_libdir}/libQt6EglFsKmsSupport.so %endif -%{_qt6_libdir}/libQt6EglFSDeviceIntegration.prl -%{_qt6_libdir}/libQt6EglFSDeviceIntegration.so -%{_qt6_libdir}/libQt6EglFsKmsGbmSupport.prl -%{_qt6_libdir}/libQt6EglFsKmsGbmSupport.so -%{_qt6_descriptionsdir}/EglFSDeviceIntegrationPrivate.json -%{_qt6_descriptionsdir}/EglFsKmsGbmSupportPrivate.json -%{_qt6_descriptionsdir}/EglFsKmsSupportPrivate.json -%{_qt6_descriptionsdir}/XcbQpaPrivate.json -%{_qt6_metatypesdir}/qt6eglfsdeviceintegrationprivate_metatypes.json -%{_qt6_metatypesdir}/qt6eglfskmsgbmsupportprivate_metatypes.json -%{_qt6_metatypesdir}/qt6eglfskmssupportprivate_metatypes.json -%{_qt6_metatypesdir}/qt6xcbqpaprivate_metatypes.json -%{_qt6_metatypesdir}/qt6waylandclient_metatypes.json -%{_qt6_metatypesdir}/qt6wlshellintegrationprivate_metatypes.json +## private-devel globs +%exclude %{_qt6_headerdir}/*/%{qt_version}/ + +%files private-devel %{_qt6_headerdir}/*/%{qt_version}/ -%{_qt6_descriptionsdir}/TestInternalsPrivate.json %files static -%dir %{_qt6_libdir}/cmake/Qt6ExampleIconsPrivate -%{_qt6_libdir}/cmake/Qt6ExampleIconsPrivate/*.cmake -%{_qt6_headerdir}/QtExampleIcons -%{_qt6_libdir}/libQt6ExampleIcons.a -%{_qt6_libdir}/libQt6ExampleIcons.prl -%{_qt6_descriptionsdir}/ExampleIconsPrivate.json -%dir %{_qt6_archdatadir}/objects-* -%{_qt6_archdatadir}/objects-*/ExampleIconsPrivate_resources_1/ -%{_qt6_metatypesdir}/qt6exampleiconsprivate_metatypes.json -%dir %{_qt6_libdir}/cmake/Qt6DeviceDiscoverySupportPrivate -%{_qt6_libdir}/cmake/Qt6DeviceDiscoverySupportPrivate/*.cmake %{_qt6_headerdir}/QtDeviceDiscoverySupport %{_qt6_libdir}/libQt6DeviceDiscoverySupport.*a %{_qt6_libdir}/libQt6DeviceDiscoverySupport.prl -%{_qt6_descriptionsdir}/DeviceDiscoverySupportPrivate.json -%{_qt6_metatypesdir}/qt6devicediscoverysupportprivate_metatypes.json -%dir %{_qt6_libdir}/cmake/Qt6FbSupportPrivate -%{_qt6_libdir}/cmake/Qt6FbSupportPrivate/*.cmake +%{_qt6_libdir}/libQt6ExampleIcons.a +%{_qt6_libdir}/libQt6ExampleIcons.prl %{_qt6_headerdir}/QtFbSupport %{_qt6_libdir}/libQt6FbSupport.*a %{_qt6_libdir}/libQt6FbSupport.prl -%{_qt6_descriptionsdir}/FbSupportPrivate.json -%{_qt6_metatypesdir}/qt6fbsupportprivate_metatypes.json -%dir %{_qt6_libdir}/cmake/Qt6InputSupportPrivate -%{_qt6_libdir}/cmake/Qt6InputSupportPrivate/*.cmake -%{_qt6_headerdir}/QtInputSupport %{_qt6_libdir}/libQt6InputSupport.*a %{_qt6_libdir}/libQt6InputSupport.prl -%{_qt6_descriptionsdir}/InputSupportPrivate.json -%{_qt6_metatypesdir}/qt6inputsupportprivate_metatypes.json -%dir %{_qt6_libdir}/cmake/Qt6KmsSupportPrivate -%{_qt6_libdir}/cmake/Qt6KmsSupportPrivate/*.cmake %{_qt6_headerdir}/QtKmsSupport %{_qt6_libdir}/libQt6KmsSupport.*a %{_qt6_libdir}/libQt6KmsSupport.prl -%{_qt6_descriptionsdir}/KmsSupportPrivate.json -%{_qt6_metatypesdir}/qt6kmssupportprivate_metatypes.json - %if 0%{?examples} %files examples %{_qt6_examplesdir}/ @@ -910,8 +790,6 @@ make check -k ||: %{_qt6_libdir}/libQt6OpenGL.so.6* %{_qt6_libdir}/libQt6OpenGLWidgets.so.6* %{_qt6_libdir}/libQt6PrintSupport.so.6* -%{_qt6_libdir}/libQt6WaylandClient.so.6* -%{_qt6_libdir}/libQt6WlShellIntegration.so.6* %{_qt6_libdir}/libQt6Widgets.so.6* %{_qt6_libdir}/libQt6XcbQpa.so.6* # Generic @@ -943,189 +821,27 @@ make check -k ||: %{_qt6_plugindir}/egldeviceintegrations/libqeglfs-x11-integration.so %{_qt6_plugindir}/egldeviceintegrations/libqeglfs-kms-egldevice-integration.so %{_qt6_plugindir}/egldeviceintegrations/libqeglfs-emu-integration.so -%dir %{_qt6_plugindir}/xcbglintegrations/ %{_qt6_plugindir}/xcbglintegrations/libqxcb-egl-integration.so %endif # Platforms %{_qt6_plugindir}/platforms/libqlinuxfb.so %{_qt6_plugindir}/platforms/libqminimal.so %{_qt6_plugindir}/platforms/libqoffscreen.so +%{_qt6_plugindir}/platforms/libqxcb.so %{_qt6_plugindir}/platforms/libqvnc.so %{_qt6_plugindir}/platforms/libqvkkhrdisplay.so -%{_qt6_plugindir}/platforms/libqwayland.so -%{_qt6_plugindir}/platforms/libqxcb.so %{_qt6_plugindir}/xcbglintegrations/libqxcb-glx-integration.so -%{_qt6_plugindir}/printsupport/libcupsprintersupport.so # Platformthemes %{_qt6_plugindir}/platformthemes/libqxdgdesktopportal.so %{_qt6_plugindir}/platformthemes/libqgtk3.so -# Wayland plugins and protocols -%{_qt6_plugindir}/wayland-decoration-client/ -%{_qt6_plugindir}/wayland-graphics-integration-client -%{_qt6_plugindir}/wayland-shell-integration -%{_qt6_datadir}/wayland/extensions/ -%{_qt6_datadir}/wayland/protocols/ +%{_qt6_plugindir}/printsupport/libcupsprintersupport.so + %changelog -* Mon Dec 22 2025 Jan Grulich - 6.10.1-3 -- Fix crash in QWaylandShmBackingStore::scroll() - -* Mon Dec 08 2025 Jan Grulich - 6.10.1-2 -- Re-add wayland fixes for mouse scrolling - -* Thu Nov 20 2025 Jan Grulich - 6.10.1-1 -- 6.10.1 - -* Mon Nov 10 2025 Jan Grulich - 6.10.0-3 -- Backport wayland fixes for mouse scrolling - -* Wed Oct 29 2025 Jan Grulich - 6.10.0-2 -- Backport: Wayland - convey preference for server side decorations - -* Tue Oct 07 2025 Jan Grulich - 6.10.0-1 -- 6.10.0 - -* Tue Sep 30 2025 Gwyn Ciesla - 6.10.0~rc-2 -- Firebird 5 rebuild - -* Thu Sep 25 2025 Jan Grulich - 6.10.0~rc-1 -- 6.10.0 RC - -* Thu Aug 28 2025 Jan Grulich - 6.9.2-1 -- 6.9.2 - -* Tue Aug 05 2025 František Zatloukal - 6.9.1-4 -- Rebuilt for icu 77.1 - -* Mon Jul 28 2025 Adam Williamson - 6.9.1-3 -- Adjust for https://fedoraproject.org/wiki/Changes/dropingOfCertPemFile removals - -* Fri Jul 25 2025 Fedora Release Engineering - 6.9.1-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild - -* Mon Jun 02 2025 Jan Grulich - 6.9.1-1 -- 6.9.1 - -* Mon Apr 28 2025 Jan Grulich - 6.9.0-2 -- Fix possible crash in FontConfig database - -* Wed Apr 02 2025 Jan Grulich - 6.9.0-1 -- 6.9.0 - -* Fri Mar 21 2025 Jan Grulich - 6.9.0-1 -- 6.9.0 RC - -* Thu Feb 13 2025 Jan Grulich - 6.8.2-3 -- Fix rendering of combined emojis - -* Thu Feb 06 2025 Jan Grulich - 6.8.2-2 -- Backport recommended fixes for Qt 6.8.2 - -* Fri Jan 31 2025 Jan Grulich - 6.8.2-1 -- 6.8.2 - -* Thu Jan 16 2025 Jan Grulich - 6.8.1-11 -- Backport additional fixes for emoji support - -* Mon Jan 13 2025 Jan Grulich - 6.8.1-10 -- Fix directory ownership for 3rdparty cmake plugins - -* Thu Jan 09 2025 Jan Grulich - 6.8.1-9 -- Fix directory ownership - Resolves: rhbz#2292582 - -* Wed Jan 08 2025 Jan Grulich - 6.8.1-8 -- Install CMake modules for plugins - -* Tue Dec 17 2024 Jan Grulich - 6.8.1-7 -- Fix QGnomePlatform obsolets - -* Mon Dec 16 2024 Jan Grulich - 6.8.1-6 -- Backport additional fixes for emoji support - -* Tue Dec 10 2024 Jan Grulich - 6.8.1-5 -- Obsolete QGnomePlatform and AdwaitaQt - -* Sat Dec 07 2024 Jan Grulich - 6.8.1-4 -- Move all mkspecs to -devel - -* Thu Dec 05 2024 Jan Grulich - 6.8.1-3 -- Move more stuff into -private-devel - -* Tue Dec 03 2024 Jan Grulich - 6.8.1-2 -- Do not install ExamplesAssetDownloader - -* Thu Nov 28 2024 Jan Grulich - 6.8.1-1 -- 6.8.1 - -* Mon Oct 21 2024 Jan Grulich - 6.8.0-4 -- Backport - a11y atspi: Watch for enabled status change - -* Wed Oct 16 2024 Jan Grulich - 6.8.0-3 -- QtPrintSupport: make cups optional target - -* Wed Oct 09 2024 Jan Grulich - 6.8.0-1 -- Backport fix for QAbstractItemModel (kdebz#493116) - -* Wed Oct 09 2024 Jan Grulich - 6.8.0-1 -- 6.8.0 - -* Wed Sep 04 2024 Jan Grulich - 6.7.2-6 -- Backport - QWidget: store initialScreen as QPointer - -* Fri Jul 19 2024 Fedora Release Engineering - 6.7.2-5 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild - -* Mon Jul 15 2024 Jan Grulich - 6.7.2-4 -- Use qt6-filesystem - -* Mon Jul 08 2024 Jan Grulich - 6.7.2-3 +* Mon Jul 08 2024 Jan Grulich - 6.6.2-1 - HTTP2: Delay any communication until encrypted() can be responded to Resolves: CVE-2024-39936 -* Wed Jul 03 2024 Jan Grulich - 6.7.2-2 -- Revert: Consider versioned targets when checking the existens in - __qt_internal_walk_libs - -* Mon Jul 01 2024 Jan Grulich - 6.7.2-1 -- 6.7.2 - -* Tue May 21 2024 Jan Grulich - 6.7.1-2 -- Use only major.minor version for private api tag - -* Tue May 21 2024 Jan Grulich - 6.7.1-1 -- 6.7.1 - -* Tue May 07 2024 Jan Grulich - 6.7.0-5 -- QGtk3Theme: Add support for xdg-desktop-portal to get color scheme - -* Wed Apr 24 2024 Jan Grulich - 6.7.0-4 -- Use bundled double-conversion in RHEL builds - -* Fri Apr 12 2024 Jan Grulich - 6.7.0-3 -- Rebuild (gcc rhbz#2272758) - -* Mon Apr 08 2024 Jan Grulich - 6.7.0-2 -- Upstream backport: Use ifdef instead of if for __cpp_lib_span - -* Tue Apr 02 2024 Jan Grulich - 6.7.0-1 -- 6.7.0 - -* Sat Mar 09 2024 Alessandro Astone - 6.6.2-6 -- Move /usr/bin/qtpaths-qt6 to main package - -* Fri Mar 01 2024 David Abdurachmanov - 6.6.2-5 -- Disable SSE2 on riscv64 - -* Fri Feb 23 2024 Neal Gompa - 6.6.2-4 -- Use wlheadless-run for tests instead of xvfb-run - -* Mon Feb 19 2024 Jan Grulich - 6.6.2-3 -- Examples: also install source files - -* Mon Feb 19 2024 Jan Grulich - 6.6.2-2 -- Examples: also install source files - * Thu Feb 15 2024 Jan Grulich - 6.6.2-1 - 6.6.2 @@ -1199,7 +915,7 @@ make check -k ||: * Fri Apr 7 2023 Marie Loise Nolden - 6.5.0-2 - fix xcb plugin with new dependency xcb-cursor instead of Xcursor introduction with qt 6.5, add firebird sql plugin cleanly, clean up spec file - + * Mon Apr 03 2023 Jan Grulich - 6.5.0-1 - 6.5.0 diff --git a/qtbase-cache-emoji-font.patch b/qtbase-cache-emoji-font.patch new file mode 100644 index 0000000..2ec9a05 --- /dev/null +++ b/qtbase-cache-emoji-font.patch @@ -0,0 +1,85 @@ +diff --git a/src/gui/text/unix/qfontconfigdatabase.cpp b/src/gui/text/unix/qfontconfigdatabase.cpp +index 474644b8..f61e6e83 100644 +--- a/src/gui/text/unix/qfontconfigdatabase.cpp ++++ b/src/gui/text/unix/qfontconfigdatabase.cpp +@@ -592,6 +592,7 @@ void QFontconfigDatabase::populateFontDatabase() + ++f; + } + ++ cacheEmojiFontFamily(); + //QPA has very lazy population of the font db. We want it to be initialized when + //QApplication is constructed, so that the population procedure can do something like this to + //set the default font +@@ -735,6 +736,9 @@ QStringList QFontconfigDatabase::fallbacksForFamily(const QString &family, QFont + if (!pattern) + return fallbackFamilies; + ++ if (!m_cacheEmojiFontFamily.isEmpty()) ++ fallbackFamilies << m_cacheEmojiFontFamily; ++ + FcValue value; + value.type = FcTypeString; + const QByteArray cs = family.toUtf8(); +@@ -1016,4 +1020,47 @@ void QFontconfigDatabase::setupFontEngine(QFontEngineFT *engine, const QFontDef + engine->glyphFormat = format; + } + ++void QFontconfigDatabase::cacheEmojiFontFamily() ++{ ++ FcPattern *pattern; ++ pattern = FcPatternCreate(); ++ ++ FcValue value; ++ value.type = FcTypeString; ++ value.u.s = (const FcChar8 *)"emoji"; ++ FcPatternAdd(pattern,FC_FAMILY,value,true); ++ ++ FcLangSet *ls = FcLangSetCreate(); ++ FcLangSetAdd(ls, (const FcChar8*)"und-zsye"); ++ FcPatternAddLangSet(pattern, FC_LANG, ls); ++ ++ FcConfigSubstitute(nullptr, pattern, FcMatchPattern); ++ FcDefaultSubstitute(pattern); ++ ++ FcResult result = FcResultMatch; ++ FcFontSet *fontSet = FcFontSort(nullptr,pattern,FcTrue,nullptr,&result); ++ FcPatternDestroy(pattern); ++ ++ if (fontSet) { ++ for (int i = 0; i < fontSet->nfont; i++) { ++ FcChar8 *value = nullptr; ++ if (FcPatternGetString(fontSet->fonts[i], FC_FAMILY, 0, &value) != FcResultMatch) ++ continue; ++ ++ FcLangSet *rls = nullptr; ++ if (FcPatternGetLangSet(fontSet->fonts[i], FC_LANG, 0, &rls) != FcResultMatch) ++ continue; ++ ++ if (!FcLangSetContains(rls, ls)) ++ continue; ++ ++ m_cacheEmojiFontFamily = QString::fromUtf8((const char *)value); ++ break; ++ } ++ FcFontSetDestroy(fontSet); ++ } ++ ++ FcLangSetDestroy(ls); ++} ++ + QT_END_NAMESPACE +diff --git a/src/gui/text/unix/qfontconfigdatabase_p.h b/src/gui/text/unix/qfontconfigdatabase_p.h +index cf15306e..90b94087 100644 +--- a/src/gui/text/unix/qfontconfigdatabase_p.h ++++ b/src/gui/text/unix/qfontconfigdatabase_p.h +@@ -37,7 +37,10 @@ public: + QFont defaultFont() const override; + + private: ++ void cacheEmojiFontFamily(); + void setupFontEngine(QFontEngineFT *engine, const QFontDef &fontDef) const; ++ ++ QString m_cacheEmojiFontFamily; + }; + + QT_END_NAMESPACE diff --git a/qtbase-tell-the-truth-about-private-API.patch b/qtbase-tell-the-truth-about-private-API.patch new file mode 100644 index 0000000..fd2ac7a --- /dev/null +++ b/qtbase-tell-the-truth-about-private-API.patch @@ -0,0 +1,28 @@ +From 25e78cce15fdf737cc48ed5d7683ad1d01b55621 Mon Sep 17 00:00:00 2001 +From: Christophe Giboudeaux +Date: Sun, 20 Sep 2020 09:57:22 +0200 +Subject: [PATCH] Tell the truth about private API + +Mark private API with symbols only for the current patch release + +This change is a port of the libqt5-qtbase patch which was +added during the Qt 5.6 cycle. +--- + cmake/QtFlagHandlingHelpers.cmake | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/cmake/QtFlagHandlingHelpers.cmake b/cmake/QtFlagHandlingHelpers.cmake +index d8597326cc..f9da7b2171 100644 +--- a/cmake/QtFlagHandlingHelpers.cmake ++++ b/cmake/QtFlagHandlingHelpers.cmake +@@ -23,7 +23,7 @@ function(qt_internal_add_linker_version_script target) + endif() + + if(TEST_ld_version_script) +- set(contents "Qt_${PROJECT_VERSION_MAJOR}_PRIVATE_API {\n qt_private_api_tag*;\n") ++ set(contents "Qt_${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}_PRIVATE_API {\n qt_private_api_tag*;\n") + if(arg_PRIVATE_HEADERS) + foreach(ph ${arg_PRIVATE_HEADERS}) + string(APPEND contents " @FILE:${ph}@\n") +-- +2.40.0 diff --git a/qtbase-use-only-major-minor-for-private-api-tag.patch b/qtbase-use-only-major-minor-for-private-api-tag.patch deleted file mode 100644 index 54e38a3..0000000 --- a/qtbase-use-only-major-minor-for-private-api-tag.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff --git a/cmake/QtFlagHandlingHelpers.cmake b/cmake/QtFlagHandlingHelpers.cmake -index 6a62b85c..1fc1f88d 100644 ---- a/cmake/QtFlagHandlingHelpers.cmake -+++ b/cmake/QtFlagHandlingHelpers.cmake -@@ -71,7 +71,7 @@ function(qt_internal_add_linker_version_script target) - - string(APPEND contents "\n};\nQt_${PROJECT_VERSION_MAJOR}") - if(QT_FEATURE_elf_private_full_version) -- string(APPEND contents ".${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}") -+ string(APPEND contents ".${PROJECT_VERSION_MINOR}") - endif() - string(APPEND contents "_PRIVATE_API { qt_private_api_tag*;\n") - if(arg_PRIVATE_HEADERS) diff --git a/qtbase-wayland-compress-high-frequency-mouse-events.patch b/qtbase-wayland-compress-high-frequency-mouse-events.patch deleted file mode 100644 index e33e22a..0000000 --- a/qtbase-wayland-compress-high-frequency-mouse-events.patch +++ /dev/null @@ -1,174 +0,0 @@ -From 095759818854e5a011aa8f859e566bbc6368ab76 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?B=C5=82a=C5=BCej=20Szczygie=C5=82?= -Date: Sun, 27 Jul 2025 00:50:00 +0200 -Subject: [PATCH] wayland: Compress high frequency mouse events -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add support for Qt::AA_CompressHighFrequencyEvents on Wayland. - -The highest USB HID polling rate is 8 kHz (125 μs). Most mice use lower -polling rate [125 Hz - 1000 Hz]. Reject all events faster than 100 μs, -because it definitely means the application main thread is freezed by -the long operation and events are delivered one after another from the -queue. Since now we rely on the 0 ms timer to deliver the last pending -event when application main thread is no longer freezed. - -Pick-to: 6.10 -Task-number: QTBUG-138706 -Change-Id: Ie9d539e233c5551b1756d599b65495571e195f9d -Reviewed-by: David Edmundson ---- - src/corelib/global/qnamespace.qdoc | 1 + - .../platforms/wayland/qwaylandinputdevice.cpp | 38 +++++++++++++++++++ - .../platforms/wayland/qwaylandinputdevice_p.h | 12 ++++++ - .../platforms/wayland/qwaylandintegration.cpp | 2 + - tests/auto/wayland/client/tst_client.cpp | 2 + - 5 files changed, 55 insertions(+) - -diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc -index c845cfa7..f463d736 100644 ---- a/src/corelib/global/qnamespace.qdoc -+++ b/src/corelib/global/qnamespace.qdoc -@@ -227,6 +227,7 @@ - application later. - On Windows 8 and above the default value is also true, but it only applies - to touch events. Mouse and window events remain unaffected by this flag. -+ On Wayland the default value is also true, but it only applies to mouse events. - On other platforms, the default is false. - (In the future, the compression feature may be implemented across platforms.) - You can test the attribute to see whether compression is enabled. -diff --git a/src/plugins/platforms/wayland/qwaylandinputdevice.cpp b/src/plugins/platforms/wayland/qwaylandinputdevice.cpp -index 170e80f8..45c78765 100644 ---- a/src/plugins/platforms/wayland/qwaylandinputdevice.cpp -+++ b/src/plugins/platforms/wayland/qwaylandinputdevice.cpp -@@ -63,6 +63,34 @@ Q_LOGGING_CATEGORY(lcQpaWaylandInput, "qt.qpa.wayland.input"); - // reasonable number of them. As of 2021 most touchscreen panels support 10 concurrent touchpoints. - static const int MaxTouchPoints = 10; - -+QWaylandEventCompressionPrivate::QWaylandEventCompressionPrivate() -+{ -+ timeElapsed.start(); -+ delayTimer.setSingleShot(true); -+} -+ -+bool QWaylandEventCompressionPrivate::compressEvent() -+{ -+ using namespace std::chrono_literals; -+ -+ if (!QCoreApplication::testAttribute(Qt::AA_CompressHighFrequencyEvents)) -+ return false; -+ -+ const auto elapsed = timeElapsed.durationElapsed(); -+ timeElapsed.start(); -+ if (elapsed < 100us || delayTimer.isActive()) -+ { -+ // The highest USB HID polling rate is 8 kHz (125 μs). Most mice use lowe polling rate [125 Hz - 1000 Hz]. -+ // Reject all events faster than 100 μs, because it definitely means the application main thread is -+ // freezed by long operation and events are delivered one after another from the queue. Since now we rely -+ // on the 0 ms timer to deliver the last pending event when application main thread is no longer freezed. -+ delayTimer.start(0); -+ return true; -+ } -+ -+ return false; -+} -+ - QWaylandInputDevice::Keyboard::Keyboard(QWaylandInputDevice *p) - : mParent(p) - { -@@ -140,6 +168,8 @@ QWaylandInputDevice::Pointer::Pointer(QWaylandInputDevice *seat) - cursorTimerCallback(); - }); - #endif -+ -+ mEventCompression.delayTimer.callOnTimeout(this, &QWaylandInputDevice::Pointer::flushFrameEvent); - } - - QWaylandInputDevice::Pointer::~Pointer() -@@ -922,6 +952,11 @@ void QWaylandInputDevice::Pointer::pointer_axis(uint32_t time, uint32_t axis, in - - void QWaylandInputDevice::Pointer::pointer_frame() - { -+ if (mEventCompression.compressEvent()) { -+ qCDebug(lcQpaWaylandInput) << "compressed pointer_frame event"; -+ return; -+ } -+ - flushFrameEvent(); - } - -@@ -1051,6 +1086,7 @@ void QWaylandInputDevice::Pointer::setFrameEvent(QWaylandPointerEvent *event) - flushFrameEvent(); - } - -+ delete mFrameData.event; - mFrameData.event = event; - - if (version() < WL_POINTER_FRAME_SINCE_VERSION) { -@@ -1170,6 +1206,8 @@ void QWaylandInputDevice::Pointer::flushScrollEvent() - - void QWaylandInputDevice::Pointer::flushFrameEvent() - { -+ mEventCompression.delayTimer.stop(); -+ - if (auto *event = mFrameData.event) { - if (auto window = event->surface) { - window->handleMouse(mParent, *event); -diff --git a/src/plugins/platforms/wayland/qwaylandinputdevice_p.h b/src/plugins/platforms/wayland/qwaylandinputdevice_p.h -index bcaf0258..0b24999e 100644 ---- a/src/plugins/platforms/wayland/qwaylandinputdevice_p.h -+++ b/src/plugins/platforms/wayland/qwaylandinputdevice_p.h -@@ -75,6 +75,16 @@ class CursorSurface; - - Q_DECLARE_LOGGING_CATEGORY(lcQpaWaylandInput); - -+struct QWaylandEventCompressionPrivate -+{ -+ QWaylandEventCompressionPrivate(); -+ -+ bool compressEvent(); -+ -+ QElapsedTimer timeElapsed; -+ QTimer delayTimer; -+}; -+ - class Q_WAYLANDCLIENT_EXPORT QWaylandInputDevice - : public QObject - , public QtWayland::wl_seat -@@ -381,6 +391,8 @@ public: - bool mScrollBeginSent = false; - QPointF mScrollDeltaRemainder; - -+ QWaylandEventCompressionPrivate mEventCompression; -+ - void setFrameEvent(QWaylandPointerEvent *event); - void flushScrollEvent(); - void flushFrameEvent(); -diff --git a/src/plugins/platforms/wayland/qwaylandintegration.cpp b/src/plugins/platforms/wayland/qwaylandintegration.cpp -index 669d47ee..fc869de6 100644 ---- a/src/plugins/platforms/wayland/qwaylandintegration.cpp -+++ b/src/plugins/platforms/wayland/qwaylandintegration.cpp -@@ -87,6 +87,8 @@ QWaylandIntegration::QWaylandIntegration(const QString &platformName) - : mPlatformName(platformName), mFontDb(new QGenericUnixFontDatabase()) - #endif - { -+ QCoreApplication::setAttribute(Qt::AA_CompressHighFrequencyEvents); -+ - mDisplay.reset(new QWaylandDisplay(this)); - mPlatformServices.reset(new QWaylandPlatformServices(mDisplay.data())); - -diff --git a/tests/auto/wayland/client/tst_client.cpp b/tests/auto/wayland/client/tst_client.cpp -index 04400e3f..09ac4f7f 100644 ---- a/tests/auto/wayland/client/tst_client.cpp -+++ b/tests/auto/wayland/client/tst_client.cpp -@@ -276,6 +276,8 @@ void tst_WaylandClient::events() - exec([&] { - pointer()->sendEnter(s, window.frameOffset() + mousePressPos); - pointer()->sendFrame(client()); -+ pointer()->sendMotion(client(), window.frameOffset() + mousePressPos / 2); -+ pointer()->sendFrame(client()); - pointer()->sendMotion(client(), window.frameOffset() + mousePressPos); - pointer()->sendFrame(client()); - pointer()->sendButton(client(), BTN_LEFT, Pointer::button_state_pressed); diff --git a/qtbase-wayland-convey-preference-for-server-side-decorations.patch b/qtbase-wayland-convey-preference-for-server-side-decorations.patch deleted file mode 100644 index 0a5b232..0000000 --- a/qtbase-wayland-convey-preference-for-server-side-decorations.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 18550cd9ad04913d50abfc88a6048b7cfaf80687 Mon Sep 17 00:00:00 2001 -From: Igor Khanin -Date: Mon, 13 Oct 2025 14:26:39 +0300 -Subject: [PATCH] wayland: Convey preference for server side decorations - -As discussed in the mailing list, Qt applications generally expect top -level windows to be decorated by the windowing system - unless -explicitly requested by the developer by marking a window as frameless. -Furthermore, Qt's client side decorations for Wayland were only really -intended as a fallback. - -However until now the Wayland xdg-shell integration conveyed to the -compositor (if it supports decorations negotiations) that it didn't -care whose responsibility it was to draw window decorations. This did -not matter under KWin, which resolves such cases in favor of SSDs - but -does matter under other SSD-capable compositors like cosmic-comp (which -considers SSDs to be the fallback option). - -This changes the xdg-shell integration code to be explicit about -requesting SSDs. - -[ChangeLog][QtWaylandClient][Important Behavior Changes] The Wayland -XDG shell integration now requests server side decorations with -compositors supporting the zxdg_decoration_manager_v1 protocol. - -Change-Id: Ia025b1f6ff17248a5710f981a0cecd90c47b6cd8 -Reviewed-by: David Edmundson ---- - -diff --git a/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp b/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp -index a1a173f..8386b65 100644 ---- a/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp -+++ b/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp -@@ -201,7 +201,7 @@ - delete m_decoration; - m_decoration = nullptr; - } else { -- m_decoration->unsetMode(); -+ m_decoration->requestMode(QWaylandXdgToplevelDecorationV1::mode_server_side); - } - } - } -diff --git a/tests/auto/wayland/xdgdecorationv1/tst_xdgdecorationv1.cpp b/tests/auto/wayland/xdgdecorationv1/tst_xdgdecorationv1.cpp -index 5ee8569..65ac08f 100644 ---- a/tests/auto/wayland/xdgdecorationv1/tst_xdgdecorationv1.cpp -+++ b/tests/auto/wayland/xdgdecorationv1/tst_xdgdecorationv1.cpp -@@ -149,7 +149,7 @@ - QVERIFY(window.frameMargins().isNull()); - - QCOMPOSITOR_TRY_VERIFY(xdgToplevel()); -- QCOMPOSITOR_TRY_VERIFY(toplevelDecoration()->m_unsetModeRequested); -+ QCOMPOSITOR_TRY_VERIFY(toplevelDecoration()->m_requestedMode == XdgToplevelDecorationV1::mode_server_side); - QVERIFY(window.frameMargins().isNull()); // We're still waiting for a configure - exec([&] { - toplevelDecoration()->sendConfigure(XdgToplevelDecorationV1::mode_client_side); diff --git a/qtbase-wayland-enable-event-compression-and-fix-scroll-end-event.patch b/qtbase-wayland-enable-event-compression-and-fix-scroll-end-event.patch deleted file mode 100644 index 80e0009..0000000 --- a/qtbase-wayland-enable-event-compression-and-fix-scroll-end-event.patch +++ /dev/null @@ -1,235 +0,0 @@ -From 9dd0d936d6691904a4bb212dcf48999a5228b84f Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?B=C5=82a=C5=BCej=20Szczygie=C5=82?= -Date: Thu, 7 Aug 2025 15:42:55 +0200 -Subject: [PATCH] wayland: Enable event compression and fix scroll end event - -We have to deliver the scroll end event in order with other scroll -events, so move scroll end event logic into flushScrollEvent(). - -Track the target scroll window on scroll begin and check whether we -have a target window to prevent a crash. - -Also we can't clear the scroll delta when scroll end event arrives, -because the event compression relies on this value. - -Use scoped pointer for frame event to simplify code and make sure it's -deleted in destructor. - -Amends 095759818854e5a011aa8f859e566bbc6368ab76 -Updates 789681872fb62450fc78d1a06472a40d970a8d57 - -Change-Id: Ifb149c8fde1286b60439be0dab16b1df65279ea8 -Reviewed-by: David Edmundson ---- - .../platforms/wayland/qwaylandinputdevice.cpp | 98 ++++++++++--------- - .../platforms/wayland/qwaylandinputdevice_p.h | 6 +- - .../platforms/wayland/qwaylandintegration.cpp | 2 + - 3 files changed, 61 insertions(+), 45 deletions(-) - -diff --git a/src/plugins/platforms/wayland/qwaylandinputdevice.cpp b/src/plugins/platforms/wayland/qwaylandinputdevice.cpp -index 7fcda34c57ca..6ce43714a35f 100644 ---- a/src/plugins/platforms/wayland/qwaylandinputdevice.cpp -+++ b/src/plugins/platforms/wayland/qwaylandinputdevice.cpp -@@ -935,10 +935,7 @@ void QWaylandInputDevice::Pointer::pointer_axis(uint32_t time, uint32_t axis, in - - mParent->mTime = time; - -- if (version() < WL_POINTER_FRAME_SINCE_VERSION) { -- qCDebug(lcQpaWaylandInput) << "Flushing new event; no frame event in this version"; -- flushFrameEvent(); -- } -+ maybePointerFrame(); - } - - void QWaylandInputDevice::Pointer::pointer_frame() -@@ -978,11 +975,9 @@ void QWaylandInputDevice::Pointer::pointer_axis_stop(uint32_t time, uint32_t axi - switch (axis) { - case axis_vertical_scroll: - qCDebug(lcQpaWaylandInput) << "Received vertical wl_pointer.axis_stop"; -- mFrameData.delta.setY(0); //TODO: what's the point of doing this? - break; - case axis_horizontal_scroll: - qCDebug(lcQpaWaylandInput) << "Received horizontal wl_pointer.axis_stop"; -- mFrameData.delta.setX(0); - break; - default: - qCWarning(lcQpaWaylandInput) << "wl_pointer.axis_stop: Unknown axis: " << axis -@@ -990,25 +985,7 @@ void QWaylandInputDevice::Pointer::pointer_axis_stop(uint32_t time, uint32_t axi - return; - } - -- // May receive axis_stop for events we haven't sent a ScrollBegin for because -- // most axis_sources do not mandate an axis_stop event to be sent. -- if (!mScrollBeginSent) { -- // TODO: For now, we just ignore these events, but we could perhaps take this as an -- // indication that this compositor will in fact send axis_stop events for these sources -- // and send a ScrollBegin the next time an axis_source event with this type is encountered. -- return; -- } -- -- QWaylandWindow *target = QWaylandWindow::mouseGrab(); -- if (!target) -- target = focusWindow(); -- Qt::KeyboardModifiers mods = mParent->modifiers(); -- const bool inverted = mFrameData.verticalAxisInverted || mFrameData.horizontalAxisInverted; -- WheelEvent wheelEvent(focusWindow(), Qt::ScrollEnd, mParent->mTime, mSurfacePos, mGlobalPos, -- QPoint(), QPoint(), Qt::MouseEventNotSynthesized, mods, inverted); -- target->handleMouse(mParent, wheelEvent); -- mScrollBeginSent = false; -- mScrollDeltaRemainder = QPointF(); -+ mScrollEnd = true; - } - - void QWaylandInputDevice::Pointer::pointer_axis_discrete(uint32_t axis, int32_t value) -@@ -1069,6 +1046,14 @@ void QWaylandInputDevice::Pointer::pointer_axis_relative_direction(uint32_t axis - } - } - -+inline void QWaylandInputDevice::Pointer::maybePointerFrame() -+{ -+ if (version() < WL_POINTER_FRAME_SINCE_VERSION) { -+ qCDebug(lcQpaWaylandInput) << "Flushing new event; no frame event in this version"; -+ pointer_frame(); -+ } -+} -+ - void QWaylandInputDevice::Pointer::setFrameEvent(QWaylandPointerEvent *event) - { - qCDebug(lcQpaWaylandInput) << "Setting frame event " << event->type; -@@ -1077,13 +1062,9 @@ void QWaylandInputDevice::Pointer::setFrameEvent(QWaylandPointerEvent *event) - flushFrameEvent(); - } - -- delete mFrameData.event; -- mFrameData.event = event; -+ mFrameData.event.reset(event); - -- if (version() < WL_POINTER_FRAME_SINCE_VERSION) { -- qCDebug(lcQpaWaylandInput) << "Flushing new event; no frame event in this version"; -- flushFrameEvent(); -- } -+ maybePointerFrame(); - } - - void QWaylandInputDevice::Pointer::FrameData::resetScrollData() -@@ -1163,11 +1144,24 @@ void QWaylandInputDevice::Pointer::flushScrollEvent() - { - QPoint angleDelta = mFrameData.angleDelta(); - -+ // The wayland protocol has separate horizontal and vertical axes, Qt has just the one inverted flag -+ // Pragmatically it should't come up -+ const bool inverted = mFrameData.verticalAxisInverted || mFrameData.horizontalAxisInverted; -+ - // Angle delta is required for Qt wheel events, so don't try to send events if it's zero - if (!angleDelta.isNull()) { -- QWaylandWindow *target = QWaylandWindow::mouseGrab(); -- if (!target) -- target = focusWindow(); -+ QWaylandWindow *target = mScrollTarget; -+ if (!mScrollBeginSent) { -+ if (!target) -+ target = QWaylandWindow::mouseGrab(); -+ if (!target) -+ target = focusWindow(); -+ } -+ if (!target) { -+ qCDebug(lcQpaWaylandInput) << "Flushing scroll event aborted - no scroll target"; -+ mFrameData.resetScrollData(); -+ return; -+ } - - if (isDefinitelyTerminated(mFrameData.axisSource) && !mScrollBeginSent) { - qCDebug(lcQpaWaylandInput) << "Flushing scroll event sending ScrollBegin"; -@@ -1177,21 +1171,38 @@ void QWaylandInputDevice::Pointer::flushScrollEvent() - mParent->modifiers(), false)); - mScrollBeginSent = true; - mScrollDeltaRemainder = QPointF(); -+ mScrollTarget = target; - } - - Qt::ScrollPhase phase = mScrollBeginSent ? Qt::ScrollUpdate : Qt::NoScrollPhase; - QPoint pixelDelta = mFrameData.pixelDeltaAndError(&mScrollDeltaRemainder); -- Qt::MouseEventSource source = mFrameData.wheelEventSource(); -- -- -- // The wayland protocol has separate horizontal and vertical axes, Qt has just the one inverted flag -- // Pragmatically it should't come up -- const bool inverted = mFrameData.verticalAxisInverted || mFrameData.horizontalAxisInverted; - - qCDebug(lcQpaWaylandInput) << "Flushing scroll event" << phase << pixelDelta << angleDelta; - target->handleMouse(mParent, WheelEvent(focusWindow(), phase, mParent->mTime, mSurfacePos, mGlobalPos, -- pixelDelta, angleDelta, source, mParent->modifiers(), inverted)); -+ pixelDelta, angleDelta, mFrameData.wheelEventSource(), mParent->modifiers(), inverted)); -+ } -+ -+ if (mScrollEnd) { -+ if (mScrollBeginSent) { -+ if (auto target = mScrollTarget.get()) { -+ qCDebug(lcQpaWaylandInput) << "Flushing scroll end event"; -+ target->handleMouse(mParent, WheelEvent(focusWindow(), Qt::ScrollEnd, mParent->mTime, mSurfacePos, mGlobalPos, -+ QPoint(), QPoint(), mFrameData.wheelEventSource(), mParent->modifiers(), inverted)); -+ } -+ mScrollBeginSent = false; -+ mScrollDeltaRemainder = QPointF(); -+ } else { -+ // May receive axis_stop for events we haven't sent a ScrollBegin for because -+ // most axis_sources do not mandate an axis_stop event to be sent. -+ -+ // TODO: For now, we just ignore these events, but we could perhaps take this as an -+ // indication that this compositor will in fact send axis_stop events for these sources -+ // and send a ScrollBegin the next time an axis_source event with this type is encountered. -+ } -+ mScrollEnd = false; -+ mScrollTarget.clear(); - } -+ - mFrameData.resetScrollData(); - } - -@@ -1199,7 +1210,7 @@ void QWaylandInputDevice::Pointer::flushFrameEvent() - { - mEventCompression.delayTimer.stop(); - -- if (auto *event = mFrameData.event) { -+ if (auto *event = mFrameData.event.get()) { - if (auto window = event->surface) { - window->handleMouse(mParent, *event); - } else if (mFrameData.event->type == QEvent::MouseButtonRelease) { -@@ -1212,8 +1223,7 @@ void QWaylandInputDevice::Pointer::flushFrameEvent() - event->modifiers); // , Qt::MouseEventSource source = - // Qt::MouseEventNotSynthesized); - } -- delete mFrameData.event; -- mFrameData.event = nullptr; -+ mFrameData.event.reset(); - } - - //TODO: do modifiers get passed correctly here? -diff --git a/src/plugins/platforms/wayland/qwaylandinputdevice_p.h b/src/plugins/platforms/wayland/qwaylandinputdevice_p.h -index 533a10991e5e..aa2ccddbcdb8 100644 ---- a/src/plugins/platforms/wayland/qwaylandinputdevice_p.h -+++ b/src/plugins/platforms/wayland/qwaylandinputdevice_p.h -@@ -370,7 +370,7 @@ private Q_SLOTS: - Qt::MouseButton mLastButton = Qt::NoButton; - - struct FrameData { -- QWaylandPointerEvent *event = nullptr; -+ QScopedPointer event; - - QPointF delta; - QPoint delta120; -@@ -387,10 +387,14 @@ private Q_SLOTS: - } mFrameData; - - bool mScrollBeginSent = false; -+ bool mScrollEnd = false; - QPointF mScrollDeltaRemainder; -+ QPointer mScrollTarget; - - QWaylandEventCompressionPrivate mEventCompression; - -+ void maybePointerFrame(); -+ - void setFrameEvent(QWaylandPointerEvent *event); - void flushScrollEvent(); - void flushFrameEvent(); diff --git a/qtbase-wayland-fix-crash-in-qwaylandshmbackingstore-scroll.patch b/qtbase-wayland-fix-crash-in-qwaylandshmbackingstore-scroll.patch deleted file mode 100644 index 7881aba..0000000 --- a/qtbase-wayland-fix-crash-in-qwaylandshmbackingstore-scroll.patch +++ /dev/null @@ -1,39 +0,0 @@ -From c93008e4d06abb0072e0e5e57d84a4ae182ecfc0 Mon Sep 17 00:00:00 2001 -From: Błażej Szczygieł -Date: Tue, 21 Oct 2025 19:49:17 +0200 -Subject: [PATCH] wayland: Fix crash in QWaylandShmBackingStore::scroll() - -Fixes a crash when monitor is unplugged while scrolling. - -recreateBackBufferIfNeeded() calls getBuffer() which may set -mFrontBuffer to nullptr. - -Amends: 6f25f703fd37a900c139e14a33a4639502bfeae7 - -Task-number: QTBUG-139231 -Change-Id: Ia5bedce2a3f6580c722f73446de81a26d40ea2f4 -Reviewed-by: David Edmundson ---- - -diff --git a/src/plugins/platforms/wayland/qwaylandshmbackingstore.cpp b/src/plugins/platforms/wayland/qwaylandshmbackingstore.cpp -index b853db2..fa70b53 100644 ---- a/src/plugins/platforms/wayland/qwaylandshmbackingstore.cpp -+++ b/src/plugins/platforms/wayland/qwaylandshmbackingstore.cpp -@@ -229,7 +229,7 @@ - // Inspired by QCALayerBackingStore. - bool QWaylandShmBackingStore::scroll(const QRegion ®ion, int dx, int dy) - { -- if (Q_UNLIKELY(!mBackBuffer || !mFrontBuffer)) -+ if (Q_UNLIKELY(!mBackBuffer)) - return false; - - const qreal devicePixelRatio = waylandWindow()->scale(); -@@ -241,6 +241,8 @@ - return false; - - recreateBackBufferIfNeeded(); -+ if (!mFrontBuffer) -+ return false; - - const QPoint scrollDelta(dx, dy); - const QMargins margins = windowDecorationMargins(); diff --git a/qtbase-wayland-optimize-scroll-operations.patch b/qtbase-wayland-optimize-scroll-operations.patch deleted file mode 100644 index 9e7b52a..0000000 --- a/qtbase-wayland-optimize-scroll-operations.patch +++ /dev/null @@ -1,242 +0,0 @@ -From 6f25f703fd37a900c139e14a33a4639502bfeae7 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?B=C5=82a=C5=BCej=20Szczygie=C5=82?= -Date: Wed, 13 Aug 2025 00:48:08 +0200 -Subject: [PATCH] wayland: Optimize scroll operation -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Don't copy the dirty region in "recreateBackBufferIfNeeded()" in -"beginPaint()". Mark this region as non-dirty in the back buffer -and paint. Finalize the back buffer (copy remaining dirty region) -before flushing. This allows to optimize scrolling, we no longer -have to do a redundant dirty area copy. - -This matches the "QCALayerBackingStore" logic. - -Task-number: QTBUG-139231 -Change-Id: I6c19491fa8f093de9c9ce7624d8f9b65b0b722c5 -Reviewed-by: Tor Arne Vestbø -Reviewed-by: David Edmundson ---- - .../wayland/qwaylandshmbackingstore.cpp | 111 ++++++++++++------ - .../wayland/qwaylandshmbackingstore_p.h | 3 +- - 2 files changed, 74 insertions(+), 40 deletions(-) - -diff --git a/src/plugins/platforms/wayland/qwaylandshmbackingstore.cpp b/src/plugins/platforms/wayland/qwaylandshmbackingstore.cpp -index d8fc7b18ca34..591e5064ebd6 100644 ---- a/src/plugins/platforms/wayland/qwaylandshmbackingstore.cpp -+++ b/src/plugins/platforms/wayland/qwaylandshmbackingstore.cpp -@@ -159,6 +159,8 @@ QWaylandShmBackingStore::QWaylandShmBackingStore(QWindow *window, QWaylandDispla - // recreateBackBufferIfNeeded always resets mBackBuffer - if (mRequestedSize.isValid() && waylandWindow()) - recreateBackBufferIfNeeded(); -+ else -+ mBackBuffer = nullptr; - qDeleteAll(copy); - wl_event_queue_destroy(oldEventQueue); - }); -@@ -183,11 +185,15 @@ QPaintDevice *QWaylandShmBackingStore::paintDevice() - - void QWaylandShmBackingStore::updateDirtyStates(const QRegion ®ion) - { -- // Update dirty state of buffers based on what was painted. The back buffer will -- // not be dirty since we already painted on it, while other buffers will become dirty. -+ // Update dirty state of buffers based on what was painted. The back buffer will be -+ // less dirty, since we painted to it, while other buffers will become more dirty. -+ // This allows us to minimize copies between front and back buffers on swap in the -+ // cases where the painted region overlaps with the previous frame (front buffer). - for (QWaylandShmBuffer *b : std::as_const(mBuffers)) { - if (b != mBackBuffer) - b->dirtyRegion() += region; -+ else -+ b->dirtyRegion() -= region; - } - } - -@@ -198,7 +204,7 @@ void QWaylandShmBackingStore::beginPaint(const QRegion ®ion) - - const QMargins margins = windowDecorationMargins(); - const QRegion regionTranslated = region.translated(margins.left(), margins.top()); -- const bool bufferWasRecreated = recreateBackBufferIfNeeded(regionTranslated); -+ const bool bufferWasRecreated = recreateBackBufferIfNeeded(); - updateDirtyStates(regionTranslated); - - // Although undocumented, QBackingStore::beginPaint expects the painted region -@@ -223,7 +229,7 @@ void QWaylandShmBackingStore::endPaint() - // Inspired by QCALayerBackingStore. - bool QWaylandShmBackingStore::scroll(const QRegion ®ion, int dx, int dy) - { -- if (!mBackBuffer) -+ if (Q_UNLIKELY(!mBackBuffer || !mFrontBuffer)) - return false; - - const qreal devicePixelRatio = waylandWindow()->scale(); -@@ -236,19 +242,35 @@ bool QWaylandShmBackingStore::scroll(const QRegion ®ion, int dx, int dy) - - recreateBackBufferIfNeeded(); - -- QImage *backBufferImage = mBackBuffer->image(); -- - const QPoint scrollDelta(dx, dy); - const QMargins margins = windowDecorationMargins(); - const QRegion adjustedRegion = region.translated(margins.left(), margins.top()); - -- const QRect boundingRect = adjustedRegion.boundingRect(); -- const QPoint devicePixelDelta = scrollDelta * devicePixelRatio; -+ const QRegion inPlaceRegion = adjustedRegion - mBackBuffer->dirtyRegion(); -+ const QRegion frontBufferRegion = adjustedRegion - inPlaceRegion; -+ -+ if (!inPlaceRegion.isEmpty()) { -+ const QRect inPlaceBoundingRect = inPlaceRegion.boundingRect(); -+ const QPoint devicePixelDelta = scrollDelta * devicePixelRatio; -+ -+ qt_scrollRectInImage(*mBackBuffer->image(), -+ QRect(inPlaceBoundingRect.topLeft() * devicePixelRatio, -+ inPlaceBoundingRect.size() * devicePixelRatio), -+ devicePixelDelta); -+ } - -- qt_scrollRectInImage(*backBufferImage, -- QRect(boundingRect.topLeft() * devicePixelRatio, -- boundingRect.size() * devicePixelRatio), -- devicePixelDelta); -+ if (!frontBufferRegion.isEmpty()) { -+ QPainter painter(mBackBuffer->image()); -+ painter.setCompositionMode(QPainter::CompositionMode_Source); -+ painter.scale(qreal(1) / devicePixelRatio, qreal(1) / devicePixelRatio); -+ for (const QRect &rect : frontBufferRegion) { -+ QRect sourceRect(rect.topLeft() * devicePixelRatio, -+ rect.size() * devicePixelRatio); -+ QRect destinationRect((rect.topLeft() + scrollDelta) * devicePixelRatio, -+ rect.size() * devicePixelRatio); -+ painter.drawImage(destinationRect, *mFrontBuffer->image(), sourceRect); -+ } -+ } - - // We do not mark the source region as dirty, even though it technically has "moved". - // This matches the behavior of other backingstore implementations using qt_scrollRectInImage. -@@ -289,6 +311,8 @@ void QWaylandShmBackingStore::flush(QWindow *window, const QRegion ®ion, cons - if (windowDecoration() && windowDecoration()->isDirty()) - updateDecorations(); - -+ finalizeBackBuffer(); -+ - mFrontBuffer = mBackBuffer; - - QMargins margins = windowDecorationMargins(); -@@ -313,6 +337,8 @@ QWaylandShmBuffer *QWaylandShmBackingStore::getBuffer(const QSize &size, bool &b - mBuffers.removeAt(i); - if (mBackBuffer == buffer) - mBackBuffer = nullptr; -+ if (mFrontBuffer == buffer) -+ mFrontBuffer = nullptr; - delete buffer; - } - } -@@ -341,7 +367,7 @@ QWaylandShmBuffer *QWaylandShmBackingStore::getBuffer(const QSize &size, bool &b - return nullptr; - } - --bool QWaylandShmBackingStore::recreateBackBufferIfNeeded(const QRegion &nonDirtyRegion) -+bool QWaylandShmBackingStore::recreateBackBufferIfNeeded() - { - wl_display_dispatch_queue_pending(mDisplay->wl_display(), mEventQueue); - -@@ -375,30 +401,6 @@ bool QWaylandShmBackingStore::recreateBackBufferIfNeeded(const QRegion &nonDirty - 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 && oldSizeInBytes == newSizeInBytes) { -- const QRegion clipRegion = buffer->dirtyRegion() - nonDirtyRegion; -- const auto clipRects = clipRegion.rects(); -- if (!clipRects.empty()) { -- Q_ASSERT(mBackBuffer); -- const QImage *sourceImage = mBackBuffer->image(); -- QImage *targetImage = buffer->image(); -- -- QPainter painter(targetImage); -- painter.setCompositionMode(QPainter::CompositionMode_Source); -- const qreal targetDevicePixelRatio = painter.device()->devicePixelRatio(); -- for (const QRect &clipRect : clipRects) { // Iterate clip rects, because complicated clip region causes higher CPU usage -- if (clipRects.size() > 1) -- painter.save(); -- painter.setClipRect(clipRect); -- painter.scale(qreal(1) / targetDevicePixelRatio, qreal(1) / targetDevicePixelRatio); -- painter.drawImage(QRectF(QPointF(), targetImage->size()), *sourceImage, sourceImage->rect()); -- if (clipRects.size() > 1) -- painter.restore(); -- } -- } -- } -- - mBackBuffer = buffer; - - for (QWaylandShmBuffer *buffer : std::as_const(mBuffers)) { -@@ -412,11 +414,40 @@ bool QWaylandShmBackingStore::recreateBackBufferIfNeeded(const QRegion &nonDirty - if (windowDecoration() && window()->isVisible() && oldSizeInBytes != newSizeInBytes) - windowDecoration()->update(); - -- buffer->dirtyRegion() = QRegion(); -- - return bufferWasRecreated; - } - -+void QWaylandShmBackingStore::finalizeBackBuffer() -+{ -+ Q_ASSERT(mBackBuffer); -+ -+ const QRegion clipRegion = mBackBuffer->dirtyRegion(); -+ if (clipRegion.isEmpty()) -+ return; -+ -+ if (Q_UNLIKELY(!mFrontBuffer || mFrontBuffer == mBackBuffer)) -+ return; -+ -+ const QImage *sourceImage = mFrontBuffer->image(); -+ QImage *targetImage = mBackBuffer->image(); -+ -+ QPainter painter(targetImage); -+ painter.setCompositionMode(QPainter::CompositionMode_Source); -+ const qreal targetDevicePixelRatio = painter.device()->devicePixelRatio(); -+ const auto clipRects = clipRegion.rects(); -+ for (const QRect &clipRect : clipRects) { // Iterate clip rects, because complicated clip region causes higher CPU usage -+ if (clipRects.size() > 1) -+ painter.save(); -+ painter.setClipRect(clipRect); -+ painter.scale(qreal(1) / targetDevicePixelRatio, qreal(1) / targetDevicePixelRatio); -+ painter.drawImage(QRectF(QPointF(), targetImage->size()), *sourceImage, sourceImage->rect()); -+ if (clipRects.size() > 1) -+ painter.restore(); -+ } -+ -+ mBackBuffer->dirtyRegion() = QRegion(); -+} -+ - QImage *QWaylandShmBackingStore::entireSurface() const - { - return mBackBuffer->image(); -@@ -496,6 +527,8 @@ QImage QWaylandShmBackingStore::toImage() const - // instead of flush() for widgets that have renderToTexture children - // (QOpenGLWidget, QQuickWidget). - -+ const_cast(this)->finalizeBackBuffer(); -+ - return *contentSurface(); - } - #endif // opengl -diff --git a/src/plugins/platforms/wayland/qwaylandshmbackingstore_p.h b/src/plugins/platforms/wayland/qwaylandshmbackingstore_p.h -index efd80159e859..cfcafb283265 100644 ---- a/src/plugins/platforms/wayland/qwaylandshmbackingstore_p.h -+++ b/src/plugins/platforms/wayland/qwaylandshmbackingstore_p.h -@@ -73,7 +73,8 @@ class Q_WAYLANDCLIENT_EXPORT QWaylandShmBackingStore : public QPlatformBackingSt - QMargins windowDecorationMargins() const; - QImage *entireSurface() const; - QImage *contentSurface() const; -- bool recreateBackBufferIfNeeded(const QRegion &nonDirtyRegion = QRegion()); -+ bool recreateBackBufferIfNeeded(); -+ void finalizeBackBuffer(); - - QWaylandWindow *waylandWindow() const; - void iterateBuffer(); diff --git a/sources b/sources index a554569..cd120ad 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (qtbase-everywhere-src-6.10.1.tar.xz) = fd5dcdc59ec3b39e48563513ae438eb4540a28e72c46961295de2ccb08609289d477ef7e91aac0b8983f2d5b05b901b4f5be10eaca4ac4c6aa8cd598f37a228e +SHA512 (qtbase-everywhere-src-6.6.2.tar.xz) = ea343bcf269779a4e078ed8baddfbe6c5ec4a34275c7d72b3f3928da60feece2ddc9ce4a380c6536a4e1654b483cee8918f8ad3038904725d2dd1c653ae83ece