[neon/kde/plasma-discover/Neon/release] debian/patches: backport from master branch to stop updates never finishng

Carlos De Maine null at kde.org
Mon Jun 22 23:03:50 BST 2026


Git commit f5e96c77ee6e2df707e6dc72f660ab28262f75f5 by Carlos De Maine.
Committed on 22/06/2026 at 22:03.
Pushed by carlosdem into branch 'Neon/release'.

backport from master branch to stop updates never finishng

A  +188  -0    debian/patches/b71c614b4d26d91d3bb00452faf14830bf31765b.diff
A  +137  -0    debian/patches/bd8dca6b797b64bc319a7ae2c1854b5e4f4069bb.diff
A  +146  -0    debian/patches/d4415b20f24cf0a181d6e3a7316dc200fbe1ce78.diff
M  +3    -0    debian/patches/series

https://invent.kde.org/neon/kde/plasma-discover/-/commit/f5e96c77ee6e2df707e6dc72f660ab28262f75f5

diff --git a/debian/patches/b71c614b4d26d91d3bb00452faf14830bf31765b.diff b/debian/patches/b71c614b4d26d91d3bb00452faf14830bf31765b.diff
new file mode 100644
index 0000000..9901ba0
--- /dev/null
+++ b/debian/patches/b71c614b4d26d91d3bb00452faf14830bf31765b.diff
@@ -0,0 +1,188 @@
+commit b71c614b4d26d91d3bb00452faf14830bf31765b
+Author: Aleix Pol <aleixpol at kde.org>
+Date:   Fri Apr 17 18:08:30 2026 +0200
+
+    rebase on master
+
+diff --git a/libdiscover/EmitWhenChanged.h b/libdiscover/EmitWhenChanged.h
+new file mode 100644
+index 000000000..c4237ffe8
+--- /dev/null
++++ b/libdiscover/EmitWhenChanged.h
+@@ -0,0 +1,35 @@
++/*
++ *   SPDX-FileCopyrightText: 2020 Aleix Pol Gonzalez <aleixpol at kde.org>
++ *
++ *   SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
++ */
++
++#pragma once
++
++#include <QObject>
++#include <functional>
++
++template<typename T>
++class EmitWhenChanged : public QObject
++{
++public:
++    EmitWhenChanged(T initial, const std::function<T()> &get, const std::function<void(T)> &emitChanged)
++        : m_get(get)
++        , m_emitChanged(emitChanged)
++        , m_value(initial)
++    {
++    }
++
++    void reevaluate()
++    {
++        const T newValue = m_get();
++        if (newValue != m_value) {
++            m_value = newValue;
++            m_emitChanged(m_value);
++        }
++    }
++
++    std::function<T()> const m_get;
++    std::function<void(T)> const m_emitChanged;
++    T m_value;
++};
+diff --git a/libdiscover/resources/ResourcesModel.cpp b/libdiscover/resources/ResourcesModel.cpp
+index e96bddd7d..543e7e41b 100644
+--- a/libdiscover/resources/ResourcesModel.cpp
++++ b/libdiscover/resources/ResourcesModel.cpp
+@@ -153,12 +153,8 @@ bool ResourcesModel::addResourcesBackend(AbstractResourcesBackend *backend)
+     connect(backend, &AbstractResourcesBackend::contentsChanged, this, &ResourcesModel::callerContentsChanged);
+     connect(backend, &AbstractResourcesBackend::allDataChanged, this, &ResourcesModel::updateCaller);
+     connect(backend, &AbstractResourcesBackend::resourcesChanged, this, &ResourcesModel::resourceDataChanged);
+-    connect(backend, &AbstractResourcesBackend::updatesCountChanged, this, [this] {
+-        m_updatesCount.reevaluate();
+-    });
+-    connect(backend, &AbstractResourcesBackend::fetchingUpdatesProgressChanged, this, [this] {
+-        m_fetchingUpdatesProgress.reevaluate();
+-    });
++    connect(backend, &AbstractResourcesBackend::updatesCountChanged, &m_updatesCount, &EmitWhenChanged<int>::reevaluate);
++    connect(backend, &AbstractResourcesBackend::fetchingUpdatesProgressChanged, &m_fetchingUpdatesProgress, &EmitWhenChanged<int>::reevaluate);
+     connect(backend, &AbstractResourcesBackend::resourceRemoved, this, &ResourcesModel::resourceRemoved);
+     connect(backend, &AbstractResourcesBackend::passiveMessage, this, &ResourcesModel::passiveMessage);
+     connect(backend, &AbstractResourcesBackend::inlineMessageChanged, this, &ResourcesModel::setInlineMessage);
+diff --git a/libdiscover/resources/ResourcesModel.h b/libdiscover/resources/ResourcesModel.h
+index 9341b8b3a..0958b6425 100644
+--- a/libdiscover/resources/ResourcesModel.h
++++ b/libdiscover/resources/ResourcesModel.h
+@@ -6,6 +6,7 @@
+ 
+ #pragma once
+ 
++#include "EmitWhenChanged.h"
+ #include <QSet>
+ #include <QTimer>
+ #include <QVector>
+@@ -42,31 +43,6 @@ private:
+     QTimer m_delayedEmission;
+ };
+ 
+-template<typename T>
+-class EmitWhenChanged
+-{
+-public:
+-    EmitWhenChanged(T initial, const std::function<T()> &get, const std::function<void(T)> &emitChanged)
+-        : m_get(get)
+-        , m_emitChanged(emitChanged)
+-        , m_value(initial)
+-    {
+-    }
+-
+-    void reevaluate()
+-    {
+-        auto newValue = m_get();
+-        if (newValue != m_value) {
+-            m_value = newValue;
+-            m_emitChanged(m_value);
+-        }
+-    }
+-
+-    std::function<T()> const m_get;
+-    std::function<void(T)> const m_emitChanged;
+-    T m_value;
+-};
+-
+ class DISCOVERCOMMON_EXPORT ResourcesModel : public QObject
+ {
+     Q_OBJECT
+diff --git a/libdiscover/resources/StandardBackendUpdater.cpp b/libdiscover/resources/StandardBackendUpdater.cpp
+index 54f786ab1..a1fbfdf4d 100644
+--- a/libdiscover/resources/StandardBackendUpdater.cpp
++++ b/libdiscover/resources/StandardBackendUpdater.cpp
+@@ -20,11 +20,20 @@ StandardBackendUpdater::StandardBackendUpdater(AbstractResourcesBackend *parent)
+     , m_backend(parent)
+     , m_progress(0)
+     , m_lastUpdate(QDateTime())
++    , m_isFetchingUpdates(
++          false,
++          [this] {
++              return m_backend->fetchingUpdatesProgress() != 100 || m_settingUp;
++          },
++          [this](bool) {
++              Q_EMIT fetchingChanged();
++          })
+ {
++    setObjectName(parent->displayName());
+     connect(m_backend, &AbstractResourcesBackend::contentsChanged, this, &StandardBackendUpdater::refreshUpdateable);
+     connect(m_backend, &AbstractResourcesBackend::invalidated, this, &StandardBackendUpdater::refreshUpdateable);
+     connect(m_backend, &AbstractResourcesBackend::resourcesChanged, this, &StandardBackendUpdater::resourcesChanged);
+-    connect(m_backend, &AbstractResourcesBackend::fetchingUpdatesProgressChanged, this, &StandardBackendUpdater::fetchingChanged);
++    connect(m_backend, &AbstractResourcesBackend::fetchingUpdatesProgressChanged, &m_isFetchingUpdates, &EmitWhenChanged<bool>::reevaluate);
+     connect(m_backend, &AbstractResourcesBackend::resourceRemoved, this, [this](AbstractResource *resource) {
+         if (m_upgradeable.remove(resource)) {
+             Q_EMIT updatesCountChanged(updatesCount());
+@@ -125,7 +134,7 @@ AbstractBackendUpdater::State toUpdateState(Transaction *t)
+ 
+ bool StandardBackendUpdater::isFetchingUpdates() const
+ {
+-    return m_backend->fetchingUpdatesProgress() != 100 || m_settingUp || !m_hasBeenPopulated;
++    return m_isFetchingUpdates.m_value;
+ }
+ 
+ void StandardBackendUpdater::transactionProgressChanged()
+@@ -190,7 +199,7 @@ void StandardBackendUpdater::refreshUpdateable()
+     m_timer.stop();
+     setSettingUp(true);
+     Q_EMIT progressingChanged(true);
+-    Q_EMIT fetchingChanged();
++    m_isFetchingUpdates.reevaluate();
+     AbstractResourcesBackend::Filters f;
+     f.state = AbstractResource::Upgradeable;
+     m_upgradeable.clear();
+@@ -211,7 +220,7 @@ void StandardBackendUpdater::refreshUpdateable()
+         setSettingUp(false);
+         Q_EMIT updatesCountChanged(updatesCount());
+         Q_EMIT progressingChanged(false);
+-        Q_EMIT fetchingChanged();
++        m_isFetchingUpdates.reevaluate();
+     });
+ }
+ 
+@@ -327,4 +336,4 @@ void StandardBackendUpdater::setSettingUp(bool settingUp)
+     Q_EMIT settingUpChanged();
+ }
+ 
+-#include "moc_StandardBackendUpdater.cpp"
++#include "moc_StandardBackendUpdater.cpp"
+\ No newline at end of file
+diff --git a/libdiscover/resources/StandardBackendUpdater.h b/libdiscover/resources/StandardBackendUpdater.h
+index cd0c3e01c..273d156e0 100644
+--- a/libdiscover/resources/StandardBackendUpdater.h
++++ b/libdiscover/resources/StandardBackendUpdater.h
+@@ -8,6 +8,7 @@
+ 
+ #include "AbstractResourcesBackend.h"
+ #include "discovercommon_export.h"
++#include <EmitWhenChanged.h>
+ #include <QDateTime>
+ #include <QSet>
+ #include <QTimer>
+@@ -75,4 +76,5 @@ private:
+     QTimer m_timer;
+     bool m_canCancel = false;
+     bool m_anyTransactionFailed = false;
++    EmitWhenChanged<bool> m_isFetchingUpdates;
+ };
diff --git a/debian/patches/bd8dca6b797b64bc319a7ae2c1854b5e4f4069bb.diff b/debian/patches/bd8dca6b797b64bc319a7ae2c1854b5e4f4069bb.diff
new file mode 100644
index 0000000..44f4d81
--- /dev/null
+++ b/debian/patches/bd8dca6b797b64bc319a7ae2c1854b5e4f4069bb.diff
@@ -0,0 +1,137 @@
+commit bd8dca6b797b64bc319a7ae2c1854b5e4f4069bb
+Author: Aleix Pol <aleixpol at kde.org>
+Date:   Sat May 23 17:51:27 2026 +0200
+
+    Remember to ignore invisible transactions
+    
+    They're not accounted for in the totalItems calculation originally.
+    
+    Define the visible property as immutable so that there is no need to
+    track the visibility.
+    
+    See
+    https://crash-reports.kde.org/organizations/kde/issues/401665/events/24ff29748e5a44fbb47db9ce5d471413
+    
+    (cherry picked from commit 262f5ec136b7bc0c8f1368f6598af87679b60b94)
+
+diff --git a/discover/DiscoverObject.cpp b/discover/DiscoverObject.cpp
+index 39edd0606..3b75f7fb4 100644
+--- a/discover/DiscoverObject.cpp
++++ b/discover/DiscoverObject.cpp
+@@ -458,8 +458,11 @@ public:
+         updateDescription();
+     }
+ 
+-    void onTransactionAdded()
++    void onTransactionAdded(Transaction *newTransaction)
+     {
++        if (!newTransaction->isVisible()) {
++            return;
++        }
+         const auto oldAmount = totalAmount(Items);
+         // Very unlikely to happen but let's be safe. We don't want to overflow.
+         Q_ASSERT(oldAmount < std::numeric_limits<qulonglong>::max());
+@@ -467,8 +470,11 @@ public:
+         setTotalAmount(Items, newAmount);
+     }
+ 
+-    void onTransactionRemoved()
++    void onTransactionRemoved(Transaction *transaction)
+     {
++        if (!transaction->isVisible()) {
++            return;
++        }
+         const auto oldAmount = totalAmount(Items);
+         // In an ideal world we'd not do subtractions on unsigned values as they could underflow. Unfortunately we deal
+         // with 64bit unsigned here, so doing a safe subtraction is difficult. Be assertive instead.
+diff --git a/libdiscover/Transaction/Transaction.cpp b/libdiscover/Transaction/Transaction.cpp
+index ec8c11f8c..4a603cc29 100644
+--- a/libdiscover/Transaction/Transaction.cpp
++++ b/libdiscover/Transaction/Transaction.cpp
+@@ -12,7 +12,7 @@
+ #include <KLocalizedString>
+ #include <resources/AbstractResource.h>
+ 
+-Transaction::Transaction(QObject *parent, AbstractResource *resource, Role role, const AddonList &addons)
++Transaction::Transaction(QObject *parent, AbstractResource *resource, Role role, const AddonList &addons, bool visible)
+     : QObject(parent)
+     , m_resource(resource)
+     , m_role(role)
+@@ -20,6 +20,7 @@ Transaction::Transaction(QObject *parent, AbstractResource *resource, Role role,
+     , m_addons(addons)
+     , m_isCancellable(true)
+     , m_progress(0)
++    , m_visible(visible)
+ {
+ }
+ 
+@@ -112,14 +113,6 @@ bool Transaction::isVisible() const
+     return m_visible;
+ }
+ 
+-void Transaction::setVisible(bool visible)
+-{
+-    if (m_visible != visible) {
+-        m_visible = visible;
+-        Q_EMIT visibleChanged(visible);
+-    }
+-}
+-
+ void Transaction::setDownloadSpeed(quint64 downloadSpeed)
+ {
+     if (downloadSpeed != m_downloadSpeed) {
+diff --git a/libdiscover/Transaction/Transaction.h b/libdiscover/Transaction/Transaction.h
+index 549151509..be9f3cfa0 100644
+--- a/libdiscover/Transaction/Transaction.h
++++ b/libdiscover/Transaction/Transaction.h
+@@ -35,7 +35,7 @@ class DISCOVERCOMMON_EXPORT Transaction : public QObject
+     Q_PROPERTY(Status status READ status NOTIFY statusChanged)
+     Q_PROPERTY(bool isCancellable READ isCancellable NOTIFY cancellableChanged)
+     Q_PROPERTY(int progress READ progress NOTIFY progressChanged)
+-    Q_PROPERTY(bool visible READ isVisible WRITE setVisible NOTIFY visibleChanged)
++    Q_PROPERTY(bool visible READ isVisible CONSTANT)
+     Q_PROPERTY(quint64 downloadSpeed READ downloadSpeed WRITE setDownloadSpeed NOTIFY downloadSpeedChanged)
+     Q_PROPERTY(QString downloadSpeedString READ downloadSpeedString NOTIFY downloadSpeedChanged)
+     Q_PROPERTY(QString remainingTimeString READ remainingTimeString NOTIFY remainingTimeChanged)
+@@ -70,7 +70,7 @@ public:
+     };
+     Q_ENUM(Role)
+ 
+-    Transaction(QObject *parent, AbstractResource *resource, Transaction::Role role, const AddonList &addons = {});
++    Transaction(QObject *parent, AbstractResource *resource, Transaction::Role role, const AddonList &addons = {}, bool visible = true);
+ 
+     ~Transaction() override;
+ 
+@@ -136,7 +136,6 @@ public:
+     virtual QVariant icon() const;
+ 
+     bool isVisible() const;
+-    void setVisible(bool v);
+ 
+     quint64 downloadSpeed() const
+     {
+@@ -195,8 +194,6 @@ Q_SIGNALS:
+      */
+     void distroErrorMessage(const QString &message);
+ 
+-    void visibleChanged(bool visible);
+-
+     void downloadSpeedChanged(quint64 downloadSpeed);
+ 
+     void remainingTimeChanged(uint remainingTime);
+diff --git a/libdiscover/resources/ResourcesUpdatesModel.cpp b/libdiscover/resources/ResourcesUpdatesModel.cpp
+index f83dd9347..ce6d59aa3 100644
+--- a/libdiscover/resources/ResourcesUpdatesModel.cpp
++++ b/libdiscover/resources/ResourcesUpdatesModel.cpp
+@@ -26,10 +26,9 @@ class UpdateTransaction : public Transaction
+     Q_OBJECT
+ public:
+     UpdateTransaction(ResourcesUpdatesModel * /*parent*/, const QVector<AbstractBackendUpdater *> &updaters)
+-        : Transaction(nullptr, nullptr, Transaction::InstallRole)
++        : Transaction(nullptr, nullptr, Transaction::InstallRole, {}, false /*not visible*/)
+         , m_allUpdaters(updaters)
+     {
+-        setVisible(false);
+         bool cancelable = false;
+         for (auto updater : std::as_const(m_allUpdaters)) {
+             connect(updater, &AbstractBackendUpdater::progressingChanged, this, &UpdateTransaction::slotProgressingChanged);
diff --git a/debian/patches/d4415b20f24cf0a181d6e3a7316dc200fbe1ce78.diff b/debian/patches/d4415b20f24cf0a181d6e3a7316dc200fbe1ce78.diff
new file mode 100644
index 0000000..43491a7
--- /dev/null
+++ b/debian/patches/d4415b20f24cf0a181d6e3a7316dc200fbe1ce78.diff
@@ -0,0 +1,146 @@
+commit d4415b20f24cf0a181d6e3a7316dc200fbe1ce78
+Author: Aleix Pol <aleixpol at kde.org>
+Date:   Sun Dec 14 02:04:23 2025 +0100
+
+    Add sorting to the progress view
+    
+    Makes sure that the transaction that is active at any given time is
+    listed on top and easily reachable to the user.
+    This is especially important since we removed the global entry on top of
+    the whole update. Flatpak will take all of the things that need updating
+    and update them at its own pace, so we better make it easy to the user
+    when there's a bunch.
+    
+    Also adds some code to test in the dummy backend.
+    
+    (cherry picked from commit b298938a319db2ea0eb1cc382930f50f17dbc5eb)
+
+diff --git a/discover/qml/ProgressView.qml b/discover/qml/ProgressView.qml
+index 8d1eb989c..d28574c2e 100644
+--- a/discover/qml/ProgressView.qml
++++ b/discover/qml/ProgressView.qml
+@@ -1,3 +1,11 @@
++/*
++ *   SPDX-FileCopyrightText: 2012-2025 Aleix Pol Gonzalez <aleixpol at kde.org>
++ *   SPDX-FileCopyrightText: 2022 Nate Graham <nate at kde.org>
++ *   SPDX-FileCopyrightText: 2023 ivan tkachenko <me at ratijas.tk>
++ *
++ *   SPDX-License-Identifier: LGPL-2.0-or-later
++ */
++
+ pragma ComponentBehavior: Bound
+ 
+ import QtQuick
+@@ -63,6 +71,8 @@ QQC2.ToolButton {
+                 }
+                 model: KItemModels.KSortFilterProxyModel {
+                     sourceModel: Discover.TransactionModel
++                    sortRoleName: "status"
++                    sortOrder: Qt.DescendingOrder
+                     filterRoleName: "visible"
+                     filterRowCallback: (sourceRow, sourceParent) => {
+                         const index = sourceModel.index(sourceRow, 0, sourceParent);
+diff --git a/libdiscover/backends/DummyBackend/DummyTransaction.cpp b/libdiscover/backends/DummyBackend/DummyTransaction.cpp
+index ae56ecd06..b45396b57 100644
+--- a/libdiscover/backends/DummyBackend/DummyTransaction.cpp
++++ b/libdiscover/backends/DummyBackend/DummyTransaction.cpp
+@@ -13,6 +13,9 @@
+ 
+ // #define TEST_PROCEED
+ 
++static int m_concurrentTransactions = 0;
++constexpr int MAX_CONCURRENT_TRANSACTIONS = 2;
++
+ DummyTransaction::DummyTransaction(DummyResource *app, Role role)
+     : DummyTransaction(app, {}, role)
+ {
+@@ -23,9 +26,21 @@ DummyTransaction::DummyTransaction(DummyResource *app, const AddonList &addons,
+     , m_app(app)
+ {
+     setCancellable(true);
+-    setStatus(DownloadingStatus);
+ 
+-    iterateTransaction();
++    considerStarting();
++}
++
++void DummyTransaction::considerStarting()
++{
++    // We can limit the concurrent jobs. Added to test the ProgressView with mixed statuses
++    if (m_concurrentTransactions < MAX_CONCURRENT_TRANSACTIONS) {
++        disconnect(OverseeTransactions::self(), &OverseeTransactions::transactionFinished, this, &DummyTransaction::considerStarting);
++        m_concurrentTransactions++;
++        iterateTransaction();
++    } else {
++        connect(OverseeTransactions::self(), &OverseeTransactions::transactionFinished, this, &DummyTransaction::considerStarting);
++        setStatus(QueuedStatus);
++    }
+ }
+ 
+ void DummyTransaction::iterateTransaction()
+@@ -34,11 +49,12 @@ void DummyTransaction::iterateTransaction()
+         return;
+ 
+     if (progress() < 100) {
++        setStatus(DownloadingStatus);
+         setProgress(qBound(0, progress() + QRandomGenerator::global()->bounded(5), 100));
+-        QTimer::singleShot(/*KRandom::random()%*/ 10, this, &DummyTransaction::iterateTransaction);
++        QTimer::singleShot(/*KRandom::random()%*/ 100, this, &DummyTransaction::iterateTransaction);
+     } else if (status() == DownloadingStatus) {
+         setStatus(CommittingStatus);
+-        QTimer::singleShot(/*KRandom::random()%*/ 10, this, &DummyTransaction::iterateTransaction);
++        QTimer::singleShot(/*KRandom::random()%*/ 100, this, &DummyTransaction::iterateTransaction);
+ #ifdef TEST_PROCEED
+     } else if (resource()->name() == "Dummy 101") {
+         Q_EMIT proceedRequest(QStringLiteral("yadda yadda"),
+@@ -60,10 +76,14 @@ void DummyTransaction::cancel()
+     m_iterate = false;
+ 
+     setStatus(CancelledStatus);
++    m_concurrentTransactions--;
++    Q_EMIT OverseeTransactions::self()->transactionFinished();
+ }
+ 
+ void DummyTransaction::finishTransaction()
+ {
++    m_concurrentTransactions--;
++    Q_EMIT OverseeTransactions::self()->transactionFinished();
+     AbstractResource::State newState = AbstractResource::State::Broken;
+     switch (role()) {
+     case InstallRole:
+diff --git a/libdiscover/backends/DummyBackend/DummyTransaction.h b/libdiscover/backends/DummyBackend/DummyTransaction.h
+index 4e57af0df..2befe119c 100644
+--- a/libdiscover/backends/DummyBackend/DummyTransaction.h
++++ b/libdiscover/backends/DummyBackend/DummyTransaction.h
+@@ -9,6 +9,23 @@
+ #include <Transaction/Transaction.h>
+ 
+ class DummyResource;
++
++class OverseeTransactions : public QObject
++{
++    Q_OBJECT
++public:
++    static OverseeTransactions *self()
++    {
++        static OverseeTransactions *m_self = nullptr;
++        if (!m_self) {
++            m_self = new OverseeTransactions;
++        }
++        return m_self;
++    }
++Q_SIGNALS:
++    void transactionFinished();
++};
++
+ class DummyTransaction : public Transaction
+ {
+     Q_OBJECT
+@@ -24,6 +41,7 @@ private Q_SLOTS:
+     void finishTransaction();
+ 
+ private:
++    void considerStarting();
+     bool m_iterate = true;
+     DummyResource *m_app;
+ };
diff --git a/debian/patches/series b/debian/patches/series
index c7a30ef..42c1e3c 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1 +1,4 @@
 snapd-qt6.diff
+bd8dca6b797b64bc319a7ae2c1854b5e4f4069bb.diff
+d4415b20f24cf0a181d6e3a7316dc200fbe1ce78.diff
+b71c614b4d26d91d3bb00452faf14830bf31765b.diff


More information about the Neon-commits mailing list