Compare commits
12 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
082bad2484 | ||
|
|
af0ef1e954 | ||
|
|
67c126dc18 | ||
|
|
2ff34253dc | ||
|
|
045b22d4d6 | ||
|
|
05ee0b98b4 | ||
|
|
07c9cbcba0 | ||
|
|
1646c99cab | ||
|
|
060d33bcdd | ||
|
|
362bc3dbd4 | ||
|
|
0e85496669 | ||
|
|
ed748d94e8 |
8 changed files with 859 additions and 35 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
|
@ -35,3 +35,7 @@
|
|||
/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
|
||||
|
|
|
|||
143
qt6-qtbase.spec
143
qt6-qtbase.spec
|
|
@ -41,12 +41,14 @@ BuildRequires: pkgconfig(libsystemd)
|
|||
#global tests 1
|
||||
|
||||
#global unstable 0
|
||||
%if 0%{?unstable}
|
||||
%global prerelease rc
|
||||
%endif
|
||||
|
||||
Name: qt6-qtbase
|
||||
Summary: Qt6 - QtBase components
|
||||
Version: 6.9.1
|
||||
Release: 1%{?dist}
|
||||
Version: 6.10.1
|
||||
Release: 3%{?dist}
|
||||
|
||||
License: LGPL-3.0-only OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
Url: http://qt-project.org/
|
||||
|
|
@ -96,6 +98,11 @@ Patch56: qtbase-mysql.patch
|
|||
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
|
||||
|
||||
# Do not check any files in %%{_qt6_plugindir}/platformthemes/ for requires.
|
||||
# Those themes are there for platform integration. If the required libraries are
|
||||
|
|
@ -166,7 +173,13 @@ BuildRequires: pkgconfig(vulkan)
|
|||
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)
|
||||
|
||||
%global sqlite 1
|
||||
BuildRequires: pkgconfig(sqlite3) >= 3.7
|
||||
|
|
@ -306,7 +319,6 @@ 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
|
||||
|
|
@ -428,7 +440,7 @@ translationdir=%{_qt6_translationdir}
|
|||
|
||||
Name: Qt6
|
||||
Description: Qt6 Configuration
|
||||
Version: 6.9.1
|
||||
Version: 6.10.1
|
||||
EOF
|
||||
|
||||
# rpm macros
|
||||
|
|
@ -499,7 +511,7 @@ 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
|
||||
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
|
||||
|
|
@ -597,6 +609,11 @@ make check -k ||:
|
|||
%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
|
||||
|
|
@ -633,6 +650,7 @@ make check -k ||:
|
|||
%{_qt6_libexecdir}/qvkgen
|
||||
%{_qt6_libexecdir}/rcc
|
||||
%{_qt6_libexecdir}/uic
|
||||
%{_qt6_libexecdir}/qtwaylandscanner
|
||||
%{_qt6_headerdir}/QtConcurrent/
|
||||
%{_qt6_headerdir}/QtCore/
|
||||
%{_qt6_headerdir}/QtDBus/
|
||||
|
|
@ -643,6 +661,9 @@ 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/
|
||||
|
|
@ -666,10 +687,14 @@ 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
|
||||
|
|
@ -716,6 +741,11 @@ 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
|
||||
|
|
@ -729,20 +759,23 @@ make check -k ||:
|
|||
%{_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_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
|
||||
|
|
@ -752,13 +785,11 @@ make check -k ||:
|
|||
%{_qt6_headerdir}/QtEglFSDeviceIntegration
|
||||
%{_qt6_headerdir}/QtEglFsKmsGbmSupport
|
||||
%{_qt6_headerdir}/QtEglFsKmsSupport
|
||||
%dir %{_qt6_libdir}/cmake/Qt6ConcurrentPrivate
|
||||
%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/Qt6OpenGLWidgetsPrivate
|
||||
%dir %{_qt6_libdir}/cmake/Qt6PrintSupportPrivate
|
||||
%dir %{_qt6_libdir}/cmake/Qt6SqlPrivate
|
||||
%dir %{_qt6_libdir}/cmake/Qt6TestInternalsPrivate
|
||||
|
|
@ -770,13 +801,11 @@ make check -k ||:
|
|||
%dir %{_qt6_libdir}/cmake/Qt6EglFsKmsGbmSupportPrivate
|
||||
%dir %{_qt6_libdir}/cmake/Qt6EglFsKmsSupportPrivate
|
||||
%dir %{_qt6_libdir}/cmake/Qt6XcbQpaPrivate
|
||||
%{_qt6_libdir}/cmake/Qt6ConcurrentPrivate/*.cmake
|
||||
%{_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/Qt6OpenGLWidgetsPrivate/*.cmake
|
||||
%{_qt6_libdir}/cmake/Qt6PrintSupportPrivate/*.cmake
|
||||
%{_qt6_libdir}/cmake/Qt6SqlPrivate/*.cmake
|
||||
%{_qt6_libdir}/cmake/Qt6TestInternalsPrivate/*.cmake
|
||||
|
|
@ -800,10 +829,12 @@ make check -k ||:
|
|||
%{_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}/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
|
||||
%{_qt6_headerdir}/*/%{qt_version}/
|
||||
%{_qt6_descriptionsdir}/TestInternalsPrivate.json
|
||||
|
||||
|
|
@ -816,35 +847,35 @@ make check -k ||:
|
|||
%{_qt6_descriptionsdir}/ExampleIconsPrivate.json
|
||||
%dir %{_qt6_archdatadir}/objects-*
|
||||
%{_qt6_archdatadir}/objects-*/ExampleIconsPrivate_resources_1/
|
||||
%{_qt6_metatypesdir}/qt6exampleiconsprivate_*_metatypes.json
|
||||
%{_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
|
||||
%{_qt6_metatypesdir}/qt6devicediscoverysupportprivate_metatypes.json
|
||||
%dir %{_qt6_libdir}/cmake/Qt6FbSupportPrivate
|
||||
%{_qt6_libdir}/cmake/Qt6FbSupportPrivate/*.cmake
|
||||
%{_qt6_headerdir}/QtFbSupport
|
||||
%{_qt6_libdir}/libQt6FbSupport.*a
|
||||
%{_qt6_libdir}/libQt6FbSupport.prl
|
||||
%{_qt6_descriptionsdir}/FbSupportPrivate.json
|
||||
%{_qt6_metatypesdir}/qt6fbsupportprivate_*_metatypes.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
|
||||
%{_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
|
||||
%{_qt6_metatypesdir}/qt6kmssupportprivate_metatypes.json
|
||||
|
||||
%if 0%{?examples}
|
||||
%files examples
|
||||
|
|
@ -879,6 +910,8 @@ 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
|
||||
|
|
@ -917,17 +950,59 @@ make check -k ||:
|
|||
%{_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/
|
||||
|
||||
%changelog
|
||||
* Mon Dec 22 2025 Jan Grulich <jgrulich@redhat.com> - 6.10.1-3
|
||||
- Fix crash in QWaylandShmBackingStore::scroll()
|
||||
|
||||
* Mon Dec 08 2025 Jan Grulich <jgrulich@redhat.com> - 6.10.1-2
|
||||
- Re-add wayland fixes for mouse scrolling
|
||||
|
||||
* Thu Nov 20 2025 Jan Grulich <jgrulich@redhat.com> - 6.10.1-1
|
||||
- 6.10.1
|
||||
|
||||
* Mon Nov 10 2025 Jan Grulich <jgrulich@redhat.com> - 6.10.0-3
|
||||
- Backport wayland fixes for mouse scrolling
|
||||
|
||||
* Wed Oct 29 2025 Jan Grulich <jgrulich@redhat.com> - 6.10.0-2
|
||||
- Backport: Wayland - convey preference for server side decorations
|
||||
|
||||
* Tue Oct 07 2025 Jan Grulich <jgrulich@redhat.com> - 6.10.0-1
|
||||
- 6.10.0
|
||||
|
||||
* Tue Sep 30 2025 Gwyn Ciesla <gwync@protonmail.com> - 6.10.0~rc-2
|
||||
- Firebird 5 rebuild
|
||||
|
||||
* Thu Sep 25 2025 Jan Grulich <jgrulich@redhat.com> - 6.10.0~rc-1
|
||||
- 6.10.0 RC
|
||||
|
||||
* Thu Aug 28 2025 Jan Grulich <jgrulich@redhat.com> - 6.9.2-1
|
||||
- 6.9.2
|
||||
|
||||
* Tue Aug 05 2025 František Zatloukal <fzatlouk@redhat.com> - 6.9.1-4
|
||||
- Rebuilt for icu 77.1
|
||||
|
||||
* Mon Jul 28 2025 Adam Williamson <awilliam@redhat.com> - 6.9.1-3
|
||||
- Adjust for https://fedoraproject.org/wiki/Changes/dropingOfCertPemFile removals
|
||||
|
||||
* Fri Jul 25 2025 Fedora Release Engineering <releng@fedoraproject.org> - 6.9.1-2
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild
|
||||
|
||||
* Mon Jun 02 2025 Jan Grulich <jgrulich@redhat.com> - 6.9.1-1
|
||||
- 6.9.1
|
||||
|
||||
|
|
@ -1124,7 +1199,7 @@ make check -k ||:
|
|||
* Fri Apr 7 2023 Marie Loise Nolden <loise@kde.org> - 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 <jgrulich@redhat.com> - 6.5.0-1
|
||||
- 6.5.0
|
||||
|
||||
|
|
|
|||
174
qtbase-wayland-compress-high-frequency-mouse-events.patch
Normal file
174
qtbase-wayland-compress-high-frequency-mouse-events.patch
Normal file
|
|
@ -0,0 +1,174 @@
|
|||
From 095759818854e5a011aa8f859e566bbc6368ab76 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?B=C5=82a=C5=BCej=20Szczygie=C5=82?= <mumei6102@gmail.com>
|
||||
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 <davidedmundson@kde.org>
|
||||
---
|
||||
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);
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
From 18550cd9ad04913d50abfc88a6048b7cfaf80687 Mon Sep 17 00:00:00 2001
|
||||
From: Igor Khanin <igor@khanin.biz>
|
||||
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 <davidedmundson@kde.org>
|
||||
---
|
||||
|
||||
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);
|
||||
|
|
@ -0,0 +1,235 @@
|
|||
From 9dd0d936d6691904a4bb212dcf48999a5228b84f Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?B=C5=82a=C5=BCej=20Szczygie=C5=82?= <mumei6102@gmail.com>
|
||||
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 <davidedmundson@kde.org>
|
||||
---
|
||||
.../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<QWaylandPointerEvent> event;
|
||||
|
||||
QPointF delta;
|
||||
QPoint delta120;
|
||||
@@ -387,10 +387,14 @@ private Q_SLOTS:
|
||||
} mFrameData;
|
||||
|
||||
bool mScrollBeginSent = false;
|
||||
+ bool mScrollEnd = false;
|
||||
QPointF mScrollDeltaRemainder;
|
||||
+ QPointer<QWaylandWindow> mScrollTarget;
|
||||
|
||||
QWaylandEventCompressionPrivate mEventCompression;
|
||||
|
||||
+ void maybePointerFrame();
|
||||
+
|
||||
void setFrameEvent(QWaylandPointerEvent *event);
|
||||
void flushScrollEvent();
|
||||
void flushFrameEvent();
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
From c93008e4d06abb0072e0e5e57d84a4ae182ecfc0 Mon Sep 17 00:00:00 2001
|
||||
From: Błażej Szczygieł <mumei6102@gmail.com>
|
||||
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 <davidedmundson@kde.org>
|
||||
---
|
||||
|
||||
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();
|
||||
242
qtbase-wayland-optimize-scroll-operations.patch
Normal file
242
qtbase-wayland-optimize-scroll-operations.patch
Normal file
|
|
@ -0,0 +1,242 @@
|
|||
From 6f25f703fd37a900c139e14a33a4639502bfeae7 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?B=C5=82a=C5=BCej=20Szczygie=C5=82?= <mumei6102@gmail.com>
|
||||
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ø <tor.arne.vestbo@qt.io>
|
||||
Reviewed-by: David Edmundson <davidedmundson@kde.org>
|
||||
---
|
||||
.../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<QWaylandShmBackingStore *>(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();
|
||||
2
sources
2
sources
|
|
@ -1 +1 @@
|
|||
SHA512 (qtbase-everywhere-src-6.9.1.tar.xz) = f0fdf4e2c10db73d8036e4b1324f04f48eced78feeed450b0ffa1fac5574daa4173996a4d25da761f5eeaa6037eab02418a88a59fd760d96a08d813c9b8136ed
|
||||
SHA512 (qtbase-everywhere-src-6.10.1.tar.xz) = fd5dcdc59ec3b39e48563513ae438eb4540a28e72c46961295de2ccb08609289d477ef7e91aac0b8983f2d5b05b901b4f5be10eaca4ac4c6aa8cd598f37a228e
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue