[neon/qt6/qt6-base/Neon/release] debian: refresh patches and links to usr/bin/

Carlos De Maine null at kde.org
Mon Nov 17 02:48:27 GMT 2025


Git commit ce4e6d55f57d7d460df0904b887aca699b553e39 by Carlos De Maine.
Committed on 17/11/2025 at 02:48.
Pushed by carlosdem into branch 'Neon/release'.

refresh patches and links to usr/bin/

A  +534  -0    debian/patches/0001-fix-slow-scrolling-on-wayland.patch
M  +4    -0    debian/patches/Add-SH-detection.patch
D  +0    -57   debian/patches/be_verbose_on_plugin_inclusion.patch
M  +3    -5    debian/patches/build_path_embedded_qtbuildinternalsextra_cmake.patch
M  +3    -3    debian/patches/cross.patch
M  +22   -5    debian/patches/enable_skip_plugins.patch
M  +5    -1    debian/patches/forkfd_grow_stack_upwards_on_hppa.patch
M  +1    -1    debian/patches/remove_privacy_breaches.diff
M  +1    -3    debian/patches/series
M  +0    -1    debian/qt6-base-dev.install
M  +9    -0    debian/qt6-base-dev.links
M  +1    -1    debian/qt6-base.install

https://invent.kde.org/neon/qt6/qt6-base/-/commit/ce4e6d55f57d7d460df0904b887aca699b553e39

