From 31b305e594cb514160d0664c695f753a3ab55e2a Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com> Date: Sun, 15 Feb 2026 10:44:54 +0530 Subject: [PATCH 1/6] fix: use constant base size in overview page to prevent double scaling --- src/qt/overviewpage.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/qt/overviewpage.cpp b/src/qt/overviewpage.cpp index 7dbd085b8360..cbfe273827bd 100644 --- a/src/qt/overviewpage.cpp +++ b/src/qt/overviewpage.cpp @@ -63,7 +63,7 @@ class TxViewDelegate : public QAbstractItemDelegate QRect rectBottomHalf(mainRect.left() + xspace, mainRect.top() + ypad + halfheight + 5, mainRect.width() - xspace, halfheight); QRect rectBounding; QColor colorForeground; - qreal initialFontSize = painter->font().pointSizeF(); + constexpr auto initial_size{GUIUtil::FontRegistry::DEFAULT_FONT_SIZE}; // Grab model indexes for desired data from TransactionTableModel QModelIndex indexDate = index.sibling(index.row(), TransactionTableModel::Date); @@ -72,7 +72,7 @@ class TxViewDelegate : public QAbstractItemDelegate // Draw first line (with slightly bigger font than the second line will get) // Content: Date/Time, Optional IS indicator, Amount - painter->setFont(GUIUtil::getScaledFont(/*baseSize=*/initialFontSize, /*bold=*/false, /*multiplier=*/1.17)); + painter->setFont(GUIUtil::getScaledFont(/*baseSize=*/initial_size, /*bold=*/false, /*multiplier=*/1.17)); // Date/Time colorForeground = qvariant_cast(indexDate.data(Qt::ForegroundRole)); QString strDate = indexDate.data(Qt::DisplayRole).toString(); @@ -93,7 +93,7 @@ class TxViewDelegate : public QAbstractItemDelegate // Draw second line (with the initial font) // Content: Address/label, Optional Watchonly indicator - painter->setFont(GUIUtil::getScaledFont(/*baseSize=*/initialFontSize, /*bold=*/false)); + painter->setFont(GUIUtil::getScaledFont(/*baseSize=*/initial_size, /*bold=*/false)); // Address/Label colorForeground = qvariant_cast(indexAddress.data(Qt::ForegroundRole)); QString address = indexAddress.data(Qt::DisplayRole).toString(); From e673c9cfe59f55cf65e86e1540f83a9bbfad3bc4 Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com> Date: Mon, 16 Feb 2026 02:27:43 +0530 Subject: [PATCH 2/6] fix: recalculate minimum width when buttons are enabled --- src/qt/bitcoingui.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 166e19155bd8..256aec68f65d 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -1091,6 +1091,8 @@ void BitcoinGUI::setWalletActionsEnabled(bool enabled) openAction->setEnabled(enabled); m_close_wallet_action->setEnabled(enabled); m_close_all_wallets_action->setEnabled(enabled); + + updateWidth(); } void BitcoinGUI::createTrayIcon() From 087859eb77d5cb680a90634ecdc49d2aa3baa140 Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com> Date: Mon, 16 Feb 2026 02:57:37 +0530 Subject: [PATCH 3/6] fix: restore `SERVICE` column comparison behavior lost in MVC refactor --- src/qt/masternodelist.cpp | 12 ++++++++++++ src/qt/masternodelist.h | 1 + 2 files changed, 13 insertions(+) diff --git a/src/qt/masternodelist.cpp b/src/qt/masternodelist.cpp index d6368fa0ce58..8318388b37ee 100644 --- a/src/qt/masternodelist.cpp +++ b/src/qt/masternodelist.cpp @@ -72,6 +72,18 @@ bool MasternodeListSortFilterProxyModel::filterAcceptsRow(int source_row, const return true; } +bool MasternodeListSortFilterProxyModel::lessThan(const QModelIndex& lhs, const QModelIndex& rhs) const +{ + if (lhs.column() == MasternodeModel::SERVICE) { + QVariant lhs_data{sourceModel()->data(lhs, sortRole())}; + QVariant rhs_data{sourceModel()->data(rhs, sortRole())}; + if (lhs_data.userType() == QMetaType::QByteArray && rhs_data.userType() == QMetaType::QByteArray) { + return lhs_data.toByteArray() < rhs_data.toByteArray(); + } + } + return QSortFilterProxyModel::lessThan(lhs, rhs); +} + MasternodeList::MasternodeList(QWidget* parent) : QWidget(parent), ui(new Ui::MasternodeList), diff --git a/src/qt/masternodelist.h b/src/qt/masternodelist.h index ce07082cd9f0..7c916884f932 100644 --- a/src/qt/masternodelist.h +++ b/src/qt/masternodelist.h @@ -56,6 +56,7 @@ class MasternodeListSortFilterProxyModel : public QSortFilterProxyModel protected: bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const override; + bool lessThan(const QModelIndex& lhs, const QModelIndex& rhs) const override; private: bool m_hide_banned{true}; From 2d99c57bcf31ee0d0569d3cbd0b334121447b863 Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com> Date: Mon, 16 Feb 2026 02:59:22 +0530 Subject: [PATCH 4/6] fix: factor status age when sorting by active/ban status --- src/qt/masternodelist.cpp | 4 ++-- src/qt/masternodemodel.cpp | 16 ++++++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/qt/masternodelist.cpp b/src/qt/masternodelist.cpp index 8318388b37ee..8d2b5cbf7993 100644 --- a/src/qt/masternodelist.cpp +++ b/src/qt/masternodelist.cpp @@ -45,8 +45,8 @@ bool MasternodeListSortFilterProxyModel::filterAcceptsRow(int source_row, const // Banned filter if (m_hide_banned) { QModelIndex idx = sourceModel()->index(source_row, MasternodeModel::STATUS, source_parent); - int banned = sourceModel()->data(idx, Qt::EditRole).toInt(); - if (banned != 0) { + int status_value = sourceModel()->data(idx, Qt::EditRole).toInt(); + if (status_value > 0) { return false; } } diff --git a/src/qt/masternodemodel.cpp b/src/qt/masternodemodel.cpp index 5eb0d0da1e7c..39477c1f1795 100644 --- a/src/qt/masternodemodel.cpp +++ b/src/qt/masternodemodel.cpp @@ -285,6 +285,22 @@ QVariant MasternodeModel::data(const QModelIndex& index, int role) const case Column::TYPE: return static_cast(entry->type()); case Column::STATUS: + if (m_current_height > 0) { + if (entry->isBanned()) { + // Banned nodes use positive values + if (auto ban_height = entry->poseBanHeight(); ban_height && *ban_height > 0) { + return m_current_height - *ban_height; + } + return 0; // Unknown ban time, treat as freshly banned + } else { + // Active nodes use negative values + int32_t active_height = entry->registeredHeight(); + if (auto revived_height = entry->poseRevivedHeight(); revived_height && *revived_height > 0) { + active_height = *revived_height; + } + return -(m_current_height - active_height); + } + } return entry->isBanned() ? 1 : 0; case Column::POSE: return entry->posePenalty(); From 269b73ee311986dd16951d63056c4c820ad15a70 Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com> Date: Mon, 16 Feb 2026 03:16:20 +0530 Subject: [PATCH 5/6] fix: correct forward declaration to prevent ABI warning --- src/dummywallet.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dummywallet.cpp b/src/dummywallet.cpp index 5ad3b2ee23ee..14eb342d596e 100644 --- a/src/dummywallet.cpp +++ b/src/dummywallet.cpp @@ -18,7 +18,7 @@ class Loader; } // namespace CoinJoin } // namespace interfaces namespace node { -class NodeContext; +struct NodeContext; } // namespace node namespace wallet { class CWallet; From b56816397807850ef436fb9ec70c42ab5a233821 Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com> Date: Mon, 16 Feb 2026 20:49:04 +0530 Subject: [PATCH 6/6] fix: calculate `COMMON_TYPES` programmatically, add dust to exclusions --- src/qt/overviewpage.cpp | 2 -- src/qt/transactionfilterproxy.h | 20 ++++++++++++++++---- src/qt/transactionrecord.h | 2 +- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/qt/overviewpage.cpp b/src/qt/overviewpage.cpp index cbfe273827bd..7f11fde0f9a8 100644 --- a/src/qt/overviewpage.cpp +++ b/src/qt/overviewpage.cpp @@ -756,8 +756,6 @@ void OverviewPage::SetupTransactionList(int nNumItems) filter->setDynamicSortFilter(true); filter->setSortRole(Qt::EditRole); filter->setShowInactive(false); - // Exclude dust receive transactions from overview - filter->setTypeFilter(TransactionFilterProxy::ALL_TYPES & ~TransactionFilterProxy::TYPE(TransactionRecord::DustReceive)); filter->sort(TransactionTableModel::Date, Qt::DescendingOrder); ui->listTransactions->setModel(filter.get()); } diff --git a/src/qt/transactionfilterproxy.h b/src/qt/transactionfilterproxy.h index 1801d27bcae8..271be2541197 100644 --- a/src/qt/transactionfilterproxy.h +++ b/src/qt/transactionfilterproxy.h @@ -6,12 +6,16 @@ #define BITCOIN_QT_TRANSACTIONFILTERPROXY_H #include +#include #include #include #include +/** Helper function to convert transaction type enum to bit field */ +constexpr quint32 TransactionTypeToBit(int type) { return 1u << type; } + /** Filter the transaction list according to pre-specified rules. */ class TransactionFilterProxy : public QSortFilterProxyModel { @@ -20,12 +24,20 @@ class TransactionFilterProxy : public QSortFilterProxyModel public: explicit TransactionFilterProxy(QObject *parent = nullptr); + /** Types to exclude from common transaction lists (CoinJoin internal transactions and dust) */ + static constexpr quint32 EXCLUDED_TYPES = + TransactionTypeToBit(TransactionRecord::CoinJoinCollateralPayment) | + TransactionTypeToBit(TransactionRecord::CoinJoinCreateDenominations) | + TransactionTypeToBit(TransactionRecord::CoinJoinMakeCollaterals) | + TransactionTypeToBit(TransactionRecord::CoinJoinMixing) | + TransactionTypeToBit(TransactionRecord::DustReceive) | + TransactionTypeToBit(TransactionRecord::RecvWithCoinJoin); /** Type filter bit field (all types) */ - static const quint32 ALL_TYPES = 0xFFFFFFFF; - /** Type filter bit field (all types but Darksend-SPAM) */ - static const quint32 COMMON_TYPES = 0x307f; + static constexpr quint32 ALL_TYPES = 0xFFFFFFFF; + /** Type filter bit field (all types except excluded) */ + static constexpr quint32 COMMON_TYPES = ALL_TYPES & ~EXCLUDED_TYPES; - static quint32 TYPE(int type) { return 1<