19 Commits

Author SHA256 Message Date
9ed46696dd Accepting request 1330573 from KDE:Qt6
Qt 6.10.2

OBS-URL: https://build.opensuse.org/request/show/1330573
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/qt6-base?expand=0&rev=78
2026-02-03 20:26:46 +00:00
21c65b9467 Qt 6.10.2
OBS-URL: https://build.opensuse.org/package/show/KDE:Qt6/qt6-base?expand=0&rev=159
2026-02-02 17:02:51 +00:00
9e933eb69a Accepting request 1323004 from KDE:Qt6
- Add patch to fix crash due to 0001-fix-slow-scrolling-on-wayland.patch
  (boo#1253651):
  * 0001-wayland-Fix-crash-in-QWaylandShmBackingStore-scroll.patch (forwarded request 1322977 from Vogtinator)

OBS-URL: https://build.opensuse.org/request/show/1323004
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/qt6-base?expand=0&rev=77
2025-12-17 16:30:56 +00:00
Christophe Marin
b6a9d2527a - Add patch to fix crash due to 0001-fix-slow-scrolling-on-wayland.patch
(boo#1253651):
  * 0001-wayland-Fix-crash-in-QWaylandShmBackingStore-scroll.patch

OBS-URL: https://build.opensuse.org/package/show/KDE:Qt6/qt6-base?expand=0&rev=157
2025-12-15 18:18:07 +00:00
ff173b5396 Accepting request 1319476 from KDE:Qt6
Qt 6.10.1

OBS-URL: https://build.opensuse.org/request/show/1319476
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/qt6-base?expand=0&rev=76
2025-11-25 14:47:28 +00:00
Christophe Marin
d7ecc801d2 OBS-URL: https://build.opensuse.org/package/show/KDE:Qt6/qt6-base?expand=0&rev=155 2025-11-23 13:19:22 +00:00
Christophe Marin
8c26ae5907 Qt 6.10.1
OBS-URL: https://build.opensuse.org/package/show/KDE:Qt6/qt6-base?expand=0&rev=154
2025-11-23 09:07:34 +00:00
087e46d9e1 Accepting request 1313166 from KDE:Qt6
- Fix slow scrolling on Wayland (bsc#1249117).
- This patch relates to QTBUG-138706 and QTBUG-139231.
- Add patch:
  * 0001-fix-slow-scrolling-on-wayland.patch (forwarded request 1313081 from mschreiner)

OBS-URL: https://build.opensuse.org/request/show/1313166
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/qt6-base?expand=0&rev=75
2025-10-24 15:22:54 +00:00
Christophe Marin
6d3e4259ff OBS-URL: https://build.opensuse.org/package/show/KDE:Qt6/qt6-base?expand=0&rev=152 2025-10-23 08:41:09 +00:00
Christophe Marin
4e574fd8b0 - Fix slow scrolling on Wayland (bsc#1249117).
- This patch relates to QTBUG-138706 and QTBUG-139231.
- Add patch:
  * 0001-fix-slow-scrolling-on-wayland.patch

OBS-URL: https://build.opensuse.org/package/show/KDE:Qt6/qt6-base?expand=0&rev=151
2025-10-23 08:35:58 +00:00
1a467f50ef Accepting request 1311343 from KDE:Qt6
- Install the adwaita decorationplugin when both
  libQt6WaylandClient6 and gnome-shell are present

OBS-URL: https://build.opensuse.org/request/show/1311343
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/qt6-base?expand=0&rev=74
2025-10-15 10:44:54 +00:00
Christophe Marin
b49354d0da - Install the adwaita decorationplugin when both
libQt6WaylandClient6 and gnome-shell are present

OBS-URL: https://build.opensuse.org/package/show/KDE:Qt6/qt6-base?expand=0&rev=149
2025-10-14 08:55:37 +00:00
793689cae1 Accepting request 1310338 from KDE:Qt6
Qt 6.10.0

OBS-URL: https://build.opensuse.org/request/show/1310338
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/qt6-base?expand=0&rev=73
2025-10-13 15:23:27 +00:00
Christophe Marin
2263127976 OBS-URL: https://build.opensuse.org/package/show/KDE:Qt6/qt6-base?expand=0&rev=147 2025-10-09 17:19:47 +00:00
Christophe Marin
1e6ddd9d96 OBS-URL: https://build.opensuse.org/package/show/KDE:Qt6/qt6-base?expand=0&rev=146 2025-10-09 17:17:39 +00:00
Christophe Marin
7ea5f78694 OBS-URL: https://build.opensuse.org/package/show/KDE:Qt6/qt6-base?expand=0&rev=145 2025-10-09 16:26:14 +00:00
Christophe Marin
6fc906d145 Qt 6.10.0
OBS-URL: https://build.opensuse.org/package/show/KDE:Qt6/qt6-base?expand=0&rev=144
2025-10-08 16:54:41 +00:00
b6cba5b925 Accepting request 1301698 from KDE:Qt6
Update to 6.9.2 (forwarded request 1301562 from krop)

OBS-URL: https://build.opensuse.org/request/show/1301698
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/qt6-base?expand=0&rev=72
2025-08-29 16:35:00 +00:00
Christophe Marin
0ffb2ba5a9 Update to 6.9.2
OBS-URL: https://build.opensuse.org/package/show/KDE:Qt6/qt6-base?expand=0&rev=142
2025-08-28 07:28:07 +00:00
10 changed files with 866 additions and 174 deletions

View File

@@ -1,66 +0,0 @@
From f4822eec1855231f189e5348dffc29299f6edf93 Mon Sep 17 00:00:00 2001
From: Samuel Gaist <samuel.gaist@idiap.ch>
Date: Sat, 24 May 2025 21:07:37 +0200
Subject: [PATCH] Add clamping to QColorTransferGenericFunction
This ensures that the inputs are within range for the use of these
function.
Depending on the values passed, they can trigger FE_INVALID errors
and thus NaN as return values.
This can happen for example when feeding an invalid ICC profile to
QColorSpace::fromIccProfile.
Credit to OSS-Fuzz
Fixes: QTBUG-137159
Pick-to: 6.8 6.5
Change-Id: I435a5768fbb7d3e6cb84d578703e7dde2e39a27e
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit f12d046383decf8f468de62732c9cff7d4303cbf)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 8706176f8f78df9bf5cc560fb80aefa3fda01d98)
---
src/gui/painting/qcolortransfergeneric_p.h | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/gui/painting/qcolortransfergeneric_p.h b/src/gui/painting/qcolortransfergeneric_p.h
index 6caebceb1a4..c2ebd937a44 100644
--- a/src/gui/painting/qcolortransfergeneric_p.h
+++ b/src/gui/painting/qcolortransfergeneric_p.h
@@ -65,6 +65,7 @@ private:
// HLG from linear [0-12] -> [0-1]
static float hlgFromLinear(float x)
{
+ x = std::clamp(x, 0.f, 12.f);
if (x > 1.f)
return m_hlg_a * std::log(x - m_hlg_b) + m_hlg_c;
return std::sqrt(x * 0.25f);
@@ -73,6 +74,7 @@ private:
// HLG to linear [0-1] -> [0-12]
static float hlgToLinear(float x)
{
+ x = std::clamp(x, 0.f, 1.f);
if (x < 0.5f)
return (x * x) * 4.f;
return std::exp((x - m_hlg_c) / m_hlg_a) + m_hlg_b;
@@ -86,6 +88,7 @@ private:
// PQ to linear [0-1] -> [0-64]
static float pqToLinear(float e)
{
+ e = std::clamp(e, 0.f, 1.f);
// m2-th root of E'
const float eRoot = std::pow(e, 1.f / m_pq_m2);
// rational transform
@@ -99,6 +102,7 @@ private:
// PQ from linear [0-64] -> [0-1]
static float pqFromLinear(float fd)
{
+ fd = std::clamp(fd, 0.f, 64.f);
// scale Fd to Y
const float y = fd * (1.f / m_pq_f);
// yRoot = Y^m1 -- "root" because m1 is <1
--
2.50.0

View File

@@ -1,40 +0,0 @@
From 282a959ed771e5598a4d1d4e9d6c1a5a2d5e6286 Mon Sep 17 00:00:00 2001
From: Antonio Larrosa <larrosa@kde.org>
Date: Wed, 9 Apr 2025 08:02:06 +0200
Subject: [PATCH] Rename variable being shadowed
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Otherwise building any application that includes this header while using -Werror=shadow fails with:
[ 89s] /usr/include/qt6/QtCore/qtmochelpers.h:563:36: in constexpr expansion of (& methods)->QtMocHelpers::UintData<QtMocHelpers::SignalData<void(libcamera::FrameBuffer*)> >::copyTo<{anonymous}::qt_meta_tag_ZN12ViewFinderGLE_t, QtMocHelpers::MetaObjectContents<24, 10, 60, 3> >(result, ((size_t)dataoffset), metatypeoffset)
[ 89s] /usr/include/qt6/QtCore/qtmochelpers.h:201:57: error: declaration of entry shadows a member of QtMocHelpers::detail::UintDataStorage<std::integer_sequence<int, 0>, QtMocHelpers::SignalData<void(libcamera::FrameBuffer*)> > [-Werror=shadow]
[ 89s] 201 | [[maybe_unused]] auto invoke = [&f](const auto &entry) { f(entry.entry); return 0; };
[ 89s] | ~~~~~~~~~~~~^~~~~
[ 89s] /usr/include/qt6/QtCore/qtmochelpers.h:180:7: note: shadowed declaration is here
[ 89s] 180 | T entry;
[ 89s] | ^~~~~
[ 89s] cc1plus: all warnings being treated as errors
Change-Id: I7a3e48fc98acbfabf611b6be813b8576c7168499
---
src/corelib/kernel/qtmochelpers.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/corelib/kernel/qtmochelpers.h b/src/corelib/kernel/qtmochelpers.h
index 3099389b872..4c549e78ad5 100644
--- a/src/corelib/kernel/qtmochelpers.h
+++ b/src/corelib/kernel/qtmochelpers.h
@@ -198,7 +198,7 @@ template <int... Idx, typename... T> struct UintDataStorage<std::integer_sequenc
template <typename F> constexpr void forEach(F &&f) const
{
- [[maybe_unused]] auto invoke = [&f](const auto &entry) { f(entry.entry); return 0; };
+ [[maybe_unused]] auto invoke = [&f](const auto &entry_) { f(entry_.entry); return 0; };
int dummy[] = {
0,
invoke(static_cast<const UintDataEntry<Idx, T> &>(*this))...
--
2.49.0

View File

@@ -0,0 +1,54 @@
From 793c4c0d728024139083660a7f382f6d95853efe Mon Sep 17 00:00:00 2001
From: Christophe Marin <christophe@krop.fr>
Date: Sun, 6 Jun 2021 10:44:09 +0200
Subject: [PATCH] Use newer GCC on Leap.patch
The default compiler in Leap doesn't meet all the Qt requirements.
Use the latest compiler version available on Leap.
Change-Id: I0c4ad87af4dd60d12fa09366eb9910edafcc9c4c
---
mkspecs/common/g++-base.conf | 6 +++---
mkspecs/common/gcc-base.conf | 4 ++--
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/mkspecs/common/g++-base.conf b/mkspecs/common/g++-base.conf
index d392879..ddca128 100644
--- a/mkspecs/common/g++-base.conf
+++ b/mkspecs/common/g++-base.conf
@@ -8,14 +8,14 @@
# you can use the manual test in tests/manual/mkspecs.
#
-QMAKE_COMPILER = gcc
+QMAKE_COMPILER = gcc-15
-QMAKE_CC = $${CROSS_COMPILE}gcc
+QMAKE_CC = $${CROSS_COMPILE}gcc-15
QMAKE_LINK_C = $$QMAKE_CC
QMAKE_LINK_C_SHLIB = $$QMAKE_CC
-QMAKE_CXX = $${CROSS_COMPILE}g++
+QMAKE_CXX = $${CROSS_COMPILE}g++-15
QMAKE_LINK = $$QMAKE_CXX
QMAKE_LINK_SHLIB = $$QMAKE_CXX
diff --git a/mkspecs/common/gcc-base.conf b/mkspecs/common/gcc-base.conf
index ae58326..33cc860 100644
--- a/mkspecs/common/gcc-base.conf
+++ b/mkspecs/common/gcc-base.conf
@@ -124,8 +124,8 @@ QMAKE_CFLAGS_MIPS_DSPR2 += -mdspr2
QMAKE_CFLAGS_ARCH_HASWELL = -march=core-avx2
# Wrapper tools that understand .o/.a files with GIMPLE instead of machine code
-QMAKE_AR_LTCG = gcc-ar cqs
-QMAKE_NM_LTCG = gcc-nm -P
+QMAKE_AR_LTCG = gcc-ar-15 cqs
+QMAKE_NM_LTCG = gcc-nm-15 -P
QMAKE_RANLIB_LTCG = true # No need to run since gcc-ar has "s"
QMAKE_LINK_OBJECT_SCRIPT = object_script
--
2.43.0

View File

@@ -3,7 +3,7 @@ From: Christophe Marin <christophe@krop.fr>
Date: Sun, 6 Jun 2021 10:44:09 +0200
Subject: [PATCH] Use newer GCC on Leap.patch
The default compiler in Leap doesn't match the Qt requirements.
The default compiler in Leap doesn't meet all the Qt requirements.
Use the latest compiler version available on Leap.
Change-Id: I0c4ad87af4dd60d12fa09366eb9910edafcc9c4c
@@ -21,16 +21,16 @@ index d392879..ddca128 100644
#
-QMAKE_COMPILER = gcc
+QMAKE_COMPILER = gcc-13
+QMAKE_COMPILER = gcc-14
-QMAKE_CC = $${CROSS_COMPILE}gcc
+QMAKE_CC = $${CROSS_COMPILE}gcc-13
+QMAKE_CC = $${CROSS_COMPILE}gcc-14
QMAKE_LINK_C = $$QMAKE_CC
QMAKE_LINK_C_SHLIB = $$QMAKE_CC
-QMAKE_CXX = $${CROSS_COMPILE}g++
+QMAKE_CXX = $${CROSS_COMPILE}g++-13
+QMAKE_CXX = $${CROSS_COMPILE}g++-14
QMAKE_LINK = $$QMAKE_CXX
QMAKE_LINK_SHLIB = $$QMAKE_CXX
@@ -44,8 +44,8 @@ index ae58326..33cc860 100644
# Wrapper tools that understand .o/.a files with GIMPLE instead of machine code
-QMAKE_AR_LTCG = gcc-ar cqs
-QMAKE_NM_LTCG = gcc-nm -P
+QMAKE_AR_LTCG = gcc-ar-13 cqs
+QMAKE_NM_LTCG = gcc-nm-13 -P
+QMAKE_AR_LTCG = gcc-ar-14 cqs
+QMAKE_NM_LTCG = gcc-nm-14 -P
QMAKE_RANLIB_LTCG = true # No need to run since gcc-ar has "s"
QMAKE_LINK_OBJECT_SCRIPT = object_script

View File

@@ -0,0 +1,534 @@
Contains 2 changes:
- wayland: Compress high frequency mouse events (https://bugreports.qt.io/browse/QTBUG-138706)
- wayland: Optimize scroll operation (https://bugreports.qt.io/browse/QTBUG-139231)
diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc
index 09ed97a..e530b28 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 170e80f..5f927fc 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()
@@ -914,14 +944,16 @@ 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()
{
+ if (mEventCompression.compressEvent()) {
+ qCDebug(lcQpaWaylandInput) << "compressed pointer_frame event";
+ return;
+ }
+
flushFrameEvent();
}
@@ -952,11 +984,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
@@ -964,25 +994,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)
@@ -1043,6 +1055,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;
@@ -1051,12 +1071,9 @@ void QWaylandInputDevice::Pointer::setFrameEvent(QWaylandPointerEvent *event)
flushFrameEvent();
}
- 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()
@@ -1136,11 +1153,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";
@@ -1150,27 +1180,46 @@ 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();
}
void QWaylandInputDevice::Pointer::flushFrameEvent()
{
- if (auto *event = mFrameData.event) {
+ mEventCompression.delayTimer.stop();
+
+ if (auto *event = mFrameData.event.get()) {
if (auto window = event->surface) {
window->handleMouse(mParent, *event);
} else if (mFrameData.event->type == QEvent::MouseButtonRelease) {
@@ -1183,8 +1232,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 bcaf025..b9582da 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
@@ -362,7 +372,7 @@ public:
Qt::MouseButton mLastButton = Qt::NoButton;
struct FrameData {
- QWaylandPointerEvent *event = nullptr;
+ QScopedPointer<QWaylandPointerEvent> event;
QPointF delta;
QPoint delta120;
@@ -379,7 +389,13 @@ public:
} mFrameData;
bool mScrollBeginSent = false;
+ bool mScrollEnd = false;
QPointF mScrollDeltaRemainder;
+ QPointer<QWaylandWindow> mScrollTarget;
+
+ QWaylandEventCompressionPrivate mEventCompression;
+
+ void maybePointerFrame();
void setFrameEvent(QWaylandPointerEvent *event);
void flushScrollEvent();
diff --git a/src/plugins/platforms/wayland/qwaylandintegration.cpp b/src/plugins/platforms/wayland/qwaylandintegration.cpp
index 669d47e..fc869de 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/src/plugins/platforms/wayland/qwaylandshmbackingstore.cpp b/src/plugins/platforms/wayland/qwaylandshmbackingstore.cpp
index d525fe1..d55cf22 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 &region)
{
- // 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 &region)
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 &region, 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 &region, 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.
@@ -291,6 +313,8 @@ void QWaylandShmBackingStore::flush(QWindow *window, const QRegion &region, cons
if (windowDecoration() && windowDecoration()->isDirty())
updateDecorations();
+ finalizeBackBuffer();
+
mFrontBuffer = mBackBuffer;
QMargins margins = windowDecorationMargins();
@@ -315,6 +339,8 @@ QWaylandShmBuffer *QWaylandShmBackingStore::getBuffer(const QSize &size, bool &b
mBuffers.removeAt(i);
if (mBackBuffer == buffer)
mBackBuffer = nullptr;
+ if (mFrontBuffer == buffer)
+ mFrontBuffer = nullptr;
delete buffer;
}
}
@@ -343,7 +369,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);
@@ -377,30 +403,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)) {
@@ -414,11 +416,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();
@@ -498,6 +529,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 efd8015..cfcafb2 100644
--- a/src/plugins/platforms/wayland/qwaylandshmbackingstore_p.h
+++ b/src/plugins/platforms/wayland/qwaylandshmbackingstore_p.h
@@ -73,7 +73,8 @@ public:
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/tests/auto/wayland/client/tst_client.cpp b/tests/auto/wayland/client/tst_client.cpp
index 04400e3..09ac4f7 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);

View File

@@ -0,0 +1,44 @@
From c93008e4d06abb0072e0e5e57d84a4ae182ecfc0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?B=C5=82a=C5=BCej=20Szczygie=C5=82?= <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>
---
src/plugins/platforms/wayland/qwaylandshmbackingstore.cpp | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/src/plugins/platforms/wayland/qwaylandshmbackingstore.cpp b/src/plugins/platforms/wayland/qwaylandshmbackingstore.cpp
index b853db21529..fa70b53cbd0 100644
--- a/src/plugins/platforms/wayland/qwaylandshmbackingstore.cpp
+++ b/src/plugins/platforms/wayland/qwaylandshmbackingstore.cpp
@@ -229,7 +229,7 @@ void QWaylandShmBackingStore::endPaint()
// Inspired by QCALayerBackingStore.
bool QWaylandShmBackingStore::scroll(const QRegion &region, int dx, int dy)
{
- if (Q_UNLIKELY(!mBackBuffer || !mFrontBuffer))
+ if (Q_UNLIKELY(!mBackBuffer))
return false;
const qreal devicePixelRatio = waylandWindow()->scale();
@@ -241,6 +241,8 @@ bool QWaylandShmBackingStore::scroll(const QRegion &region, int dx, int dy)
return false;
recreateBackBufferIfNeeded();
+ if (!mFrontBuffer)
+ return false;
const QPoint scrollDelta(dx, dy);
const QMargins margins = windowDecorationMargins();
--
2.52.0

View File

@@ -1,3 +1,55 @@
-------------------------------------------------------------------
Sat Jan 31 08:10:33 UTC 2026 - Christophe Marin <christophe@krop.fr>
- Update to 6.10.2:
* https://www.qt.io/blog/qt-6.10.2-released
-------------------------------------------------------------------
Mon Dec 15 15:41:38 UTC 2025 - Fabian Vogt <fabian@ritter-vogt.de>
- Add patch to fix crash due to 0001-fix-slow-scrolling-on-wayland.patch
(boo#1253651):
* 0001-wayland-Fix-crash-in-QWaylandShmBackingStore-scroll.patch
-------------------------------------------------------------------
Thu Nov 20 15:14:22 UTC 2025 - Christophe Marin <christophe@krop.fr>
- Update to 6.10.1
https://www.qt.io/blog/qt-6.10.1-released
-------------------------------------------------------------------
Wed Oct 22 19:43:33 UTC 2025 - Martin Schreiner <martin.schreiner@suse.com>
- Fix slow scrolling on Wayland (bsc#1249117).
- This patch relates to QTBUG-138706 and QTBUG-139231.
- Add patch:
* 0001-fix-slow-scrolling-on-wayland.patch
-------------------------------------------------------------------
Tue Oct 14 08:54:57 UTC 2025 - Christophe Marin <christophe@krop.fr>
- Install the adwaita decorationplugin when both
libQt6WaylandClient6 and gnome-shell are present
-------------------------------------------------------------------
Tue Oct 7 08:53:20 UTC 2025 - Christophe Marin <christophe@krop.fr>
- Update to 6.10.0
* https://www.qt.io/blog/qt-6.10-released
- Drop patch:
* 0001-Rename-variable-being-shadowed.patch
- Add patches:
* 0001-Use-newer-GCC-on-Leap.patch
* 0001-Use-newer-GCC-on-Leap-16.patch
-------------------------------------------------------------------
Wed Aug 27 07:15:04 UTC 2025 - Christophe Marin <christophe@krop.fr>
- Update to 6.9.2:
* https://www.qt.io/blog/qt-6.9.2-released
- Drop patch, merged upstream:
* 0001-Add-clamping-to-QColorTransferGenericFunction.patch
-------------------------------------------------------------------
Fri Jul 11 10:11:11 UTC 2025 - Christophe Marin <christophe@krop.fr>

View File

@@ -1,7 +1,7 @@
#
# spec file for package qt6-base
#
# Copyright (c) 2025 SUSE LLC
# Copyright (c) 2026 SUSE LLC and contributors
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -16,8 +16,8 @@
#
%define real_version 6.9.1
%define short_version 6.9
%define real_version 6.10.2
%define short_version 6.10
%define tar_name qtbase-everywhere-src
%define tar_suffix %{nil}
#
@@ -33,7 +33,7 @@
%bcond_without system_md4c
%endif
Name: qt6-base%{?pkg_suffix}
Version: 6.9.1
Version: 6.10.2
Release: 0
Summary: Qt 6 core components (Core, Gui, Widgets, Network...)
# Legal: qtpaths is BSD-3-Clause
@@ -42,29 +42,30 @@ URL: https://www.qt.io
Source0: https://download.qt.io/official_releases/qt/%{short_version}/%{real_version}%{tar_suffix}/submodules/%{tar_name}-%{real_version}%{tar_suffix}.tar.xz
Source99: qt6-base-rpmlintrc
# Patches 0-100 are upstream patches #
# PATCH-FIX-UPSTREAM 0001-Rename-variable-being-shadowed.patch alarrosa@suse.com -- https://codereview.qt-project.org/c/qt/qtbase/+/638284
Patch0: 0001-Rename-variable-being-shadowed.patch
# CVE-2025-5992
Patch1: 0001-Add-clamping-to-QColorTransferGenericFunction.patch
Patch0: 0001-fix-slow-scrolling-on-wayland.patch
Patch1: 0001-wayland-Fix-crash-in-QWaylandShmBackingStore-scroll.patch
# Patches 100-200 are openSUSE and/or non-upstream(able) patches #
# No need to pollute the library dir with object files, install them in the qt6 subfolder
Patch100: 0001-CMake-Install-objects-files-into-ARCHDATADIR.patch
%if 0%{?suse_version} == 1500
Patch101: 0001-Use-newer-GCC-on-Leap.patch
%endif
Patch102: 0001-Don-t-strip-binaries-when-building-with-qmake.patch
Patch101: 0001-Don-t-strip-binaries-when-building-with-qmake.patch
# Change a couple default build system settings
Patch103: 0001-Change-default-settings-for-Qt-packages.patch
Patch102: 0001-Change-default-settings-for-Qt-packages.patch
# Conditional patches depending on the leap version
Patch201: 0001-Use-newer-GCC-on-Leap.patch
Patch202: 0001-Use-newer-GCC-on-Leap-16.patch
##
BuildRequires: cmake >= 3.18.3
BuildRequires: cups-devel
# The default GCC version in Leap 15 is too old
%if 0%{?suse_version} == 1500
BuildRequires: gcc13-PIE
BuildRequires: gcc13-c++
%else
BuildRequires: gcc-c++
BuildRequires: gcc14-PIE
BuildRequires: gcc14-c++
%endif
%if 0%{?suse_version} == 1600
BuildRequires: gcc15-PIE
BuildRequires: gcc15-c++
%endif
BuildRequires: gcc-c++
BuildRequires: libicu-devel
BuildRequires: libmysqlclient-devel
BuildRequires: libproxy-devel
@@ -74,6 +75,9 @@ BuildRequires: pcre2-devel
BuildRequires: perl
BuildRequires: pkgconfig
BuildRequires: qt6-macros
%ifnarch ppc64le s390x
BuildRequires: renderdoc-devel
%endif
BuildRequires: xmlstarlet
BuildRequires: cmake(double-conversion)
%if %{with system_md4c}
@@ -160,6 +164,9 @@ Requires: cmake(Qt6OpenGLWidgets) = %{real_version}
Requires: cmake(Qt6PrintSupport) = %{real_version}
Requires: cmake(Qt6Sql) = %{real_version}
Requires: cmake(Qt6Test) = %{real_version}
Requires: cmake(Qt6WaylandClient) = %{real_version}
# This package contains information on features enabled at build time
Requires: cmake(Qt6WaylandGlobalPrivate) = %{real_version}
Requires: cmake(Qt6Widgets) = %{real_version}
Requires: cmake(Qt6Xml) = %{real_version}
BuildArch: noarch
@@ -180,6 +187,7 @@ Requires: cmake(Qt6OpenGLPrivate) = %{real_version}
Requires: cmake(Qt6PrintSupportPrivate) = %{real_version}
Requires: cmake(Qt6SqlPrivate) = %{real_version}
Requires: cmake(Qt6TestPrivate) = %{real_version}
Requires: cmake(Qt6WaylandClientPrivate) = %{real_version}
Requires: cmake(Qt6WidgetsPrivate) = %{real_version}
Requires: cmake(Qt6XmlPrivate) = %{real_version}
BuildArch: noarch
@@ -243,10 +251,14 @@ The Qt 6 Core library. It adds these features to C++:
Summary: Development files for the Qt 6 Core library
Requires: libQt6Core6 = %{version}
Requires: qt6-base-common-devel = %{version}
# Some KDE packages start using gcc features not available in gcc < 14
%if 0%{?suse_version} == 1500
# Some public classes require C++ 17 features
Requires: gcc13-PIE
Requires: gcc13-c++
Requires: gcc14-PIE
Requires: gcc14-c++
%endif
%if 0%{?suse_version} == 1600
Requires: gcc15-PIE
Requires: gcc15-c++
%endif
%description -n qt6-core-devel
@@ -528,6 +540,34 @@ Requires: cmake(Qt6Test) = %{real_version}
This package provides private headers of libQt6Test that do not have any
ABI or API guarantees.
%package -n libQt6WaylandClient6
Summary: Qt 6 WaylandClient library
Requires: (qt6-wayland-decoration-client-adwaita if gnome-shell)
%description -n libQt6WaylandClient6
The Qt 6 WaylandClient library.
%package -n qt6-waylandclient-devel
Summary: Development files for the Qt 6 WaylandClient library
Requires: libQt6WaylandClient6 = %{version}
# qtwaylandscanner is required
Requires: qt6-wayland = %{version}
Requires: cmake(Qt6Gui) = %{real_version}
Requires: cmake(Qt6WaylandGlobalPrivate) = %{real_version}
%description -n qt6-waylandclient-devel
Development files for the Qt6 WaylandClient library.
%package -n qt6-waylandclient-private-devel
Summary: Non-ABI stable API for the Qt 6 WaylandClient library
Requires: cmake(Qt6CorePrivate) = %{real_version}
Requires: cmake(Qt6GuiPrivate) = %{real_version}
Requires: cmake(Qt6WaylandClient) = %{real_version}
%description -n qt6-waylandclient-private-devel
This package provides private headers of libQt6WaylandClient that do not have
any ABI or API guarantees.
%package -n libQt6Widgets6
Summary: Qt 6 Widgets library
Requires: libQt6Gui6 = %{version}
@@ -590,14 +630,37 @@ BuildArch: noarch
%description -n qt6-docs-common
This package contains common files used for building Qt documentation.
### Private only libraries ###
%package -n qt6-waylandglobal-private-devel
Summary: Collection of build features used by qt6-wayland libraries
%description -n qt6-waylandglobal-private-devel
This package contains enabled features information shared by all the
qt6-wayland libraries.
%package -n libQt6WlShellIntegration6
Summary: Qt 6 WlShellIntegration library
%description -n libQt6WlShellIntegration6
The Qt 6 WlShellIntegration library.
This library does not have any ABI or API guarantees.
%package -n qt6-wlshellintegration-private-devel
Summary: Qt 6 WlShellIntegration library - Development files
Requires: libQt6WlShellIntegration6 = %{version}
Requires: cmake(Qt6Gui) = %{real_version}
Requires: cmake(Qt6WaylandClient) = %{real_version}
%description -n qt6-wlshellintegration-private-devel
Development files for the Qt 6 WlShellIntegration library.
This library does not have any ABI or API guarantees.
### Static libraries ###
%package -n qt6-exampleicons-devel-static
Summary: Qt ExampleIcons module
# TODO
Requires: cmake(Qt6CorePrivate) = %{real_version}
Requires: cmake(Qt6GuiPrivate) = %{real_version}
Requires: cmake(Qt6Core) = %{real_version}
%description -n qt6-exampleicons-devel-static
Qt icon library for examples. This private library can be used by Qt examples.
@@ -735,12 +798,25 @@ access the available data sources. Note that you also need to install
and configure ODBC drivers for the ODBC driver manager that is
installed on your system.
%package -n qt6-wayland
Summary: Qt 6 Wayland plugins
%description -n qt6-wayland
Qt 6 wayland plugins.
%{qt6_examples_package}
%endif
%prep
%autosetup -p1 -n %{tar_name}-%{real_version}%{tar_suffix}
%setup -q -n %{tar_name}-%{real_version}%{tar_suffix}
%autopatch -p1 -m 0 -M 200
%if 0%{?suse_version} == 1500
%patch -p1 -P 201
%endif
%if 0%{?suse_version} == 1600
%patch -p1 -P 202
%endif
# Copy the freetype license file to prevent errors when building docs
cp src/3rdparty/freetype/LICENSE.txt src/gui/painting/FREETYPE_LICENSE.txt
@@ -762,10 +838,6 @@ cat >> meta_package << EOF
This is a meta package, it does not contain any file
EOF
# Work around an issue with zstd CMake files (boo#1211566)
# TODO: Remove when the issue is fixed
sed -i '/zstd CONFIG/d' cmake/FindWrapZSTD.cmake
%build
%define _lto_cflags %{nil}
@@ -833,10 +905,6 @@ mkdir -p %{buildroot}%{_qt6_translationsdir}
# CMake modules for plugins are not useful
rm %{buildroot}%{_qt6_cmakedir}/*/*Plugin{Config,ConfigVersion,Targets*}.cmake
# There are no private headers
rm %{buildroot}%{_qt6_mkspecsdir}/modules/qt_lib_concurrent_private.pri
rm %{buildroot}%{_qt6_mkspecsdir}/modules/qt_lib_openglwidgets_private.pri
# 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
@@ -851,12 +919,11 @@ rm -r %{buildroot}%{_qt6_cmakedir}/Qt6ExamplesAssetDownloaderPrivate
rm -r %{buildroot}%{_qt6_includedir}/QtExamplesAssetDownloader
rm %{buildroot}%{_qt6_descriptionsdir}/ExamplesAssetDownloaderPrivate.json
rm %{buildroot}%{_qt6_libdir}/libQt6ExamplesAssetDownloader.*
rm %{buildroot}%{_qt6_metatypesdir}/qt6examplesassetdownloaderprivate_*_metatypes.json
rm %{buildroot}%{_qt6_metatypesdir}/qt6examplesassetdownloaderprivate*_metatypes.json
# E: env-script-interpreter
sed -i 's#!/bin/env python3#!/usr/bin/python3#' %{buildroot}%{_qt6_examplesdir}/corelib/serialization/cbordump/cbortag.py
%ldconfig_scriptlets -n libQt6Concurrent6
%ldconfig_scriptlets -n libQt6Core6
%ldconfig_scriptlets -n libQt6DBus6
@@ -867,7 +934,9 @@ sed -i 's#!/bin/env python3#!/usr/bin/python3#' %{buildroot}%{_qt6_examplesdir}/
%ldconfig_scriptlets -n libQt6PrintSupport6
%ldconfig_scriptlets -n libQt6Sql6
%ldconfig_scriptlets -n libQt6Test6
%ldconfig_scriptlets -n libQt6WaylandClient6
%ldconfig_scriptlets -n libQt6Widgets6
%ldconfig_scriptlets -n libQt6WlShellIntegration6
%ldconfig_scriptlets -n libQt6Xml6
%files devel
@@ -909,6 +978,7 @@ sed -i 's#!/bin/env python3#!/usr/bin/python3#' %{buildroot}%{_qt6_examplesdir}/
%{_qt6_cmakedir}/Qt6BuildInternals/Qt6BuildInternalsConfigVersion.cmake
%{_qt6_cmakedir}/Qt6BuildInternals/Qt6BuildInternalsConfigVersionImpl.cmake
%{_qt6_cmakedir}/Qt6BuildInternals/QtBuildInternalsExtra.cmake
%{_qt6_cmakedir}/Qt6BuildInternals/QtBuildInternalsHelpers.cmake
%{_qt6_cmakedir}/Qt6BuildInternals/QtStandaloneTestTemplateProject/
%{_qt6_cmakedir}/Qt6BuildInternals/StandaloneTests/QtBaseTestsConfig.cmake
%{_qt6_cmakedir}/Qt6HostInfo/
@@ -917,6 +987,7 @@ sed -i 's#!/bin/env python3#!/usr/bin/python3#' %{buildroot}%{_qt6_examplesdir}/
%{_qt6_libexecdir}/cmake_automoc_parser
%{_qt6_libexecdir}/moc
%{_qt6_libexecdir}/qlalr
%{_qt6_libexecdir}/qt_cyclonedx_generator.py
%{_qt6_libexecdir}/qt-cmake-private
%{_qt6_libexecdir}/qt-cmake-private-install.cmake
%{_qt6_libexecdir}/qt-cmake-standalone-test
@@ -937,13 +1008,11 @@ sed -i 's#!/bin/env python3#!/usr/bin/python3#' %{buildroot}%{_qt6_examplesdir}/
%files -n qt6-concurrent-devel
%{_qt6_cmakedir}/Qt6Concurrent/
# upstream bug, there are no headers in include/QtConcurrent/<version>
%{_qt6_cmakedir}/Qt6ConcurrentPrivate/
%{_qt6_descriptionsdir}/Concurrent.json
%{_qt6_includedir}/QtConcurrent/
%{_qt6_libdir}/libQt6Concurrent.prl
%{_qt6_libdir}/libQt6Concurrent.so
%{_qt6_metatypesdir}/qt6concurrent_*_metatypes.json
%{_qt6_metatypesdir}/qt6concurrent_metatypes.json
%{_qt6_mkspecsdir}/modules/qt_lib_concurrent.pri
%{_qt6_pkgconfigdir}/Qt6Concurrent.pc
@@ -970,7 +1039,7 @@ sed -i 's#!/bin/env python3#!/usr/bin/python3#' %{buildroot}%{_qt6_examplesdir}/
%{_qt6_includedir}/QtCore/
%{_qt6_libdir}/libQt6Core.prl
%{_qt6_libdir}/libQt6Core.so
%{_qt6_metatypesdir}/qt6core_*_metatypes.json
%{_qt6_metatypesdir}/qt6core_metatypes.json
%{_qt6_mkspecsdir}/modules/qt_lib_core.pri
# workaround for boo#1195368, QTBUG-100370
%{_qt6_mkspecsdir}/modules/qt_lib_core_private.pri
@@ -992,7 +1061,7 @@ sed -i 's#!/bin/env python3#!/usr/bin/python3#' %{buildroot}%{_qt6_examplesdir}/
%{_qt6_includedir}/QtDBus/
%{_qt6_libdir}/libQt6DBus.prl
%{_qt6_libdir}/libQt6DBus.so
%{_qt6_metatypesdir}/qt6dbus_*_metatypes.json
%{_qt6_metatypesdir}/qt6dbus_metatypes.json
%{_qt6_mkspecsdir}/modules/qt_lib_dbus.pri
%{_qt6_pkgconfigdir}/Qt6DBus.pc
%exclude %{_qt6_includedir}/QtDBus/%{real_version}
@@ -1024,7 +1093,7 @@ sed -i 's#!/bin/env python3#!/usr/bin/python3#' %{buildroot}%{_qt6_examplesdir}/
%{_qt6_includedir}/QtGui/
%{_qt6_libdir}/libQt6Gui.prl
%{_qt6_libdir}/libQt6Gui.so
%{_qt6_metatypesdir}/qt6gui_*_metatypes.json
%{_qt6_metatypesdir}/qt6gui_metatypes.json
%{_qt6_mkspecsdir}/modules/qt_lib_gui.pri
%{_qt6_pkgconfigdir}/Qt6Gui.pc
%exclude %{_qt6_includedir}/QtGui/%{real_version}
@@ -1052,10 +1121,10 @@ sed -i 's#!/bin/env python3#!/usr/bin/python3#' %{buildroot}%{_qt6_examplesdir}/
%{_qt6_libdir}/libQt6EglFsKmsSupport.so
%{_qt6_libdir}/libQt6XcbQpa.prl
%{_qt6_libdir}/libQt6XcbQpa.so
%{_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_mkspecsdir}/modules/qt_lib_eglfs_kms_gbm_support_private.pri
%{_qt6_mkspecsdir}/modules/qt_lib_eglfs_kms_support_private.pri
%{_qt6_mkspecsdir}/modules/qt_lib_eglfsdeviceintegration_private.pri
@@ -1071,7 +1140,7 @@ sed -i 's#!/bin/env python3#!/usr/bin/python3#' %{buildroot}%{_qt6_examplesdir}/
%{_qt6_includedir}/QtNetwork/
%{_qt6_libdir}/libQt6Network.prl
%{_qt6_libdir}/libQt6Network.so
%{_qt6_metatypesdir}/qt6network_*_metatypes.json
%{_qt6_metatypesdir}/qt6network_metatypes.json
%{_qt6_mkspecsdir}/modules/qt_lib_network.pri
%{_qt6_pkgconfigdir}/Qt6Network.pc
%exclude %{_qt6_includedir}/QtNetwork/%{real_version}
@@ -1091,7 +1160,7 @@ sed -i 's#!/bin/env python3#!/usr/bin/python3#' %{buildroot}%{_qt6_examplesdir}/
%{_qt6_includedir}/QtOpenGL/
%{_qt6_libdir}/libQt6OpenGL.prl
%{_qt6_libdir}/libQt6OpenGL.so
%{_qt6_metatypesdir}/qt6opengl_*_metatypes.json
%{_qt6_metatypesdir}/qt6opengl_metatypes.json
%{_qt6_mkspecsdir}/modules/qt_lib_opengl.pri
%{_qt6_pkgconfigdir}/Qt6OpenGL.pc
%exclude %{_qt6_includedir}/QtOpenGL/%{real_version}
@@ -1107,13 +1176,11 @@ sed -i 's#!/bin/env python3#!/usr/bin/python3#' %{buildroot}%{_qt6_examplesdir}/
%files -n qt6-openglwidgets-devel
%{_qt6_cmakedir}/Qt6OpenGLWidgets/
# upstream bug, there are no headers in include/QtOpenGLWidgets/<version>
%{_qt6_cmakedir}/Qt6OpenGLWidgetsPrivate/
%{_qt6_descriptionsdir}/OpenGLWidgets.json
%{_qt6_includedir}/QtOpenGLWidgets/
%{_qt6_libdir}/libQt6OpenGLWidgets.prl
%{_qt6_libdir}/libQt6OpenGLWidgets.so
%{_qt6_metatypesdir}/qt6openglwidgets_*_metatypes.json
%{_qt6_metatypesdir}/qt6openglwidgets_metatypes.json
%{_qt6_mkspecsdir}/modules/qt_lib_openglwidgets.pri
%{_qt6_pkgconfigdir}/Qt6OpenGLWidgets.pc
@@ -1127,7 +1194,7 @@ sed -i 's#!/bin/env python3#!/usr/bin/python3#' %{buildroot}%{_qt6_examplesdir}/
%{_qt6_includedir}/QtPrintSupport/
%{_qt6_libdir}/libQt6PrintSupport.prl
%{_qt6_libdir}/libQt6PrintSupport.so
%{_qt6_metatypesdir}/qt6printsupport_*_metatypes.json
%{_qt6_metatypesdir}/qt6printsupport_metatypes.json
%{_qt6_mkspecsdir}/modules/qt_lib_printsupport.pri
%{_qt6_pkgconfigdir}/Qt6PrintSupport.pc
%exclude %{_qt6_includedir}/QtPrintSupport/%{real_version}
@@ -1149,7 +1216,7 @@ sed -i 's#!/bin/env python3#!/usr/bin/python3#' %{buildroot}%{_qt6_examplesdir}/
%{_qt6_libdir}/libQt6Sql.prl
%{_qt6_libdir}/libQt6Sql.so
%{_qt6_mkspecsdir}/modules/qt_lib_sql.pri
%{_qt6_metatypesdir}/qt6sql_*_metatypes.json
%{_qt6_metatypesdir}/qt6sql_metatypes.json
%{_qt6_pkgconfigdir}/Qt6Sql.pc
%exclude %{_qt6_includedir}/QtSql/%{real_version}
@@ -1168,7 +1235,7 @@ sed -i 's#!/bin/env python3#!/usr/bin/python3#' %{buildroot}%{_qt6_examplesdir}/
%{_qt6_includedir}/QtTest/
%{_qt6_libdir}/libQt6Test.prl
%{_qt6_libdir}/libQt6Test.so
%{_qt6_metatypesdir}/qt6test_*_metatypes.json
%{_qt6_metatypesdir}/qt6test_metatypes.json
%{_qt6_mkspecsdir}/modules/qt_lib_testlib.pri
%{_qt6_pkgconfigdir}/Qt6Test.pc
%exclude %{_qt6_includedir}/QtTest/%{real_version}
@@ -1179,6 +1246,27 @@ sed -i 's#!/bin/env python3#!/usr/bin/python3#' %{buildroot}%{_qt6_examplesdir}/
%{_qt6_includedir}/QtTest/%{real_version}/
%{_qt6_mkspecsdir}/modules/qt_lib_testlib_private.pri
%files -n libQt6WaylandClient6
%{_qt6_libdir}/libQt6WaylandClient.so.*
%files -n qt6-waylandclient-devel
%dir %{_qt6_cmakedir}/Qt6
%{_qt6_cmakedir}/Qt6WaylandClient/
%{_qt6_cmakedir}/Qt6WaylandScannerTools/
%{_qt6_descriptionsdir}/WaylandClient.json
%{_qt6_includedir}/QtWaylandClient/
%{_qt6_libdir}/libQt6WaylandClient.prl
%{_qt6_libdir}/libQt6WaylandClient.so
%{_qt6_metatypesdir}/qt6waylandclient_metatypes.json
%{_qt6_mkspecsdir}/modules/qt_lib_waylandclient.pri
%{_qt6_pkgconfigdir}/Qt6WaylandClient.pc
%exclude %{_qt6_includedir}/QtWaylandClient/%{real_version}
%files -n qt6-waylandclient-private-devel
%{_qt6_cmakedir}/Qt6WaylandClientPrivate/
%{_qt6_includedir}/QtWaylandClient/%{real_version}/
%{_qt6_mkspecsdir}/modules/qt_lib_waylandclient_private.pri
%files -n libQt6Widgets6
%{_qt6_libdir}/libQt6Widgets.so.*
@@ -1189,7 +1277,7 @@ sed -i 's#!/bin/env python3#!/usr/bin/python3#' %{buildroot}%{_qt6_examplesdir}/
%{_qt6_includedir}/QtWidgets/
%{_qt6_libdir}/libQt6Widgets.prl
%{_qt6_libdir}/libQt6Widgets.so
%{_qt6_metatypesdir}/qt6widgets_*_metatypes.json
%{_qt6_metatypesdir}/qt6widgets_metatypes.json
%{_qt6_mkspecsdir}/modules/qt_lib_widgets.pri
%{_qt6_pkgconfigdir}/Qt6Widgets.pc
%exclude %{_qt6_includedir}/QtWidgets/%{real_version}
@@ -1209,7 +1297,7 @@ sed -i 's#!/bin/env python3#!/usr/bin/python3#' %{buildroot}%{_qt6_examplesdir}/
%{_qt6_includedir}/QtXml/
%{_qt6_libdir}/libQt6Xml.prl
%{_qt6_libdir}/libQt6Xml.so
%{_qt6_metatypesdir}/qt6xml_*_metatypes.json
%{_qt6_metatypesdir}/qt6xml_metatypes.json
%{_qt6_mkspecsdir}/modules/qt_lib_xml.pri
%{_qt6_pkgconfigdir}/Qt6Xml.pc
%exclude %{_qt6_includedir}/QtXml/%{real_version}
@@ -1225,6 +1313,26 @@ sed -i 's#!/bin/env python3#!/usr/bin/python3#' %{buildroot}%{_qt6_examplesdir}/
%{_qt6_docdir}/config/
%{_qt6_docdir}/global/
### Private only libraries ###
%files -n qt6-waylandglobal-private-devel
%{_qt6_cmakedir}/Qt6WaylandGlobalPrivate/
%{_qt6_descriptionsdir}/WaylandGlobalPrivate.json
%{_qt6_includedir}/QtWaylandGlobal/
%{_qt6_mkspecsdir}/modules/qt_lib_waylandglobal_private.pri
%files -n libQt6WlShellIntegration6
%{_qt6_libdir}/libQt6WlShellIntegration.so.*
%files -n qt6-wlshellintegration-private-devel
%{_qt6_cmakedir}/Qt6WlShellIntegrationPrivate/
%{_qt6_descriptionsdir}/WlShellIntegrationPrivate.json
%{_qt6_includedir}/QtWlShellIntegration/
%{_qt6_libdir}/libQt6WlShellIntegration.prl
%{_qt6_libdir}/libQt6WlShellIntegration.so
%{_qt6_metatypesdir}/qt6wlshellintegrationprivate_metatypes.json
%{_qt6_mkspecsdir}/modules/qt_lib_wl_shell_integration_private.pri
### Static libraries ###
%files -n qt6-exampleicons-devel-static
@@ -1238,7 +1346,7 @@ sed -i 's#!/bin/env python3#!/usr/bin/python3#' %{buildroot}%{_qt6_examplesdir}/
# These are CMake objects files which are not part of any library
%dir %{_qt6_archdatadir}/objects-*
%{_qt6_archdatadir}/objects-*/ExampleIconsPrivate_resources_1/
%{_qt6_metatypesdir}/qt6exampleiconsprivate_*_metatypes.json
%{_qt6_metatypesdir}/qt6exampleiconsprivate_metatypes.json
%files -n qt6-kmssupport-devel-static
%{_qt6_cmakedir}/Qt6KmsSupportPrivate/
@@ -1246,7 +1354,7 @@ sed -i 's#!/bin/env python3#!/usr/bin/python3#' %{buildroot}%{_qt6_examplesdir}/
%{_qt6_includedir}/QtKmsSupport/
%{_qt6_libdir}/libQt6KmsSupport.a
%{_qt6_libdir}/libQt6KmsSupport.prl
%{_qt6_metatypesdir}/qt6kmssupportprivate_*_metatypes.json
%{_qt6_metatypesdir}/qt6kmssupportprivate_metatypes.json
%exclude %{_qt6_includedir}/QtKmsSupport/%{real_version}
%files -n qt6-kmssupport-private-devel
@@ -1270,9 +1378,9 @@ sed -i 's#!/bin/env python3#!/usr/bin/python3#' %{buildroot}%{_qt6_examplesdir}/
%{_qt6_libdir}/libQt6FbSupport.prl
%{_qt6_libdir}/libQt6InputSupport.a
%{_qt6_libdir}/libQt6InputSupport.prl
%{_qt6_metatypesdir}/qt6devicediscoverysupportprivate_*_metatypes.json
%{_qt6_metatypesdir}/qt6fbsupportprivate_*_metatypes.json
%{_qt6_metatypesdir}/qt6inputsupportprivate_*_metatypes.json
%{_qt6_metatypesdir}/qt6devicediscoverysupportprivate_metatypes.json
%{_qt6_metatypesdir}/qt6fbsupportprivate_metatypes.json
%{_qt6_metatypesdir}/qt6inputsupportprivate_metatypes.json
%exclude %{_qt6_includedir}/QtDeviceDiscoverySupport/%{real_version}
%exclude %{_qt6_includedir}/QtFbSupport/%{real_version}
%exclude %{_qt6_includedir}/QtInputSupport/%{real_version}
@@ -1322,6 +1430,12 @@ sed -i 's#!/bin/env python3#!/usr/bin/python3#' %{buildroot}%{_qt6_examplesdir}/
%files -n qt6-sql-unixODBC
%{_qt6_pluginsdir}/sqldrivers/libqsqlodbc.so
%files -n qt6-wayland
%{_qt6_datadir}/wayland/
%{_qt6_libexecdir}/qtwaylandscanner
%{_qt6_pluginsdir}/wayland-decoration-client/
%{_qt6_pluginsdir}/wayland-graphics-integration-client/
%{_qt6_pluginsdir}/wayland-shell-integration/
%endif
%changelog

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:aeb78d29291a2b5fd53cb55950f8f5065b4978c25fb1d77f627d695ab9adf21e
size 50374380

Binary file not shown.