diff --git a/debian/patches/0001-fix-slow-scrolling-on-wayland.patch b/debian/patches/0001-fix-slow-scrolling-on-wayland.patch
new file mode 100644
index 0000000..4440661
--- /dev/null
+++ b/debian/patches/0001-fix-slow-scrolling-on-wayland.patch
@@ -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 c845cfa7eec..f463d7364ca 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 170e80f806c..5f927fca51a 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 bcaf025840d..b9582daf32c 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 669d47ee3b8..fc869de669f 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 d8fc7b18ca3..591e5064ebd 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.
+@@ -289,6 +311,8 @@ void QWaylandShmBackingStore::flush(QWindow *window, const QRegion &region, 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 efd80159e85..cfcafb28326 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 04400e3f26a..09ac4f7f81d 100644
+--- a/tests/auto/wayland/client/tst_client.cpp
++++ b/tests/auto/wayland/client/tst_client.cpp
+@@ -276,6 +276,8 @@ void tst_WaylandClient::events()
+     exec([&] {
+         pointer()->sendEnter(s, window.frameOffset() + mousePressPos);
+         pointer()->sendFrame(client());
++        pointer()->sendMotion(client(), window.frameOffset() + mousePressPos / 2);
++        pointer()->sendFrame(client());
+         pointer()->sendMotion(client(), window.frameOffset() + mousePressPos);
+         pointer()->sendFrame(client());
+         pointer()->sendButton(client(), BTN_LEFT, Pointer::button_state_pressed);
diff --git a/debian/patches/Add-SH-detection.patch b/debian/patches/Add-SH-detection.patch
index 1e02454..6fce938 100644
--- a/debian/patches/Add-SH-detection.patch
+++ b/debian/patches/Add-SH-detection.patch
@@ -7,6 +7,10 @@ Author: John Paul Adrian Glaubitz <glaubitz at physik.fu-berlin.de>
 Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1043225
 Reviewed-by: Lisandro Damián Nicanor Pérez Meyer <lisandro at debian.org>
 
+---
+ src/corelib/global/qprocessordetection.h |   12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
 --- a/src/corelib/global/qprocessordetection.h
 +++ b/src/corelib/global/qprocessordetection.h
 @@ -311,12 +311,12 @@
diff --git a/debian/patches/be_verbose_on_plugin_inclusion.patch b/debian/patches/be_verbose_on_plugin_inclusion.patch
deleted file mode 100644
index 5b62a6d..0000000
--- a/debian/patches/be_verbose_on_plugin_inclusion.patch
+++ /dev/null
@@ -1,57 +0,0 @@
-From c8e2cdda704dbe2c381091fe687653cdf2b191ca Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Lisandro=20Dami=C3=A1n=20Nicanor=20P=C3=A9rez=20Meyer?=
- <perezmeyer at gmail.com>
-Date: Wed, 1 Nov 2023 21:41:59 -0300
-Subject: [PATCH] Be verbose on plugin inclusion, easy patch point for distros
-
-TL;DR: This creates two changes:
-
-1. Makes the plugin inclusion status more visible for builders for both Qt
-   itself and applications.
-2. Allows a simple patch-point for distros to change the default
-   (perhaps not ideal, but good enough).
-3. Does not changes the current behavior.
-
-As discussed both in the mailing list and privately with
-Alexandru Croitor and Joerg Bornemann this makes a lot os sense for Qt
-on static builds and when trying to find where the plugins are so they
-can be easily packaged up in order to distribute a build with all the
-dependencies on it.
-
-But at the same time it makes no sense for distributions building the
-libraries in dynamic mode as it forces unnecesary build time
-dependencies for for both Qt and applications like QML modules or even
-PostgreSQL! [0].
-
-[0] <https://sources.debian.org/src/martchus-qtutilities/6.10.0-1/cmake/modules/QtConfig.cmake/?hl=35#L35>
-
-Other approaches have been considered like not shipping specific CMake
-files, but this depends on the packager finding the right ones at the
-right time, and does not allows end users to change the behavior if they
-happen to need it.
-
-Change-Id: Id32fbc0cf0f289edd4426fb703cf1195288aacb4
-Gerrit: https://codereview.qt-project.org/c/qt/qtbase/+/515440
----
- cmake/QtPlugins.cmake.in         | 9 +++++++++
- cmake/QtPostProcessHelpers.cmake | 9 +++++++++
- 2 files changed, 18 insertions(+)
-
---- a/cmake/QtPlugins.cmake.in
-+++ b/cmake/QtPlugins.cmake.in
-@@ -9,6 +9,15 @@
-     set(QT_SKIP_AUTO_PLUGIN_INCLUSION OFF)
- endif()
- 
-+# Distributions should probably change this default.
-+if(NOT DEFINED QT_SKIP_AUTO_PLUGIN_INCLUSION)
-+    set(QT_SKIP_AUTO_PLUGIN_INCLUSION OFF)
-+endif()
-+
-+if(QT_REPO_MODULE_VERSION)
-+    message(STATUS "Skip auto plugin inclusion is set to ${QT_SKIP_AUTO_PLUGIN_INCLUSION}")
-+endif()
-+
- if(NOT QT_NO_CREATE_TARGETS AND NOT QT_SKIP_AUTO_PLUGIN_INCLUSION)
-     __qt_internal_include_plugin_packages(@QT_MODULE@)
- endif()
diff --git a/debian/patches/build_path_embedded_qtbuildinternalsextra_cmake.patch b/debian/patches/build_path_embedded_qtbuildinternalsextra_cmake.patch
index 314fb80..6d0f3f6 100644
--- a/debian/patches/build_path_embedded_qtbuildinternalsextra_cmake.patch
+++ b/debian/patches/build_path_embedded_qtbuildinternalsextra_cmake.patch
@@ -12,11 +12,9 @@ https://reproducible-builds.org/docs/build-path/
  cmake/QtBuildInternalsExtra.cmake.in |    3 ---
  1 file changed, 3 deletions(-)
 
-Index: qtbase-everywhere-src-6.7.0/cmake/QtBuildInternalsExtra.cmake.in
-===================================================================
---- qtbase-everywhere-src-6.7.0.orig/cmake/QtBuildInternalsExtra.cmake.in
-+++ qtbase-everywhere-src-6.7.0/cmake/QtBuildInternalsExtra.cmake.in
-@@ -77,9 +77,6 @@ endif()
+--- a/cmake/QtBuildInternalsExtra.cmake.in
++++ b/cmake/QtBuildInternalsExtra.cmake.in
+@@ -74,9 +74,6 @@ endif()
  set(QT_WILL_INSTALL @QT_WILL_INSTALL@ CACHE BOOL
      "Boolean indicating if doing a Qt prefix build (vs non-prefix build)." FORCE)
  
diff --git a/debian/patches/cross.patch b/debian/patches/cross.patch
index d2a5cf7..2a66e8f 100644
--- a/debian/patches/cross.patch
+++ b/debian/patches/cross.patch
@@ -2,7 +2,7 @@
  examples/sql/CMakeLists.txt                         |    2 +-
  src/tools/configure.cmake                           |    2 +-
  3 files changed, 2 insertions(+), 4 deletions(-)
-
+ 
 --- a/src/tools/configure.cmake
 +++ b/src/tools/configure.cmake
 @@ -5,7 +5,7 @@ qt_feature("androiddeployqt" PRIVATE
@@ -11,7 +11,7 @@
      PURPOSE "The Android deployment tool automates the process of creating Android packages."
 -    CONDITION NOT CMAKE_CROSSCOMPILING AND QT_FEATURE_regularexpression AND QT_FEATURE_settings)
 +    CONDITION (QT_FORCE_BUILD_TOOLS OR NOT CMAKE_CROSSCOMPILING) AND QT_FEATURE_regularexpression)
-
+ 
  qt_feature("macdeployqt" PRIVATE
      SECTION "Deployment"
 --- a/examples/sql/CMakeLists.txt
@@ -19,7 +19,7 @@
 @@ -15,6 +15,6 @@ if(TARGET Qt6::Xml)
      qt_internal_add_example(masterdetail)
  endif()
-
+ 
 -if(NOT CMAKE_CROSSCOMPILING)
 +if(QT_FORCE_BUILD_TOOLS OR NOT CMAKE_CROSSCOMPILING)
      qt_internal_add_example(sqlbrowser)
diff --git a/debian/patches/enable_skip_plugins.patch b/debian/patches/enable_skip_plugins.patch
index 5adb104..f09202a 100644
--- a/debian/patches/enable_skip_plugins.patch
+++ b/debian/patches/enable_skip_plugins.patch
@@ -1,17 +1,34 @@
+Description: Enable skipping plugins search at build time.
+ This patch sets
+ QT_SKIP_AUTO_PLUGIN_INCLUSION and QT_SKIP_AUTO_QML_PLUGIN_INCLUSION to ON
+ by default, thus avoiding unnecesary build dependencies on plugins.
+ .
+ The variables can still be set to OFF by the user at build time, allowing
+ them to find the packages if necessary. But if you need so for a Debian
+ package please reach the Qt maintainers first. We want to know why you
+ need to do so. Thanks in advance!
+Author: Lisandro Damián Nicanor Pérez Meyer <lisandro at debian.org>
+Forwarded: not-needed
+
+---
+ cmake/QtPlugins.cmake.in         |    2 +-
+ cmake/QtPostProcessHelpers.cmake |    2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
 --- a/cmake/QtPlugins.cmake.in
 +++ b/cmake/QtPlugins.cmake.in
-@@ -11,7 +11,7 @@ endif()
- 
+@@ -6,7 +6,7 @@ include_guard(DIRECTORY)
+
  # Distributions should probably change this default.
  if(NOT DEFINED QT_SKIP_AUTO_PLUGIN_INCLUSION)
 -    set(QT_SKIP_AUTO_PLUGIN_INCLUSION OFF)
 +    set(QT_SKIP_AUTO_PLUGIN_INCLUSION ON)
  endif()
- 
- if(QT_REPO_MODULE_VERSION)
+
+ if(NOT QT_NO_CREATE_TARGETS AND NOT QT_SKIP_AUTO_PLUGIN_INCLUSION)
 --- a/cmake/QtPublicPluginHelpers.cmake
 +++ b/cmake/QtPublicPluginHelpers.cmake
-@@ -601,7 +601,7 @@ macro(__qt_internal_include_qml_plugin_packages)
+@@ -649,7 +649,7 @@ macro(__qt_internal_include_qml_plugin_packages)
  
      # Distributions should probably change this default.
      if(NOT DEFINED QT_SKIP_AUTO_QML_PLUGIN_INCLUSION)
diff --git a/debian/patches/forkfd_grow_stack_upwards_on_hppa.patch b/debian/patches/forkfd_grow_stack_upwards_on_hppa.patch
index 11cc7c8..50b205f 100644
--- a/debian/patches/forkfd_grow_stack_upwards_on_hppa.patch
+++ b/debian/patches/forkfd_grow_stack_upwards_on_hppa.patch
@@ -6,9 +6,13 @@ Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1042018
 Reviewed-by: Lisandro Damián Nicanor Pérez Meyer <lisandro at debian.org>
 Last-Update: 2023-07-28
 
+---
+ src/3rdparty/forkfd/forkfd_linux.c |    5 +++++
+ 1 file changed, 5 insertions(+)
+
 --- a/src/3rdparty/forkfd/forkfd_linux.c
 +++ b/src/3rdparty/forkfd/forkfd_linux.c
-@@ -169,7 +169,12 @@
+@@ -169,7 +169,12 @@ int system_vforkfd(int flags, pid_t *ppi
      }
      *system = 1;
  
diff --git a/debian/patches/remove_privacy_breaches.diff b/debian/patches/remove_privacy_breaches.diff
index b61f9c7..e911149 100644
--- a/debian/patches/remove_privacy_breaches.diff
+++ b/debian/patches/remove_privacy_breaches.diff
@@ -12,7 +12,7 @@ Last-Update: 2015-02-18
 
 --- a/doc/global/template/scripts/main.js
 +++ b/doc/global/template/scripts/main.js
-@@ -94,11 +94,6 @@
+@@ -94,11 +94,6 @@ $(document).ready(function($) {
  });
  
  $( window ).load(function() {
diff --git a/debian/patches/series b/debian/patches/series
index 874bf2f..6693071 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1,11 +1,9 @@
 # Neon added
+0001-fix-slow-scrolling-on-wayland.patch
 
 # Needs to be fixed upstream.
 Add-SH-detection.patch
 
-# Pushed to gerrit
-be_verbose_on_plugin_inclusion.patch
-
 # Debian specific
 build_path_embedded_qtbuildinternalsextra_cmake.patch
 cross.patch
diff --git a/debian/qt6-base-dev.install b/debian/qt6-base-dev.install
index 2c6b5e6..77934cf 100755
--- a/debian/qt6-base-dev.install
+++ b/debian/qt6-base-dev.install
@@ -10,7 +10,6 @@ usr/lib/${DEB_HOST_MULTIARCH}/qt6/mkspecs/
 usr/lib/${DEB_HOST_MULTIARCH}/qt6/sbom/
 usr/lib/${DEB_HOST_MULTIARCH}/pkgconfig/
 usr/lib/qt6/bin/androiddeployqt
-usr/lib/qt6/bin/androiddeployqt6
 usr/lib/qt6/bin/androidtestrunner
 usr/lib/qt6/bin/qdbuscpp2xml
 usr/lib/qt6/bin/qdbusxml2cpp
diff --git a/debian/qt6-base-dev.links b/debian/qt6-base-dev.links
index 750afd9..9f6afa2 100644
--- a/debian/qt6-base-dev.links
+++ b/debian/qt6-base-dev.links
@@ -3,8 +3,17 @@
 usr/lib/qt6/bin/qtpaths6 usr/lib/qt6/bin/qtpaths
 # On public path we want qtpaths6.
 usr/lib/qt6/bin/qtpaths6 usr/bin/qtpaths6
+
 # androiddeployqt and androiddeployqt6 are identical files. We want people to use androiddeployqt6,
 # so we do not install androiddeployqt. Instead, androiddeployqt is a symbolic link pointing to androiddeployqt6.
 usr/lib/qt6/bin/androiddeployqt6 usr/lib/qt6/bin/androiddeployqt
 # On public path we want androiddeployqt6.
 usr/lib/qt6/bin/androiddeployqt6 usr/bin/androiddeployqt6
+
+usr/lib/qt6/bin/androidtestrunner usr/bin/androidtestrunner6
+usr/lib/qt6/bin/qdbuscpp2xmlusr/bin/qdbuscpp2xmlusr6
+usr/lib/qt6/bin/qdbusxml2cpp usr/bin/qdbusxml2cpp6
+usr/lib/qt6/bin/qt-cmake usr/bin/qt-cmake6
+usr/lib/qt6/bin/qt-cmake-create usr/bin/qt-cmake-create6
+usr/lib/qt6/bin/qt-configure-module usr/bin/qt-configure-module6
+usr/lib/qt6/bin/qtpaths usr/bin/qtpaths6
diff --git a/debian/qt6-base.install b/debian/qt6-base.install
index 9e3f99d..def0f30 100644
--- a/debian/qt6-base.install
+++ b/debian/qt6-base.install
@@ -5,7 +5,7 @@ usr/lib/${DEB_HOST_MULTIARCH}/qt6/examples/
 usr/lib/${DEB_HOST_MULTIARCH}/qt6/modules/
 usr/lib/${DEB_HOST_MULTIARCH}/qt6/plugins/
 usr/lib/${DEB_HOST_MULTIARCH}/qt6/qt6.conf
-usr/lib/qt6/bin/qmake6
+usr/lib/qt6/bin/qmake
 usr/lib/qt6/libexec/qt-internal-configure-examples
 usr/lib/qt6/libexec/qtwaylandscanner
 usr/share/qt6/wayland/extensions/


More information about the Neon-commits mailing list