Skip to content

Conversation

@kwvg
Copy link
Collaborator

@kwvg kwvg commented Dec 16, 2025

Additional Information

  • Dependency for backport: merge bitcoin-core/gui#79, #497 (allow different font for overview page balances) #6831

  • Additional fixes have been included to deal with crash cases encountered when working on dash#6831, the first fix uses fallback weights if fontWeight{Bold,Normal} is set to a value not supported by the font. This is possible if the values are manually edited or overridden.

    Crash:
    dash@8cf837862c23:/src/dash$ ./src/qt/dash-qt --testnet
    QStandardPaths: XDG_RUNTIME_DIR not set, defaulting to '/tmp/runtime-dash'
    Assertion failure:
      assertion: nIndex != -1
      file: qt/optionsmodel.cpp, line: 546
      function: virtual QVariant OptionsModel::data(const QModelIndex &, int) const
       0#: (0x55D83D7D9C71) stacktraces.cpp:656    - __wrap___assert_fail
       1#: (0x55D83CF4D6D4) optionsmodel.cpp:553   - OptionsModel::data(QModelIndex const&, int) const
       2#: (0x55D83E4C4608) <unknown-file>         - ???
       3#: (0x55D83E4C9068) <unknown-file>         - ???
       4#: (0x55D83E4CA06B) <unknown-file>         - ???
       5#: (0x55D83CF0CF7E) guiutil.cpp            - GUIUtil::setupAppearance(QWidget*, OptionsModel*)
       6#: (0x55D83CEDB8D9) bitcoin.cpp:436        - BitcoinApplication::initializeResult(bool, interfaces::BlockAndHeaderTipInfo)
       7#: (0x55D83CEE8DDD) qobjectdefs_impl.h:425 - QtPrivate::QSlotObject<void (BitcoinApplication::*)(bool, interfaces::BlockAndHeaderTipInfo), QtPrivate::List<bool, interfaces::BlockAndHeaderTipInfo>, void>::impl(int, QtPrivate::QSlotObjectBase*, QObject*, void**, bool*)
       8#: (0x55D83E0C288D) <unknown-file>         - ???
       9#: (0x55D83DC5DAB9) <unknown-file>         - ???
      10#: (0x55D83E2F4186) <unknown-file>         - ???
      11#: (0x55D83E2F5BAC) <unknown-file>         - ???
      12#: (0x55D83E2F6E7E) <unknown-file>         - ???
      13#: (0x55D83E0A5668) <unknown-file>         - ???
    dash-qt: qt/optionsmodel.cpp:546: virtual QVariant OptionsModel::data(const QModelIndex &, int) const: Assertion `nIndex != -1' failed.
    Aborted (core dumped)
    

    The second fix uses the argument passed to the lambda addBestDefaults instead of a global font, this has also been flagged by CodeRabbit (comment)

    Crash:
    dash@8cf837862c23:/src/dash$ ./src/qt/dash-qt --testnet
    QStandardPaths: XDG_RUNTIME_DIR not set, defaulting to '/tmp/runtime-dash'
    Assertion failure:
      assertion: mapWeight.count(weight)
      file: qt/guiutil_font.cpp, line: 119
      function: int GUIUtil::weightToArg(const QFont::Weight)
       0#: (0x55B3C209CC31) stacktraces.cpp:656       - __wrap___assert_fail
       1#: (0x55B3C17E17D6) basic_ios.h:50            - std::ctype<char> const& std::__check_facet<std::ctype<char> >(std::ctype<char> const*)
       2#: (0x55B3C17E17D6) basic_ios.h:454           - std::basic_ios<char, std::char_traits<char> >::widen(char) const
       3#: (0x55B3C17E17D6) ostream:742               - std::basic_ostream<char, std::char_traits<char> >& std::endl<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char>>&)
       4#: (0x55B3C17E17D6) ostream:121               - std::ostream::operator<<(std::ostream& (*)(std::ostream&))
       5#: (0x55B3C17E17D6) guiutil_font.cpp:118      - GUIUtil::weightToArg(QFont::Weight)
       6#: (0x55B3C17A189A) bitcoin.cpp:702           - GuiMain(int, char**)
       7#: (0x7F88E4B1E1CA) libc_start_call_main.h:74 - __libc_start_call_main
       8#: (0x7F88E4B1E28B) libc-start.c:128          - call_init
       9#: (0x7F88E4B1E28B) libc-start.c:347          - __libc_start_main_impl
      10#: (0x55B3C179C545) <unknown-file>            - ???
    dash-qt: qt/guiutil_font.cpp:119: int GUIUtil::weightToArg(const QFont::Weight): Assertion `mapWeight.count(weight)' failed.
    Aborted (core dumped)
    
  • A helper, qstrprintf() has been introduced to streamline debug print logging based on a review suggestion (comment).

Breaking Changes

None expected.

How Has This Been Tested?

On build 2dc48de running Dash Qt on ./src/qt/dash-qt --testnet --font-family="Comic Sans MS"

Dash Qt running with Comic Sans

On build 2dc48de running Dash Qt on ./src/qt/dash-qt --testnet --font-family="Fictional Sans Serif"

Dash Qt existing when attempting to run with invalid font

Checklist:

  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have added or updated relevant unit/integration/functional/e2e tests (note: N/A)
  • I have made corresponding changes to the documentation (note: N/A)
  • I have assigned this pull request to a milestone (for repository code-owners and collaborators only)

@kwvg kwvg added this to the 23.1 milestone Dec 16, 2025
@github-actions
Copy link

github-actions bot commented Dec 16, 2025

✅ No Merge Conflicts Detected

This PR currently has no conflicts with other open PRs.

@kwvg kwvg changed the title refactor: extract Dash-specific font infrastructure to qt/guiutil_font.{cpp,h}, encapsulate globals into Font{Info,Registry}, move away from enum approach to allow for future flexibility refactor: extract Dash-specific font infrastructure to qt/guiutil_font.{cpp,h}, encapsulate globals into Font{Info,Registry} Dec 16, 2025
@kwvg kwvg force-pushed the guiutil_font branch 5 times, most recently from c0b9f13 to 72d2868 Compare December 16, 2025 15:07
@kwvg
Copy link
Collaborator Author

kwvg commented Dec 16, 2025

@coderabbitai review

@coderabbitai
Copy link

coderabbitai bot commented Dec 16, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai
Copy link

coderabbitai bot commented Dec 16, 2025

Walkthrough

Adds a new Qt font subsystem (src/qt/guiutil_font.h/.cpp) introducing GUIUtil::FontInfo, GUIUtil::FontRegistry, g_font_registry, g_fonts_known and public APIs (loadFonts, fontsLoaded, setApplicationFont, setFont, updateFonts, getFont variants). Removes the legacy font management surface from guiutil.h/.cpp and migrates many Qt translation units to include the new header and use registry-driven font weights, scales, and application. Adds guiutil_font files to the Qt Makefile and adds OptionsModel::isOptionOverridden; test non-backported list updated.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant User as User (CLI / Settings)
  participant App as bitcoin (startup/UI)
  participant Registry as GUIUtil::g_font_registry
  participant QDB as QFontDatabase
  participant QtApp as QApplication / Widgets

  Note over User,App: Startup or runtime UI font change
  User->>App: provide -font-family / -font-scale / -font-weight or change via UI
  App->>Registry: RegisterFont / SetFont / SetFontScale / SetWeightNormal / SetWeightBold
  Registry->>QDB: Load / query font families & variants
  QDB-->>Registry: return font metadata & supported weights
  Registry->>Registry: compute mappings, supported weights, defaults
  Registry->>QtApp: setApplicationFont()
  Registry->>QtApp: updateFonts() — apply per-widget/class fonts
  QtApp-->>Registry: widgets request reapply or lifecycle updates
Loading

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 8.11% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: extracting Dash-specific font infrastructure into new files and encapsulating globals into FontInfo/Registry classes.
Description check ✅ Passed The description comprehensively explains the purpose, includes dependency information, documents crash fixes, and provides testing evidence with screenshots.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (2)
src/qt/guiutil_font.h (2)

82-82: Consider using toString() instead of toUtf8() for initialization.

QStringView::toUtf8() returns a QByteArray, which then gets implicitly converted to QString. Using DEFAULT_FONT.toString() would be more direct and avoids unnecessary UTF-8 encoding/decoding round-trip.

-    QString m_font{DEFAULT_FONT.toUtf8()};
+    QString m_font{DEFAULT_FONT.toString()};

74-78: Document initialization requirement for getter methods.

These getters use m_weights.at(m_font) which will throw std::out_of_range if called before RegisterFont() populates the map. While SetFont() validates this, the getters assume the font is already registered.

Consider adding a brief comment noting that loadFonts() must be called before using these methods, or add a defensive check in the getters.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 123ee5e and 72d2868.

📒 Files selected for processing (35)
  • src/Makefile.qt.include (2 hunks)
  • src/qt/addressbookpage.cpp (1 hunks)
  • src/qt/addresstablemodel.cpp (1 hunks)
  • src/qt/appearancewidget.cpp (5 hunks)
  • src/qt/appearancewidget.h (2 hunks)
  • src/qt/askpassphrasedialog.cpp (1 hunks)
  • src/qt/bitcoin.cpp (3 hunks)
  • src/qt/bitcoingui.cpp (1 hunks)
  • src/qt/coincontroldialog.cpp (1 hunks)
  • src/qt/governancelist.cpp (1 hunks)
  • src/qt/guiutil.cpp (0 hunks)
  • src/qt/guiutil.h (0 hunks)
  • src/qt/guiutil_font.cpp (1 hunks)
  • src/qt/guiutil_font.h (1 hunks)
  • src/qt/masternodelist.cpp (1 hunks)
  • src/qt/modaloverlay.cpp (1 hunks)
  • src/qt/openuridialog.cpp (1 hunks)
  • src/qt/optionsmodel.cpp (4 hunks)
  • src/qt/overviewpage.cpp (3 hunks)
  • src/qt/proposalwizard.cpp (1 hunks)
  • src/qt/qrdialog.cpp (1 hunks)
  • src/qt/qrimagewidget.cpp (1 hunks)
  • src/qt/receivecoinsdialog.cpp (1 hunks)
  • src/qt/receiverequestdialog.cpp (1 hunks)
  • src/qt/rpcconsole.cpp (1 hunks)
  • src/qt/sendcoinsdialog.cpp (1 hunks)
  • src/qt/sendcoinsentry.cpp (1 hunks)
  • src/qt/signverifymessagedialog.cpp (1 hunks)
  • src/qt/splashscreen.cpp (1 hunks)
  • src/qt/test/apptests.cpp (1 hunks)
  • src/qt/trafficgraphwidget.cpp (1 hunks)
  • src/qt/transactiondescdialog.cpp (1 hunks)
  • src/qt/utilitydialog.cpp (1 hunks)
  • src/qt/walletview.cpp (1 hunks)
  • test/util/data/non-backported.txt (1 hunks)
💤 Files with no reviewable changes (2)
  • src/qt/guiutil.h
  • src/qt/guiutil.cpp
🧰 Additional context used
📓 Path-based instructions (2)
src/**/*.{cpp,h,hpp,cc}

📄 CodeRabbit inference engine (CLAUDE.md)

Dash Core implementation must be written in C++20, requiring at least Clang 16 or GCC 11.1

Files:

  • src/qt/receiverequestdialog.cpp
  • src/qt/rpcconsole.cpp
  • src/qt/splashscreen.cpp
  • src/qt/transactiondescdialog.cpp
  • src/qt/bitcoingui.cpp
  • src/qt/qrdialog.cpp
  • src/qt/qrimagewidget.cpp
  • src/qt/coincontroldialog.cpp
  • src/qt/proposalwizard.cpp
  • src/qt/receivecoinsdialog.cpp
  • src/qt/optionsmodel.cpp
  • src/qt/overviewpage.cpp
  • src/qt/test/apptests.cpp
  • src/qt/sendcoinsentry.cpp
  • src/qt/addressbookpage.cpp
  • src/qt/guiutil_font.cpp
  • src/qt/governancelist.cpp
  • src/qt/addresstablemodel.cpp
  • src/qt/masternodelist.cpp
  • src/qt/openuridialog.cpp
  • src/qt/modaloverlay.cpp
  • src/qt/askpassphrasedialog.cpp
  • src/qt/sendcoinsdialog.cpp
  • src/qt/walletview.cpp
  • src/qt/trafficgraphwidget.cpp
  • src/qt/appearancewidget.h
  • src/qt/guiutil_font.h
  • src/qt/signverifymessagedialog.cpp
  • src/qt/appearancewidget.cpp
  • src/qt/utilitydialog.cpp
  • src/qt/bitcoin.cpp
src/qt/**/*.{cpp,h}

📄 CodeRabbit inference engine (CLAUDE.md)

GUI implementation in src/qt/ must use Qt 5

Files:

  • src/qt/receiverequestdialog.cpp
  • src/qt/rpcconsole.cpp
  • src/qt/splashscreen.cpp
  • src/qt/transactiondescdialog.cpp
  • src/qt/bitcoingui.cpp
  • src/qt/qrdialog.cpp
  • src/qt/qrimagewidget.cpp
  • src/qt/coincontroldialog.cpp
  • src/qt/proposalwizard.cpp
  • src/qt/receivecoinsdialog.cpp
  • src/qt/optionsmodel.cpp
  • src/qt/overviewpage.cpp
  • src/qt/test/apptests.cpp
  • src/qt/sendcoinsentry.cpp
  • src/qt/addressbookpage.cpp
  • src/qt/guiutil_font.cpp
  • src/qt/governancelist.cpp
  • src/qt/addresstablemodel.cpp
  • src/qt/masternodelist.cpp
  • src/qt/openuridialog.cpp
  • src/qt/modaloverlay.cpp
  • src/qt/askpassphrasedialog.cpp
  • src/qt/sendcoinsdialog.cpp
  • src/qt/walletview.cpp
  • src/qt/trafficgraphwidget.cpp
  • src/qt/appearancewidget.h
  • src/qt/guiutil_font.h
  • src/qt/signverifymessagedialog.cpp
  • src/qt/appearancewidget.cpp
  • src/qt/utilitydialog.cpp
  • src/qt/bitcoin.cpp
🧠 Learnings (15)
📓 Common learnings
Learnt from: kwvg
Repo: dashpay/dash PR: 6761
File: src/chainlock/signing.cpp:15-250
Timestamp: 2025-07-23T09:28:32.783Z
Learning: In refactoring PRs like #6761, kwvg prefers to defer code formatting fixes to separate follow-up PRs when formatting is not the primary objective, to maintain focus on the structural changes and avoid scope creep.
Learnt from: kwvg
Repo: dashpay/dash PR: 6761
File: src/wallet/wallet.cpp:0-0
Timestamp: 2025-07-29T14:33:01.040Z
Learning: In refactoring PRs like #6761, kwvg acknowledges code safety improvements (like null pointer checks and unused parameter warnings) but prefers to defer them to follow-up PRs to maintain focus on the primary refactoring objectives, avoiding scope creep.
Learnt from: kwvg
Repo: dashpay/dash PR: 6543
File: src/wallet/receive.cpp:240-251
Timestamp: 2025-02-06T14:34:30.466Z
Learning: Pull request #6543 is focused on move-only changes and refactoring, specifically backporting from Bitcoin. Behavior changes should be proposed in separate PRs.
Learnt from: knst
Repo: dashpay/dash PR: 6916
File: src/univalue/include/univalue.h:81-88
Timestamp: 2025-10-25T07:08:51.918Z
Learning: The univalue library (in src/univalue/) is no longer a vendored external dependency but is now part of the Bitcoin Core codebase and can be modified as needed during backports.
Learnt from: PastaPastaPasta
Repo: dashpay/dash PR: 6804
File: src/qt/proposalwizard.cpp:40-42
Timestamp: 2025-08-11T17:16:36.654Z
Learning: In the Dash repository, when a PR adds new files that are not from Bitcoin backports, these files must be added to the list in test/util/data/non-backported.txt. This applies to newly created files like qt/proposalwizard.{h,cpp} and forms/proposalwizard.ui. Limited exemptions may exist for subtrees and similar cases.
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/qt/**/*.{cpp,h} : GUI implementation in src/qt/ must use Qt 5

Applied to files:

  • src/qt/receiverequestdialog.cpp
  • src/qt/rpcconsole.cpp
  • src/qt/splashscreen.cpp
  • src/qt/transactiondescdialog.cpp
  • src/qt/bitcoingui.cpp
  • src/qt/qrdialog.cpp
  • src/qt/qrimagewidget.cpp
  • src/qt/coincontroldialog.cpp
  • src/qt/proposalwizard.cpp
  • src/qt/receivecoinsdialog.cpp
  • src/qt/optionsmodel.cpp
  • src/qt/overviewpage.cpp
  • src/qt/test/apptests.cpp
  • src/qt/sendcoinsentry.cpp
  • src/qt/addressbookpage.cpp
  • test/util/data/non-backported.txt
  • src/qt/guiutil_font.cpp
  • src/Makefile.qt.include
  • src/qt/governancelist.cpp
  • src/qt/addresstablemodel.cpp
  • src/qt/masternodelist.cpp
  • src/qt/openuridialog.cpp
  • src/qt/modaloverlay.cpp
  • src/qt/askpassphrasedialog.cpp
  • src/qt/sendcoinsdialog.cpp
  • src/qt/walletview.cpp
  • src/qt/trafficgraphwidget.cpp
  • src/qt/appearancewidget.h
  • src/qt/guiutil_font.h
  • src/qt/signverifymessagedialog.cpp
  • src/qt/appearancewidget.cpp
  • src/qt/utilitydialog.cpp
  • src/qt/bitcoin.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/wallet/**/*.{cpp,h} : Wallet implementation must use Berkeley DB and SQLite

Applied to files:

  • src/qt/receiverequestdialog.cpp
  • src/qt/rpcconsole.cpp
  • src/qt/splashscreen.cpp
  • src/qt/coincontroldialog.cpp
  • src/qt/askpassphrasedialog.cpp
  • src/qt/walletview.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/{test,wallet/test}/**/*.{cpp,h} : Unit tests in src/test/ and src/wallet/test/ must use Boost::Test framework

Applied to files:

  • src/qt/test/apptests.cpp
📚 Learning: 2025-12-01T18:13:21.314Z
Learnt from: PastaPastaPasta
Repo: dashpay/dash PR: 7018
File: test/lint/lint-github-actions.py:1-9
Timestamp: 2025-12-01T18:13:21.314Z
Learning: In the Dash repository, the file test/util/data/non-backported.txt should only include C++ files (.cpp or .h) because it is used for running clang-format. Other file types (such as Python files, .ui files, etc.) should not be added to this list.

Applied to files:

  • test/util/data/non-backported.txt
📚 Learning: 2025-08-11T17:16:36.654Z
Learnt from: PastaPastaPasta
Repo: dashpay/dash PR: 6804
File: src/qt/proposalwizard.cpp:40-42
Timestamp: 2025-08-11T17:16:36.654Z
Learning: In the Dash repository, when a PR adds new files that are not from Bitcoin backports, these files must be added to the list in test/util/data/non-backported.txt. This applies to newly created files like qt/proposalwizard.{h,cpp} and forms/proposalwizard.ui. Limited exemptions may exist for subtrees and similar cases.

Applied to files:

  • test/util/data/non-backported.txt
  • src/Makefile.qt.include
📚 Learning: 2025-12-01T18:13:36.294Z
Learnt from: UdjinM6
Repo: dashpay/dash PR: 7018
File: test/util/data/non-backported.txt:0-0
Timestamp: 2025-12-01T18:13:36.294Z
Learning: Python files (.py) should not be added to test/util/data/non-backported.txt because that file is used to run clang-format on C/C++ files, not Python files.

Applied to files:

  • test/util/data/non-backported.txt
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/coinjoin/**/*.{cpp,h} : CoinJoin implementation must use masternode-coordinated mixing sessions with uniform denomination outputs

Applied to files:

  • test/util/data/non-backported.txt
  • src/qt/masternodelist.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/llmq/**/*.{cpp,h} : InstantSend implementation must provide distributed key generation for secure transaction locking with quorum consensus

Applied to files:

  • test/util/data/non-backported.txt
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/{validation,txmempool}/**/*.{cpp,h} : Block validation and mempool handling must use extensions to Bitcoin Core mechanisms for special transaction validation and enhanced transaction relay

Applied to files:

  • test/util/data/non-backported.txt
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/{masternode,llmq}/**/*.{cpp,h} : BLS integration must be used for cryptographic foundation of advanced masternode features

Applied to files:

  • test/util/data/non-backported.txt
  • src/qt/masternodelist.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/{masternode,evo,llmq,governance,coinjoin}/**/*.{cpp,h} : Use Dash-specific database implementations: CFlatDB for persistent storage (MasternodeMetaStore, GovernanceStore, SporkStore, NetFulfilledRequestStore) and CDBWrapper extensions for Evolution/DKG/InstantSend/Quorum/RecoveredSigs data

Applied to files:

  • test/util/data/non-backported.txt
  • src/qt/masternodelist.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/llmq/**/*.{cpp,h} : LLMQ quorums must support multiple configurations (50/60, 400/60, 400/85) for different services (ChainLocks, InstantSend, governance voting)

Applied to files:

  • test/util/data/non-backported.txt
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/evo/evodb/**/*.{cpp,h} : Evolution Database (CEvoDb) must handle masternode snapshots, quorum state, governance objects with efficient differential updates for masternode lists

Applied to files:

  • src/qt/masternodelist.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/{masternode,evo}/**/*.{cpp,h} : Masternode lists must use immutable data structures (Immer library) for thread safety

Applied to files:

  • src/qt/masternodelist.cpp
🧬 Code graph analysis (6)
src/qt/optionsmodel.cpp (1)
src/qt/guiutil_font.cpp (10)
  • fontsLoaded (249-252)
  • fontsLoaded (249-249)
  • setApplicationFont (254-284)
  • setApplicationFont (254-254)
  • weightToArg (121-125)
  • weightToArg (121-121)
  • weightFromArg (111-119)
  • weightFromArg (111-111)
  • updateFonts (297-403)
  • updateFonts (297-297)
src/qt/overviewpage.cpp (1)
src/qt/guiutil_font.cpp (6)
  • getFont (405-459)
  • getFont (405-405)
  • getFont (461-464)
  • getFont (461-461)
  • getFont (466-469)
  • getFont (466-466)
src/qt/guiutil_font.cpp (1)
src/qt/guiutil.cpp (2)
  • TextWidth (1284-1287)
  • TextWidth (1284-1284)
src/qt/guiutil_font.h (1)
src/qt/guiutil_font.cpp (36)
  • FontInfo (88-94)
  • FontInfo (96-96)
  • GetBestMatch (153-167)
  • GetBestMatch (153-153)
  • RegisterFont (98-101)
  • RegisterFont (98-98)
  • WeightToIdx (488-497)
  • WeightToIdx (488-488)
  • IdxToWeight (481-486)
  • IdxToWeight (481-481)
  • SetFont (103-109)
  • SetFont (103-103)
  • weightFromArg (111-119)
  • weightFromArg (111-111)
  • weightToArg (121-125)
  • weightToArg (121-121)
  • loadFonts (184-247)
  • loadFonts (184-184)
  • fontsLoaded (249-252)
  • fontsLoaded (249-249)
  • setApplicationFont (254-284)
  • setApplicationFont (254-254)
  • setFont (286-295)
  • setFont (286-286)
  • updateFonts (297-403)
  • updateFonts (297-297)
  • getFont (405-459)
  • getFont (405-405)
  • getFont (461-464)
  • getFont (461-461)
  • getFont (466-469)
  • getFont (466-466)
  • getFontNormal (471-474)
  • getFontNormal (471-471)
  • getFontBold (476-479)
  • getFontBold (476-476)
src/qt/appearancewidget.cpp (1)
src/qt/guiutil_font.cpp (4)
  • setApplicationFont (254-284)
  • setApplicationFont (254-254)
  • updateFonts (297-403)
  • updateFonts (297-297)
src/qt/bitcoin.cpp (1)
src/qt/guiutil_font.cpp (8)
  • weightToArg (121-125)
  • weightToArg (121-121)
  • setApplicationFont (254-284)
  • setApplicationFont (254-254)
  • weightFromArg (111-119)
  • weightFromArg (111-111)
  • updateFonts (297-403)
  • updateFonts (297-297)
🪛 Cppcheck (2.18.0)
src/qt/guiutil_font.cpp

[error] 52-52: There is an unknown macro here somewhere. Configuration is required. If QT_END_NAMESPACE is a macro then please configure it.

(unknownMacro)

🪛 GitHub Actions: Clang Diff Format Check
src/qt/guiutil_font.cpp

[error] 1-1: Clang format differences found. Run the clang-format-diff.py diff check (e.g., 'git diff -U0 origin/develop -- ... | ./contrib/devtools/clang-format-diff.py -p1') to fix formatting issues in this file.

🔇 Additional comments (39)
src/qt/proposalwizard.cpp (1)

16-16: LGTM!

The include for guiutil_font.h is correctly added and necessary since this file uses GUIUtil::setFont and GUIUtil::updateFonts which are now declared in the new font utilities header.

src/qt/appearancewidget.h (1)

51-55: Verify member initialization in constructor.

These members are now declared without in-class initializers. The type of prevFontFamily changed from GUIUtil::FontFamily (enum) to QString, which aligns with the new FontRegistry-based approach where fonts are identified by name strings.

Ensure the constructor in appearancewidget.cpp properly initializes all five members (prevTheme, prevScale, prevFontFamily, prevWeightNormal, prevWeightBold) to avoid undefined behavior from reading uninitialized values.

src/Makefile.qt.include (1)

142-142: LGTM!

Build integration is correct:

  • qt/guiutil_font.h is properly added to BITCOIN_QT_H for the header
  • qt/guiutil_font.cpp is properly added to BITCOIN_QT_BASE_CPP for the source

Based on learnings, new non-backported files should also be added to test/util/data/non-backported.txt. The AI summary indicates this has been done, but please verify that src/qt/guiutil_font.* entries are present in that file.

Also applies to: 234-234

src/qt/trafficgraphwidget.cpp (1)

9-9: LGTM!

The include is correctly added since this file uses GUIUtil::getFont at lines 171-172, which is now declared in the new font utilities header.

src/qt/sendcoinsdialog.cpp (1)

18-18: LGTM!

The include is correctly added since this file uses GUIUtil::setFont and GUIUtil::updateFonts, which are now declared in the new font utilities header.

src/qt/bitcoingui.cpp (1)

13-13: LGTM!

The include is correctly added since this file extensively uses font utilities (GUIUtil::setFont, GUIUtil::updateFonts, GUIUtil::getFontNormal), which are now declared in the new font utilities header.

src/qt/modaloverlay.cpp (1)

10-10: LGTM!

The include is correctly added since this file uses GUIUtil::setFont and GUIUtil::updateFonts, which are now declared in the new font utilities header.

src/qt/test/apptests.cpp (1)

11-11: LGTM - Include supports font infrastructure refactoring.

The addition of guiutil_font.h aligns with the PR's objective to extract font utilities into dedicated headers. The include is necessary for the GUIUtil::loadFonts() call at line 82.

src/qt/receiverequestdialog.cpp (1)

10-10: LGTM - Include supports font infrastructure refactoring.

The addition of guiutil_font.h is necessary for the GUIUtil::updateFonts() call at line 29 and aligns with the PR's font infrastructure extraction.

src/qt/askpassphrasedialog.cpp (1)

15-15: LGTM - Include supports font infrastructure refactoring.

The addition of guiutil_font.h is necessary for the font utility calls at lines 34 and 36 (GUIUtil::setFont() and GUIUtil::updateFonts()), supporting the PR's objective to extract font utilities.

src/qt/coincontroldialog.cpp (1)

16-16: LGTM - Include supports font infrastructure refactoring.

The addition of guiutil_font.h is necessary for the font utility calls at lines 55-61 and 63, supporting the PR's font infrastructure extraction objective.

src/qt/governancelist.cpp (1)

21-21: LGTM - Include supports font infrastructure refactoring.

The addition of guiutil_font.h is necessary for the font utility calls at lines 315-317 and 356, aligning with the PR's objective to extract font utilities into dedicated headers.

src/qt/transactiondescdialog.cpp (1)

9-9: LGTM - Include supports font infrastructure refactoring.

The addition of guiutil_font.h is necessary for the GUIUtil::updateFonts() call at line 20 and aligns with the PR's font infrastructure extraction.

src/qt/masternodelist.cpp (1)

8-8: LGTM - Includes support font refactoring and coin utilities.

The additions are necessary:

  • coins.h at line 8 is required for the Coin type used at line 182
  • guiutil_font.h at line 12 is necessary for the font utility calls at lines 43-46 and 94

Both includes align with the PR's font infrastructure extraction objective.

Also applies to: 12-12

src/qt/qrimagewidget.cpp (1)

8-8: LGTM - Include supports font infrastructure refactoring.

The addition of guiutil_font.h is necessary for the GUIUtil::getFontNormal() call at line 86 and aligns with the PR's objective to extract font utilities into dedicated headers.

src/qt/sendcoinsentry.cpp (1)

16-16: LGTM!

The include is correctly placed after guiutil.h and is necessary for the GUIUtil::setFont() and GUIUtil::updateFonts() calls used in this file's constructor.

src/qt/rpcconsole.cpp (1)

21-21: LGTM!

The include is correctly placed and necessary. This file makes extensive use of font utilities including GUIUtil::setFont(), GUIUtil::updateFonts(), and GUIUtil::fixedPitchFont() for console rendering and UI styling.

src/qt/qrdialog.cpp (1)

11-11: LGTM!

The include is correctly placed after guiutil.h and is necessary for the GUIUtil::setFont() and GUIUtil::updateFonts() calls in the constructor.

src/qt/addresstablemodel.cpp (1)

9-9: LGTM!

The include is correctly placed after guiutil.h and is necessary for the GUIUtil::getFontNormal() call used in the data() method when returning the font for the Address column.

test/util/data/non-backported.txt (1)

30-30: LGTM!

The new font utility files are correctly added to the non-backported list in alphabetical order. Based on learnings, new files not from Bitcoin backports must be added here, and this glob pattern appropriately covers the C++ source and header files (guiutil_font.cpp and guiutil_font.h).

src/qt/splashscreen.cpp (1)

19-19: LGTM! Include addition is necessary for the font refactoring.

The include is required since this file uses GUIUtil::getFontNormal() and GUIUtil::getFontBold() (lines 61-62, 233), which are now part of the extracted font infrastructure.

src/qt/addressbookpage.cpp (1)

17-17: LGTM! Include addition is necessary for the font refactoring.

The include is required since this file calls GUIUtil::updateFonts() (line 124), which is now part of the extracted font infrastructure.

src/qt/utilitydialog.cpp (1)

15-15: LGTM! Include addition is necessary for the font refactoring.

The include is required since this file calls GUIUtil::updateFonts() (lines 40, 195), which is now part of the extracted font infrastructure.

src/qt/signverifymessagedialog.cpp (1)

11-11: LGTM! Include addition is necessary for the font refactoring.

The include is required since this file uses GUIUtil::setFont() and GUIUtil::updateFonts() (lines 57-59, 61, 115-117), which are now part of the extracted font infrastructure.

src/qt/openuridialog.cpp (1)

10-10: LGTM! Include addition is necessary for the font refactoring.

The include is required since this file calls GUIUtil::updateFonts() (line 23), which is now part of the extracted font infrastructure.

src/qt/walletview.cpp (1)

14-14: LGTM! Include addition is necessary for the font refactoring.

The include is required since this file uses GUIUtil::setFont() and GUIUtil::updateFonts() (lines 71-74), which are now part of the extracted font infrastructure.

src/qt/receivecoinsdialog.cpp (1)

10-10: LGTM! Include addition is necessary for the font refactoring.

The include is required since this file uses GUIUtil::setFont() and GUIUtil::updateFonts() (lines 26-30), which are now part of the extracted font infrastructure.

src/qt/overviewpage.cpp (2)

12-12: LGTM! Include addition is necessary for the font refactoring.

The include is required since this file uses multiple font APIs including GUIUtil::setFont(), GUIUtil::updateFonts(), and the new g_font_registry.GetScaledFontSize().


74-74: Migration to FontRegistry API is complete and correctly initialized.

Verification confirms:

  • No remaining calls to the old GUIUtil::getScaledFontSize() API exist in the codebase
  • g_font_registry is a global variable initialized at startup and configured early in bitcoin.cpp (before any UI painting occurs)
  • Both lines 74 and 95 correctly use the new GUIUtil::g_font_registry.GetScaledFontSize() API

The code is ready.

src/qt/optionsmodel.cpp (2)

15-15: LGTM! Clean migration to FontRegistry.

The refactoring systematically replaces direct font handling with FontRegistry-based methods. The addition of the explicit updateFonts() call at lines 157-159 ensures fonts are properly applied after all font-related settings are loaded during initialization. The fallback logic at lines 127-132 and 144-151 correctly handles unsupported weights by selecting appropriate defaults.

Also applies to: 101-159


557-572: Well-structured weight-to-index conversion with proper fallbacks.

The read logic correctly attempts to convert stored weights to indices and falls back to registry defaults when the stored weight is unavailable (index == -1). The assertions ensure the fallback values are always valid.

src/qt/appearancewidget.cpp (2)

23-28: Well-implemented state preservation and restoration.

The constructor captures initial font state from the registry (lines 23-28), and the destructor correctly restores it when changes aren't accepted (lines 67-80). This ensures a proper cancel/revert experience. The explicit updateFonts() call at line 80 applies the restored state.

Also applies to: 67-80


36-38: Good: Dynamic font family population.

Populating the font family combo from g_fonts_known makes the UI automatically reflect available fonts without hard-coding font names.

src/qt/bitcoin.cpp (2)

489-492: LGTM! CLI arguments properly reference FontRegistry constants.

The argument setup at lines 489-492 correctly uses g_fonts_known, FontRegistry::DEFAULT_FONT, DEFAULT_FONT_SCALE, and weightToArg() to derive default values and valid ranges. This ensures CLI help text stays synchronized with the actual font subsystem.


673-709: Comprehensive font validation and application.

The validation blocks properly check CLI arguments, convert them via the registry, and display error dialogs for invalid inputs. The final updateFonts() call at lines 708-709 ensures all font changes are applied consistently.

src/qt/guiutil_font.cpp (4)

184-247: LGTM! Robust font loading with proper error handling.

The loadFonts() function correctly:

  • Preserves the system default font before loading custom fonts (line 187)
  • Loads all Montserrat variants including italic styles (lines 195-206)
  • Returns false and clears osDefaultFont if any font fails to load (lines 209-212)
  • Registers all known fonts with the registry (lines 240-242)

297-403: Well-structured font update logic with proper cleanup.

The updateFonts() function demonstrates good engineering:

  • Lines 309-329: Cleans up null QPointers from deleted widgets to prevent use-after-free
  • Lines 381-386: Defers font application to a separate loop to avoid font inheritance issues (as noted in the comment)
  • Lines 388-402: Updates global class fonts for UI components not in the widget tree

The assertion at line 350 is appropriate for debug builds to catch font initialization issues.


405-479: LGTM! Platform-specific font handling is appropriate.

The getFont() overloads provide flexible APIs for font construction. The platform-specific Montserrat handling at lines 414-433 correctly:

  • Uses setStyleName() on macOS to select font variants (lines 416-426)
  • Uses family name suffixes on other platforms (lines 428-432)

This accounts for Qt font handling differences across platforms.


127-182: Clever weight detection via text width comparison.

The weight calculation logic is well-designed:

  • CalcSupportedWeights() (lines 127-151) detects which font weights actually render differently by comparing text widths—this is a practical solution to Qt's limited font introspection
  • CalcDefaultWeights() (lines 169-182) ensures normal and bold weights are distinct, falling back to the next heavier weight if they would otherwise be identical

@kwvg kwvg marked this pull request as ready for review December 16, 2025 18:55
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

♻️ Duplicate comments (1)
src/qt/guiutil_font.h (1)

125-126: Typo: "appliciation" should be "application".

This issue was already flagged in a previous review.

-/** Load dash specific appliciation fonts */
+/** Load dash specific application fonts */
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 72d2868 and 719717a.

📒 Files selected for processing (1)
  • src/qt/guiutil_font.h (1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
src/**/*.{cpp,h,hpp,cc}

📄 CodeRabbit inference engine (CLAUDE.md)

Dash Core implementation must be written in C++20, requiring at least Clang 16 or GCC 11.1

Files:

  • src/qt/guiutil_font.h
src/qt/**/*.{cpp,h}

📄 CodeRabbit inference engine (CLAUDE.md)

GUI implementation in src/qt/ must use Qt 5

Files:

  • src/qt/guiutil_font.h
🧠 Learnings (3)
📓 Common learnings
Learnt from: kwvg
Repo: dashpay/dash PR: 6761
File: src/chainlock/signing.cpp:15-250
Timestamp: 2025-07-23T09:28:32.783Z
Learning: In refactoring PRs like #6761, kwvg prefers to defer code formatting fixes to separate follow-up PRs when formatting is not the primary objective, to maintain focus on the structural changes and avoid scope creep.
Learnt from: kwvg
Repo: dashpay/dash PR: 6761
File: src/wallet/wallet.cpp:0-0
Timestamp: 2025-07-29T14:33:01.040Z
Learning: In refactoring PRs like #6761, kwvg acknowledges code safety improvements (like null pointer checks and unused parameter warnings) but prefers to defer them to follow-up PRs to maintain focus on the primary refactoring objectives, avoiding scope creep.
Learnt from: kwvg
Repo: dashpay/dash PR: 6543
File: src/wallet/receive.cpp:240-251
Timestamp: 2025-02-06T14:34:30.466Z
Learning: Pull request #6543 is focused on move-only changes and refactoring, specifically backporting from Bitcoin. Behavior changes should be proposed in separate PRs.
Learnt from: knst
Repo: dashpay/dash PR: 6916
File: src/univalue/include/univalue.h:81-88
Timestamp: 2025-10-25T07:08:51.918Z
Learning: The univalue library (in src/univalue/) is no longer a vendored external dependency but is now part of the Bitcoin Core codebase and can be modified as needed during backports.
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/qt/**/*.{cpp,h} : GUI implementation in src/qt/ must use Qt 5

Applied to files:

  • src/qt/guiutil_font.h
📚 Learning: 2025-10-05T20:38:28.457Z
Learnt from: knst
Repo: dashpay/dash PR: 6871
File: contrib/guix/libexec/build.sh:358-360
Timestamp: 2025-10-05T20:38:28.457Z
Learning: In the Dash repository, when backporting code from Bitcoin Core, typos and minor issues in comments should be kept as-is to reduce merge conflicts in future backports, even if they remain unfixed in Bitcoin Core's master branch.

Applied to files:

  • src/qt/guiutil_font.h
🪛 GitHub Actions: Clang Diff Format Check
src/qt/guiutil_font.h

[error] 1-1: Clang format differences found. Run the clang-format-diff step again or apply clang-format changes to this file.

🔇 Additional comments (2)
src/qt/guiutil_font.h (2)

23-38: LGTM: Well-designed FontInfo struct.

The explicit constructor and deleted default constructor ensure proper initialization, and the structure cleanly encapsulates font weight information.


1-1: Run clang-format to fix formatting issues.

The pipeline failure indicates that this file has clang-format differences. Please run clang-format on this file to resolve the CI check failure.

#!/bin/bash
# Run clang-format on the file
clang-format -i src/qt/guiutil_font.h
⛔ Skipped due to learnings
Learnt from: kwvg
Repo: dashpay/dash PR: 6529
File: src/rpc/governance.cpp:1074-1089
Timestamp: 2025-02-14T15:15:58.165Z
Learning: Code blocks marked with `// clang-format off` and `// clang-format on` directives should be excluded from clang-format suggestions as they are intentionally formatted manually for better readability.
Learnt from: kwvg
Repo: dashpay/dash PR: 6729
File: src/rpc/evo.cpp:1273-1273
Timestamp: 2025-07-09T15:05:36.250Z
Learning: When clang-format suggestions significantly harm readability (like splitting logical parameter groups across multiple lines), it's acceptable to use `// clang-format off` and `// clang-format on` directives to exclude the problematic section from automatic formatting, prioritizing code readability over strict line length compliance.
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Dash extends Bitcoin Core through composition with minimal changes to the Bitcoin Core foundation
Learnt from: kwvg
Repo: dashpay/dash PR: 6761
File: src/chainlock/signing.h:5-6
Timestamp: 2025-07-23T09:30:34.631Z
Learning: Dash Core uses BITCOIN_ prefix for header guards as the standard convention, inherited from Bitcoin Core. Only a few BLS-specific files in src/bls/ use DASH_ prefix. The vast majority of files (385+) use BITCOIN_ prefix.

Copy link

@UdjinM6 UdjinM6 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see below + coderabbit has a few valid points too

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (3)
src/qt/guiutil_font.cpp (1)

1-516: Address clang-format issues before merging.

The pipeline reports clang-format differences. Run git diff -U0 origin/develop -- src/qt/guiutil_font.cpp | ./contrib/devtools/clang-format-diff.py -p1 to identify and fix formatting issues.

Based on learnings, this is a refactoring PR focused on structural changes.

src/qt/guiutil_font.h (2)

68-77: Inconsistent error handling between setters and getters.

The SetWeightBold and SetWeightNormal methods use assert(m_weights.count(m_font)) which will crash in debug builds if the font is not registered. This is inconsistent with the defensive approach in GetWeight* methods (lines 84-108) which gracefully return defaults.

This was flagged in a previous review. Consider aligning the error handling approach, either by making setters defensive or documenting that RegisterFont must be called first.


1-156: Address clang-format issues before merging.

The pipeline reports clang-format differences for this file as well.

🧹 Nitpick comments (4)
src/qt/appearancewidget.cpp (2)

67-70: Assert on SetFont return value may be too aggressive.

Using assert(GUIUtil::g_font_registry.SetFont(prevFontFamily)) will crash in debug builds if prevFontFamily was somehow unregistered between construction and destruction. While this is unlikely, consider using a conditional check with logging instead, matching the defensive style used in GetWeight* methods.

🔎 Suggested defensive approach
-        if (prevFontFamily != GUIUtil::g_font_registry.GetFont()) {
-            assert(GUIUtil::g_font_registry.SetFont(prevFontFamily));
-            GUIUtil::setApplicationFont();
-        }
+        if (prevFontFamily != GUIUtil::g_font_registry.GetFont()) {
+            if (!GUIUtil::g_font_registry.SetFont(prevFontFamily)) {
+                qWarning() << "Failed to restore previous font family:" << prevFontFamily;
+            }
+            GUIUtil::setApplicationFont();
+        }

119-122: Assert may crash if font index is out of bounds.

The assert on line 119 assumes SetFont will always succeed for fonts in g_fonts_known. While this should be safe during normal operation, a bounds check before accessing g_fonts_known would be more defensive.

🔎 Suggested bounds check
 void AppearanceWidget::updateFontFamily(int index)
 {
-    assert(GUIUtil::g_font_registry.SetFont(GUIUtil::g_fonts_known[ui->fontFamily->itemData(index).toInt()]));
+    int fontIdx = ui->fontFamily->itemData(index).toInt();
+    if (fontIdx < 0 || static_cast<size_t>(fontIdx) >= GUIUtil::g_fonts_known.size()) {
+        qWarning() << "Invalid font index:" << fontIdx;
+        return;
+    }
+    if (!GUIUtil::g_font_registry.SetFont(GUIUtil::g_fonts_known[fontIdx])) {
+        qWarning() << "Failed to set font:" << GUIUtil::g_fonts_known[fontIdx];
+        return;
+    }
     GUIUtil::setApplicationFont();
     GUIUtil::updateFonts();
     updateWeightSlider(true);
 }
src/qt/guiutil_font.cpp (1)

352-363: Move static ignore lists outside the loop.

The vecIgnoreClasses and vecIgnoreObjects vectors are recreated on every iteration of the widget loop. Moving them outside the loop (or making them static const) would improve performance, especially when there are many widgets.

🔎 Suggested fix
+    static const std::vector<QString> vecIgnoreClasses{
+        "QWidget", "QDialog", "QFrame", "QStackedWidget", "QDesktopWidget", "QDesktopScreenWidget",
+        "QTipLabel", "QMessageBox", "QMenu", "QComboBoxPrivateScroller", "QComboBoxPrivateContainer",
+        "QScrollBar", "QListView", "BitcoinGUI", "WalletView", "WalletFrame", "QVBoxLayout", "QGroupBox"
+    };
+    static const std::vector<QString> vecIgnoreObjects{
+        "messagesWidget"
+    };
+
     // Loop through all widgets
     for (QWidget* w : qApp->allWidgets()) {
-        std::vector<QString> vecIgnoreClasses{
-            "QWidget", "QDialog", "QFrame", "QStackedWidget", "QDesktopWidget", "QDesktopScreenWidget",
-            "QTipLabel", "QMessageBox", "QMenu", "QComboBoxPrivateScroller", "QComboBoxPrivateContainer",
-            "QScrollBar", "QListView", "BitcoinGUI", "WalletView", "WalletFrame", "QVBoxLayout", "QGroupBox"
-        };
-        std::vector<QString> vecIgnoreObjects{
-            "messagesWidget"
-        };
         if (std::find(vecIgnoreClasses.begin(), vecIgnoreClasses.end(), w->metaObject()->className()) != vecIgnoreClasses.end() ||
src/qt/guiutil_font.h (1)

79-80: Consider documenting the scaling formula.

The GetScaledFontSize formula std::round(size * (1 + (m_font_scale * m_scale_steps)) * 4) / 4.0 rounds to 0.25pt increments. A brief comment explaining this design choice would help maintainers.

🔎 Suggested documentation
     double GetScaleSteps() const { return m_scale_steps; }
+    // Scale font size by (1 + scale * steps), rounding to nearest 0.25pt for smoother rendering
     double GetScaledFontSize(int size) const { return std::round(size * (1 + (m_font_scale * m_scale_steps)) * 4) / 4.0; }
📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 719717a and 2dc48de.

📒 Files selected for processing (8)
  • src/qt/appearancewidget.cpp
  • src/qt/appearancewidget.h
  • src/qt/bitcoin.cpp
  • src/qt/guiutil_font.cpp
  • src/qt/guiutil_font.h
  • src/qt/optionsmodel.cpp
  • src/qt/overviewpage.cpp
  • src/qt/test/apptests.cpp
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/qt/overviewpage.cpp
  • src/qt/appearancewidget.h
  • src/qt/bitcoin.cpp
🧰 Additional context used
📓 Path-based instructions (2)
src/**/*.{cpp,h,hpp,cc}

📄 CodeRabbit inference engine (CLAUDE.md)

Dash Core implementation must be written in C++20, requiring at least Clang 16 or GCC 11.1

Files:

  • src/qt/optionsmodel.cpp
  • src/qt/test/apptests.cpp
  • src/qt/guiutil_font.h
  • src/qt/appearancewidget.cpp
  • src/qt/guiutil_font.cpp
src/qt/**/*.{cpp,h}

📄 CodeRabbit inference engine (CLAUDE.md)

GUI implementation in src/qt/ must use Qt 5

Files:

  • src/qt/optionsmodel.cpp
  • src/qt/test/apptests.cpp
  • src/qt/guiutil_font.h
  • src/qt/appearancewidget.cpp
  • src/qt/guiutil_font.cpp
🧠 Learnings (8)
📓 Common learnings
Learnt from: kwvg
Repo: dashpay/dash PR: 6761
File: src/chainlock/signing.cpp:15-250
Timestamp: 2025-07-23T09:28:32.783Z
Learning: In refactoring PRs like #6761, kwvg prefers to defer code formatting fixes to separate follow-up PRs when formatting is not the primary objective, to maintain focus on the structural changes and avoid scope creep.
Learnt from: kwvg
Repo: dashpay/dash PR: 6761
File: src/wallet/wallet.cpp:0-0
Timestamp: 2025-07-29T14:33:01.040Z
Learning: In refactoring PRs like #6761, kwvg acknowledges code safety improvements (like null pointer checks and unused parameter warnings) but prefers to defer them to follow-up PRs to maintain focus on the primary refactoring objectives, avoiding scope creep.
Learnt from: kwvg
Repo: dashpay/dash PR: 6543
File: src/wallet/receive.cpp:240-251
Timestamp: 2025-02-06T14:34:30.466Z
Learning: Pull request #6543 is focused on move-only changes and refactoring, specifically backporting from Bitcoin. Behavior changes should be proposed in separate PRs.
Learnt from: kwvg
Repo: dashpay/dash PR: 6718
File: test/functional/test_framework/test_framework.py:2102-2102
Timestamp: 2025-06-09T16:43:20.996Z
Learning: In the test framework consolidation PR (#6718), user kwvg prefers to limit functional changes to those directly related to MasternodeInfo, avoiding scope creep even for minor improvements like error handling consistency.
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/qt/**/*.{cpp,h} : GUI implementation in src/qt/ must use Qt 5

Applied to files:

  • src/qt/optionsmodel.cpp
  • src/qt/test/apptests.cpp
  • src/qt/guiutil_font.h
  • src/qt/appearancewidget.cpp
  • src/qt/guiutil_font.cpp
📚 Learning: 2025-12-17T13:58:19.813Z
Learnt from: kwvg
Repo: dashpay/dash PR: 7072
File: src/qt/walletcontroller.cpp:520-528
Timestamp: 2025-12-17T13:58:19.813Z
Learning: In Dash Qt wallet code, prefer using existing Qt signals/slots (e.g., ShowProgress signals) for long-running operations instead of adding explicit QProgressDialog dialogs. This minimizes upstream deviations and simplifies backports. Apply this pattern to wallet-related Qt components (e.g., operations like rescanning) and rely on signal-based progress updates rather than bespoke dialogs.

Applied to files:

  • src/qt/optionsmodel.cpp
  • src/qt/test/apptests.cpp
  • src/qt/appearancewidget.cpp
  • src/qt/guiutil_font.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/{test,wallet/test}/**/*.{cpp,h} : Unit tests in src/test/ and src/wallet/test/ must use Boost::Test framework

Applied to files:

  • src/qt/test/apptests.cpp
📚 Learning: 2025-10-05T20:38:28.457Z
Learnt from: knst
Repo: dashpay/dash PR: 6871
File: contrib/guix/libexec/build.sh:358-360
Timestamp: 2025-10-05T20:38:28.457Z
Learning: In the Dash repository, when backporting code from Bitcoin Core, typos and minor issues in comments should be kept as-is to reduce merge conflicts in future backports, even if they remain unfixed in Bitcoin Core's master branch.

Applied to files:

  • src/qt/guiutil_font.h
📚 Learning: 2025-07-23T09:28:32.783Z
Learnt from: kwvg
Repo: dashpay/dash PR: 6761
File: src/chainlock/signing.cpp:15-250
Timestamp: 2025-07-23T09:28:32.783Z
Learning: In refactoring PRs like #6761, kwvg prefers to defer code formatting fixes to separate follow-up PRs when formatting is not the primary objective, to maintain focus on the structural changes and avoid scope creep.

Applied to files:

  • src/qt/guiutil_font.cpp
📚 Learning: 2025-02-14T15:15:58.165Z
Learnt from: kwvg
Repo: dashpay/dash PR: 6529
File: src/rpc/governance.cpp:1074-1089
Timestamp: 2025-02-14T15:15:58.165Z
Learning: Code blocks marked with `// clang-format off` and `// clang-format on` directives should be excluded from clang-format suggestions as they are intentionally formatted manually for better readability.

Applied to files:

  • src/qt/guiutil_font.cpp
📚 Learning: 2025-08-19T14:57:31.801Z
Learnt from: knst
Repo: dashpay/dash PR: 6692
File: src/llmq/blockprocessor.cpp:217-224
Timestamp: 2025-08-19T14:57:31.801Z
Learning: In PR #6692, knst acknowledged a null pointer dereference issue in ProcessBlock() method where LookupBlockIndex may return nullptr but is passed to gsl::not_null, and created follow-up PR #6789 to address it, consistent with avoiding scope creep in performance-focused PRs.

Applied to files:

  • src/qt/guiutil_font.cpp
🧬 Code graph analysis (4)
src/qt/optionsmodel.cpp (1)
src/qt/guiutil_font.cpp (8)
  • setApplicationFont (268-301)
  • setApplicationFont (268-268)
  • weightToArg (141-145)
  • weightToArg (141-141)
  • weightFromArg (131-139)
  • weightFromArg (131-131)
  • updateFonts (314-420)
  • updateFonts (314-314)
src/qt/test/apptests.cpp (1)
src/qt/guiutil_font.cpp (2)
  • setApplicationFont (268-301)
  • setApplicationFont (268-268)
src/qt/appearancewidget.cpp (1)
src/qt/guiutil_font.cpp (4)
  • setApplicationFont (268-301)
  • setApplicationFont (268-268)
  • updateFonts (314-420)
  • updateFonts (314-314)
src/qt/guiutil_font.cpp (1)
src/qt/guiutil.cpp (2)
  • TextWidth (1284-1287)
  • TextWidth (1284-1284)
🪛 Cppcheck (2.18.0)
src/qt/guiutil_font.cpp

[error] 52-52: There is an unknown macro here somewhere. Configuration is required. If QT_END_NAMESPACE is a macro then please configure it.

(unknownMacro)

🪛 GitHub Actions: Clang Diff Format Check
src/qt/guiutil_font.h

[error] 1-1: Clang format differences found. Run './contrib/devtools/clang-format-diff.py -p1' to update formatting.

src/qt/guiutil_font.cpp

[error] 1-1: Clang format differences found. Run './contrib/devtools/clang-format-diff.py -p1' to update formatting.

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (11)
  • GitHub Check: predict_conflicts
  • GitHub Check: win64-build / Build source
  • GitHub Check: mac-build / Build source
  • GitHub Check: linux64_nowallet-build / Build source
  • GitHub Check: linux64_tsan-build / Build source
  • GitHub Check: linux64_sqlite-build / Build source
  • GitHub Check: linux64_ubsan-build / Build source
  • GitHub Check: linux64-build / Build source
  • GitHub Check: linux64_fuzz-build / Build source
  • GitHub Check: arm-linux-build / Build source
  • GitHub Check: Lint / Run linters
🔇 Additional comments (9)
src/qt/test/apptests.cpp (1)

82-84: LGTM! Correct initialization order for font setup.

The call to setApplicationFont() is correctly placed after loadFonts() and before createOptionsModel(), ensuring fonts are properly initialized before the options model processes font-related settings.

src/qt/optionsmodel.cpp (3)

156-158: Good: Batched font update after all settings.

Calling updateFonts() once after processing all font-related settings (family, scale, weight normal, weight bold) is efficient and prevents multiple redundant font updates.


100-108: LGTM! Font family initialization with proper flow.

The initialization correctly:

  1. Sets a default value using FontRegistry::DEFAULT_FONT
  2. Registers the font before setting it
  3. Calls setApplicationFont() to apply changes
  4. Handles command-line override gracefully

553-568: The assertion on lines 558/566 is safe and will not fail. The default weights are guaranteed to be in the supported weights list.

In CalcDefaultWeights (guiutil_font.cpp:189-200), m_normal_default and m_bold_default are set exclusively by calling GetBestMatch, which always returns a weight from m_supported_weights (lines 173-187). Since CalcSupportedWeights ensures m_supported_weights is never empty (line 169 provides a fallback), and both defaults are sourced from this non-empty list, WeightToIdx(GetWeightNormalDefault()) will always find the weight and return a valid index. The assertion is correct.

src/qt/appearancewidget.cpp (1)

36-38: LGTM! Dynamic font family population.

The font family combo box is now populated from g_fonts_known, which allows for extensibility if additional fonts are registered at runtime.

src/qt/guiutil_font.cpp (2)

69-74: Nice helper function for debug logging.

The qstrprintf template provides a clean wrapper around tinyformat for Qt string output, improving code readability compared to manual conversions.


204-261: Robust font loading with proper error handling.

The loadFonts() function correctly:

  1. Stores the OS default font before any modifications
  2. Loads all Montserrat variants including italic styles
  3. Checks for failures and cleans up osDefaultFont on error
  4. Registers all known fonts after successful loading
src/qt/guiutil_font.h (2)

45-58: Well-designed constants with platform-specific handling.

The FontRegistry class provides clear constants for defaults with appropriate platform-specific handling for macOS font weights. The use of constexpr ensures compile-time evaluation.


8-16: LGTM! Clean header organization.

The includes are properly organized with Qt headers first, followed by standard library headers. The <map> header is now included as addressed in a previous review.

@kwvg kwvg requested a review from UdjinM6 December 22, 2025 15:50
@kwvg kwvg changed the title refactor: extract Dash-specific font infrastructure to qt/guiutil_font.{cpp,h}, encapsulate globals into Font{Info,Registry} feat(qt): extract Dash-specific font infrastructure to qt/guiutil_font.{cpp,h}, encapsulate globals into Font{Info,Registry}, add arbitrary font support Dec 22, 2025
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/qt/optionsdialog.cpp (1)

16-18: Missing guiutil_font include when using GUIUtil::g_font_registry

OptionsDialog now calls GUIUtil::setFont(..., {GUIUtil::g_font_registry.GetWeightBold()/GetWeightNormal(), ...}) but this file does not include qt/guiutil_font.h. Relying on transitive includes is brittle and may fail to compile if guiutil.h no longer exposes the font registry symbols.

Add the explicit include alongside the other Qt GUIUtil headers.

[ suggest_essential_refactor ]

Proposed include fix
 #include <qt/guiconstants.h>
 #include <qt/guiutil.h>
+#include <qt/guiutil_font.h>
 #include <qt/optionsmodel.h>

Also applies to: 52-55, 389-405

src/qt/signverifymessagedialog.cpp (1)

105-121: Fix incorrect setFont call for vecNormal (compile-time type error)

In showPage, the second setFont call currently passes {vecNormal} instead of vecNormal. Given the signature setFont(const std::vector<QWidget*>&, const FontAttrib&), {vecNormal} forms an std::initializer_list<std::vector<QWidget*>> and will not compile.

Use vecNormal directly, mirroring the pattern in OptionsDialog::showPage and BitcoinGUI::createToolBars().

Proposed fix for `showPage`
-    GUIUtil::setFont({btnActive}, {GUIUtil::g_font_registry.GetWeightBold(), 16});
-    GUIUtil::setFont({vecNormal}, {GUIUtil::g_font_registry.GetWeightNormal(), 16});
+    GUIUtil::setFont({btnActive}, {GUIUtil::g_font_registry.GetWeightBold(), 16});
+    GUIUtil::setFont(vecNormal, {GUIUtil::g_font_registry.GetWeightNormal(), 16});
🧹 Nitpick comments (2)
src/qt/masternodelist.cpp (1)

1-15: Address clang-format diff failures reported by CI

The Clang Diff Format Check workflow is failing; please run the suggested clang-format-diff.py command from the pipeline output and apply the resulting patch to bring this file (and any other touched Qt sources) in line with the project’s formatting rules.

src/qt/sendcoinsdialog.cpp (1)

18-92: Send dialog font wiring into FontRegistry is correct (only a minor nit)

The new qt/guiutil_font.h include and use of GUIUtil::g_font_registry for the various headings (labelCoinControl*, labelBalance*) are type‑correct and align with the rest of the PR. Calling setFont twice for labelCoinControlFeatures is harmless since the latter call overwrites the previous attributes; if you touch this again, you might optionally drop it from the first batch to avoid the redundant map update.

📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2dc48de and 14137c6.

📒 Files selected for processing (23)
  • src/qt/askpassphrasedialog.cpp
  • src/qt/bitcoin.cpp
  • src/qt/bitcoingui.cpp
  • src/qt/coincontroldialog.cpp
  • src/qt/governancelist.cpp
  • src/qt/guiutil.cpp
  • src/qt/guiutil_font.cpp
  • src/qt/guiutil_font.h
  • src/qt/masternodelist.cpp
  • src/qt/modaloverlay.cpp
  • src/qt/optionsdialog.cpp
  • src/qt/optionsmodel.cpp
  • src/qt/overviewpage.cpp
  • src/qt/proposalwizard.cpp
  • src/qt/qrdialog.cpp
  • src/qt/receivecoinsdialog.cpp
  • src/qt/rpcconsole.cpp
  • src/qt/sendcoinsdialog.cpp
  • src/qt/sendcoinsentry.cpp
  • src/qt/signverifymessagedialog.cpp
  • src/qt/test/apptests.cpp
  • src/qt/trafficgraphwidget.cpp
  • src/qt/walletview.cpp
🚧 Files skipped from review as they are similar to previous changes (4)
  • src/qt/coincontroldialog.cpp
  • src/qt/walletview.cpp
  • src/qt/overviewpage.cpp
  • src/qt/rpcconsole.cpp
🧰 Additional context used
📓 Path-based instructions (2)
src/**/*.{cpp,h,hpp,cc}

📄 CodeRabbit inference engine (CLAUDE.md)

Dash Core implementation must be written in C++20, requiring at least Clang 16 or GCC 11.1

Files:

  • src/qt/test/apptests.cpp
  • src/qt/receivecoinsdialog.cpp
  • src/qt/proposalwizard.cpp
  • src/qt/governancelist.cpp
  • src/qt/modaloverlay.cpp
  • src/qt/trafficgraphwidget.cpp
  • src/qt/optionsmodel.cpp
  • src/qt/sendcoinsdialog.cpp
  • src/qt/askpassphrasedialog.cpp
  • src/qt/bitcoingui.cpp
  • src/qt/bitcoin.cpp
  • src/qt/optionsdialog.cpp
  • src/qt/guiutil_font.h
  • src/qt/sendcoinsentry.cpp
  • src/qt/signverifymessagedialog.cpp
  • src/qt/guiutil.cpp
  • src/qt/guiutil_font.cpp
  • src/qt/masternodelist.cpp
  • src/qt/qrdialog.cpp
src/qt/**/*.{cpp,h}

📄 CodeRabbit inference engine (CLAUDE.md)

GUI implementation in src/qt/ must use Qt 5

Files:

  • src/qt/test/apptests.cpp
  • src/qt/receivecoinsdialog.cpp
  • src/qt/proposalwizard.cpp
  • src/qt/governancelist.cpp
  • src/qt/modaloverlay.cpp
  • src/qt/trafficgraphwidget.cpp
  • src/qt/optionsmodel.cpp
  • src/qt/sendcoinsdialog.cpp
  • src/qt/askpassphrasedialog.cpp
  • src/qt/bitcoingui.cpp
  • src/qt/bitcoin.cpp
  • src/qt/optionsdialog.cpp
  • src/qt/guiutil_font.h
  • src/qt/sendcoinsentry.cpp
  • src/qt/signverifymessagedialog.cpp
  • src/qt/guiutil.cpp
  • src/qt/guiutil_font.cpp
  • src/qt/masternodelist.cpp
  • src/qt/qrdialog.cpp
🧠 Learnings (27)
📓 Common learnings
Learnt from: kwvg
Repo: dashpay/dash PR: 7068
File: src/qt/guiutil_font.h:68-77
Timestamp: 2025-12-22T15:42:48.595Z
Learning: In the Dash Core Qt codebase (src/qt/guiutil_font.h), kwvg intentionally uses `assert()` in setter methods like `SetWeightBold` and `SetWeightNormal` to enforce invariants (e.g., `assert(m_weights.count(m_font))`). This fail-fast approach is preferred over defensive checks with fallbacks when an inconsistent state indicates a programming error that should be caught during development, rather than a runtime condition requiring graceful handling.
Learnt from: kwvg
Repo: dashpay/dash PR: 6761
File: src/chainlock/signing.cpp:15-250
Timestamp: 2025-07-23T09:28:32.783Z
Learning: In refactoring PRs like #6761, kwvg prefers to defer code formatting fixes to separate follow-up PRs when formatting is not the primary objective, to maintain focus on the structural changes and avoid scope creep.
Learnt from: kwvg
Repo: dashpay/dash PR: 7072
File: src/qt/walletcontroller.cpp:520-528
Timestamp: 2025-12-17T13:58:26.891Z
Learning: In Dash Qt wallet code, when leveraging upstream Bitcoin Core wallet capabilities (especially for operations like rescanning), prefer using the inherited signal-based mechanisms (e.g., ShowProgress signals) over adding explicit Qt progress dialogs to minimize upstream deviation and simplify future backports.
Learnt from: kwvg
Repo: dashpay/dash PR: 6718
File: test/functional/test_framework/test_framework.py:2102-2102
Timestamp: 2025-06-09T16:43:20.996Z
Learning: In the test framework consolidation PR (#6718), user kwvg prefers to limit functional changes to those directly related to MasternodeInfo, avoiding scope creep even for minor improvements like error handling consistency.
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/qt/**/*.{cpp,h} : GUI implementation in src/qt/ must use Qt 5

Applied to files:

  • src/qt/test/apptests.cpp
  • src/qt/receivecoinsdialog.cpp
  • src/qt/proposalwizard.cpp
  • src/qt/governancelist.cpp
  • src/qt/modaloverlay.cpp
  • src/qt/trafficgraphwidget.cpp
  • src/qt/optionsmodel.cpp
  • src/qt/sendcoinsdialog.cpp
  • src/qt/askpassphrasedialog.cpp
  • src/qt/bitcoingui.cpp
  • src/qt/bitcoin.cpp
  • src/qt/guiutil_font.h
  • src/qt/sendcoinsentry.cpp
  • src/qt/signverifymessagedialog.cpp
  • src/qt/guiutil.cpp
  • src/qt/guiutil_font.cpp
  • src/qt/masternodelist.cpp
  • src/qt/qrdialog.cpp
📚 Learning: 2025-12-22T15:42:48.595Z
Learnt from: kwvg
Repo: dashpay/dash PR: 7068
File: src/qt/guiutil_font.h:68-77
Timestamp: 2025-12-22T15:42:48.595Z
Learning: In the Dash Core Qt codebase (src/qt/guiutil_font.h), kwvg intentionally uses `assert()` in setter methods like `SetWeightBold` and `SetWeightNormal` to enforce invariants (e.g., `assert(m_weights.count(m_font))`). This fail-fast approach is preferred over defensive checks with fallbacks when an inconsistent state indicates a programming error that should be caught during development, rather than a runtime condition requiring graceful handling.

Applied to files:

  • src/qt/test/apptests.cpp
  • src/qt/receivecoinsdialog.cpp
  • src/qt/proposalwizard.cpp
  • src/qt/governancelist.cpp
  • src/qt/modaloverlay.cpp
  • src/qt/trafficgraphwidget.cpp
  • src/qt/optionsmodel.cpp
  • src/qt/sendcoinsdialog.cpp
  • src/qt/askpassphrasedialog.cpp
  • src/qt/bitcoingui.cpp
  • src/qt/bitcoin.cpp
  • src/qt/optionsdialog.cpp
  • src/qt/sendcoinsentry.cpp
  • src/qt/signverifymessagedialog.cpp
  • src/qt/guiutil.cpp
  • src/qt/guiutil_font.cpp
  • src/qt/masternodelist.cpp
  • src/qt/qrdialog.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/{test,wallet/test}/**/*.{cpp,h} : Unit tests in src/test/ and src/wallet/test/ must use Boost::Test framework

Applied to files:

  • src/qt/test/apptests.cpp
📚 Learning: 2025-12-17T13:58:19.813Z
Learnt from: kwvg
Repo: dashpay/dash PR: 7072
File: src/qt/walletcontroller.cpp:520-528
Timestamp: 2025-12-17T13:58:19.813Z
Learning: In Dash Qt wallet code, prefer using existing Qt signals/slots (e.g., ShowProgress signals) for long-running operations instead of adding explicit QProgressDialog dialogs. This minimizes upstream deviations and simplifies backports. Apply this pattern to wallet-related Qt components (e.g., operations like rescanning) and rely on signal-based progress updates rather than bespoke dialogs.

Applied to files:

  • src/qt/test/apptests.cpp
  • src/qt/receivecoinsdialog.cpp
  • src/qt/proposalwizard.cpp
  • src/qt/governancelist.cpp
  • src/qt/modaloverlay.cpp
  • src/qt/trafficgraphwidget.cpp
  • src/qt/optionsmodel.cpp
  • src/qt/sendcoinsdialog.cpp
  • src/qt/askpassphrasedialog.cpp
  • src/qt/bitcoingui.cpp
  • src/qt/bitcoin.cpp
  • src/qt/optionsdialog.cpp
  • src/qt/sendcoinsentry.cpp
  • src/qt/signverifymessagedialog.cpp
  • src/qt/guiutil.cpp
  • src/qt/guiutil_font.cpp
  • src/qt/masternodelist.cpp
  • src/qt/qrdialog.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/wallet/**/*.{cpp,h} : Wallet implementation must use Berkeley DB and SQLite

Applied to files:

  • src/qt/askpassphrasedialog.cpp
📚 Learning: 2025-12-22T15:42:48.595Z
Learnt from: kwvg
Repo: dashpay/dash PR: 7068
File: src/qt/guiutil_font.h:68-77
Timestamp: 2025-12-22T15:42:48.595Z
Learning: In C++/Qt codebases, use fail-fast asserts in setters to enforce invariants (e.g., ensuring internal maps contain necessary keys). Prefer assert() for programmer errors that should be caught in development and debugging, rather than defensive runtime checks with fallbacks. This helps catch invariant violations early during development. Apply to header and source files where invariant-driven state mutations occur, especially in setters like SetWeightBold/SetWeightNormal that assume established relationships or preconditions.

Applied to files:

  • src/qt/guiutil_font.h
📚 Learning: 2025-10-05T20:38:28.457Z
Learnt from: knst
Repo: dashpay/dash PR: 6871
File: contrib/guix/libexec/build.sh:358-360
Timestamp: 2025-10-05T20:38:28.457Z
Learning: In the Dash repository, when backporting code from Bitcoin Core, typos and minor issues in comments should be kept as-is to reduce merge conflicts in future backports, even if they remain unfixed in Bitcoin Core's master branch.

Applied to files:

  • src/qt/guiutil_font.h
  • src/qt/guiutil_font.cpp
📚 Learning: 2025-07-17T15:48:29.418Z
Learnt from: kwvg
Repo: dashpay/dash PR: 6752
File: src/wallet/load.cpp:164-164
Timestamp: 2025-07-17T15:48:29.418Z
Learning: In Dash Core, kwvg prefers using assert() statements to document expected behavior in code paths, especially when the called function also has internal asserts. This is used as a defensive programming pattern rather than requiring conditional error handling.

Applied to files:

  • src/qt/guiutil_font.h
📚 Learning: 2025-07-29T14:33:01.040Z
Learnt from: kwvg
Repo: dashpay/dash PR: 6761
File: src/wallet/wallet.cpp:0-0
Timestamp: 2025-07-29T14:33:01.040Z
Learning: In refactoring PRs like #6761, kwvg acknowledges code safety improvements (like null pointer checks and unused parameter warnings) but prefers to defer them to follow-up PRs to maintain focus on the primary refactoring objectives, avoiding scope creep.

Applied to files:

  • src/qt/guiutil_font.h
  • src/qt/guiutil_font.cpp
📚 Learning: 2025-07-23T09:28:32.783Z
Learnt from: kwvg
Repo: dashpay/dash PR: 6761
File: src/chainlock/signing.cpp:15-250
Timestamp: 2025-07-23T09:28:32.783Z
Learning: In refactoring PRs like #6761, kwvg prefers to defer code formatting fixes to separate follow-up PRs when formatting is not the primary objective, to maintain focus on the structural changes and avoid scope creep.

Applied to files:

  • src/qt/guiutil_font.h
  • src/qt/guiutil_font.cpp
📚 Learning: 2025-07-29T14:32:48.369Z
Learnt from: kwvg
Repo: dashpay/dash PR: 6761
File: src/chainlock/signing.cpp:247-250
Timestamp: 2025-07-29T14:32:48.369Z
Learning: In PR #6761, kwvg acknowledged a null pointer check issue in ChainLockSigner::Cleanup() method but deferred it to follow-up, consistent with the pattern of avoiding scope creep in refactoring PRs.

Applied to files:

  • src/qt/guiutil_font.h
  • src/qt/guiutil_font.cpp
📚 Learning: 2025-06-09T16:43:20.996Z
Learnt from: kwvg
Repo: dashpay/dash PR: 6718
File: test/functional/test_framework/test_framework.py:2102-2102
Timestamp: 2025-06-09T16:43:20.996Z
Learning: In the test framework consolidation PR (#6718), user kwvg prefers to limit functional changes to those directly related to MasternodeInfo, avoiding scope creep even for minor improvements like error handling consistency.

Applied to files:

  • src/qt/guiutil_font.h
  • src/qt/guiutil_font.cpp
📚 Learning: 2025-11-04T18:24:27.241Z
Learnt from: UdjinM6
Repo: dashpay/dash PR: 6933
File: src/llmq/utils.cpp:284-298
Timestamp: 2025-11-04T18:24:27.241Z
Learning: In consensus-critical code (such as quorum formation, block validation, or deployment activation logic), do not suggest changes to the logic itself even if the implementation appears theoretically incorrect or off-by-one. Consensus rules, once deployed on the Dash network, must be preserved exactly to avoid network forks. Refactoring PRs should maintain perfect behavioral equivalence. Only suggest logic changes if explicitly accompanied by a DIP (Dash Improvement Proposal) or if the maintainer indicates the consensus rule needs to be changed with appropriate activation logic.

Applied to files:

  • src/qt/guiutil_font.h
  • src/qt/guiutil_font.cpp
📚 Learning: 2025-12-17T13:58:26.891Z
Learnt from: kwvg
Repo: dashpay/dash PR: 7072
File: src/qt/walletcontroller.cpp:520-528
Timestamp: 2025-12-17T13:58:26.891Z
Learning: In Dash Qt wallet code, when leveraging upstream Bitcoin Core wallet capabilities (especially for operations like rescanning), prefer using the inherited signal-based mechanisms (e.g., ShowProgress signals) over adding explicit Qt progress dialogs to minimize upstream deviation and simplify future backports.

Applied to files:

  • src/qt/guiutil_font.h
📚 Learning: 2025-08-11T17:16:36.654Z
Learnt from: PastaPastaPasta
Repo: dashpay/dash PR: 6804
File: src/qt/proposalwizard.cpp:40-42
Timestamp: 2025-08-11T17:16:36.654Z
Learning: In the Dash repository, when a PR adds new files that are not from Bitcoin backports, these files must be added to the list in test/util/data/non-backported.txt. This applies to newly created files like qt/proposalwizard.{h,cpp} and forms/proposalwizard.ui. Limited exemptions may exist for subtrees and similar cases.

Applied to files:

  • src/qt/guiutil_font.h
📚 Learning: 2025-02-06T14:34:30.466Z
Learnt from: kwvg
Repo: dashpay/dash PR: 6543
File: src/wallet/receive.cpp:240-251
Timestamp: 2025-02-06T14:34:30.466Z
Learning: Pull request #6543 is focused on move-only changes and refactoring, specifically backporting from Bitcoin. Behavior changes should be proposed in separate PRs.

Applied to files:

  • src/qt/guiutil_font.cpp
📚 Learning: 2025-02-14T15:15:58.165Z
Learnt from: kwvg
Repo: dashpay/dash PR: 6529
File: src/rpc/governance.cpp:1074-1089
Timestamp: 2025-02-14T15:15:58.165Z
Learning: Code blocks marked with `// clang-format off` and `// clang-format on` directives should be excluded from clang-format suggestions as they are intentionally formatted manually for better readability.

Applied to files:

  • src/qt/guiutil_font.cpp
📚 Learning: 2025-08-19T14:57:31.801Z
Learnt from: knst
Repo: dashpay/dash PR: 6692
File: src/llmq/blockprocessor.cpp:217-224
Timestamp: 2025-08-19T14:57:31.801Z
Learning: In PR #6692, knst acknowledged a null pointer dereference issue in ProcessBlock() method where LookupBlockIndex may return nullptr but is passed to gsl::not_null, and created follow-up PR #6789 to address it, consistent with avoiding scope creep in performance-focused PRs.

Applied to files:

  • src/qt/guiutil_font.cpp
📚 Learning: 2025-07-09T15:05:36.250Z
Learnt from: kwvg
Repo: dashpay/dash PR: 6729
File: src/rpc/evo.cpp:1273-1273
Timestamp: 2025-07-09T15:05:36.250Z
Learning: When clang-format suggestions significantly harm readability (like splitting logical parameter groups across multiple lines), it's acceptable to use `// clang-format off` and `// clang-format on` directives to exclude the problematic section from automatic formatting, prioritizing code readability over strict line length compliance.

Applied to files:

  • src/qt/guiutil_font.cpp
📚 Learning: 2025-10-13T12:37:12.357Z
Learnt from: knst
Repo: dashpay/dash PR: 6883
File: src/rpc/rawtransaction.cpp:1088-1125
Timestamp: 2025-10-13T12:37:12.357Z
Learning: In backport pull requests (especially from Bitcoin Core), treat "moved" or refactored code as out-of-scope for content-level review. Focus validation on verifying that code is moved correctly: no fields added, no fields removed, no fields reordered, and no unexpected changes beyond whitespace adjustments. Pre-existing issues in the upstream code should be preserved to maintain fidelity to the original implementation.

Applied to files:

  • src/qt/guiutil_font.cpp
📚 Learning: 2025-10-25T07:08:51.918Z
Learnt from: knst
Repo: dashpay/dash PR: 6916
File: src/univalue/include/univalue.h:81-88
Timestamp: 2025-10-25T07:08:51.918Z
Learning: For backport PRs from bitcoin/bitcoin, bitcoin-core/gui, etc., backported changes should match the original upstream PRs even if they appear strange, modify vendored code, or seem to violate coding guidelines. Still flag genuine issues like bugs, undefined behavior, crashes, compilation errors, or linter failures.

Applied to files:

  • src/qt/guiutil_font.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/coinjoin/**/*.{cpp,h} : CoinJoin implementation must use masternode-coordinated mixing sessions with uniform denomination outputs

Applied to files:

  • src/qt/masternodelist.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/evo/evodb/**/*.{cpp,h} : Evolution Database (CEvoDb) must handle masternode snapshots, quorum state, governance objects with efficient differential updates for masternode lists

Applied to files:

  • src/qt/masternodelist.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/{masternode,evo,llmq,governance,coinjoin}/**/*.{cpp,h} : Use Dash-specific database implementations: CFlatDB for persistent storage (MasternodeMetaStore, GovernanceStore, SporkStore, NetFulfilledRequestStore) and CDBWrapper extensions for Evolution/DKG/InstantSend/Quorum/RecoveredSigs data

Applied to files:

  • src/qt/masternodelist.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/{masternode,llmq}/**/*.{cpp,h} : BLS integration must be used for cryptographic foundation of advanced masternode features

Applied to files:

  • src/qt/masternodelist.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/{masternode,evo}/**/*.{cpp,h} : Masternode lists must use immutable data structures (Immer library) for thread safety

Applied to files:

  • src/qt/masternodelist.cpp
🧬 Code graph analysis (16)
src/qt/test/apptests.cpp (1)
src/qt/guiutil_font.cpp (2)
  • setApplicationFont (305-338)
  • setApplicationFont (305-305)
src/qt/receivecoinsdialog.cpp (1)
src/qt/guiutil_font.cpp (2)
  • setFont (340-348)
  • setFont (340-340)
src/qt/proposalwizard.cpp (1)
src/qt/guiutil_font.cpp (2)
  • setFont (340-348)
  • setFont (340-340)
src/qt/governancelist.cpp (1)
src/qt/guiutil_font.cpp (2)
  • setFont (340-348)
  • setFont (340-340)
src/qt/trafficgraphwidget.cpp (1)
src/qt/guiutil_font.cpp (4)
  • getFont (447-501)
  • getFont (447-447)
  • getFont (503-506)
  • getFont (503-503)
src/qt/optionsmodel.cpp (1)
src/qt/guiutil_font.cpp (10)
  • fontsLoaded (300-303)
  • fontsLoaded (300-300)
  • setApplicationFont (305-338)
  • setApplicationFont (305-305)
  • weightToArg (178-182)
  • weightToArg (178-178)
  • weightFromArg (168-176)
  • weightFromArg (168-168)
  • updateFonts (350-445)
  • updateFonts (350-350)
src/qt/sendcoinsdialog.cpp (1)
src/qt/guiutil_font.cpp (2)
  • setFont (340-348)
  • setFont (340-340)
src/qt/askpassphrasedialog.cpp (1)
src/qt/guiutil_font.cpp (2)
  • setFont (340-348)
  • setFont (340-340)
src/qt/bitcoingui.cpp (1)
src/qt/guiutil_font.cpp (2)
  • setFont (340-348)
  • setFont (340-340)
src/qt/optionsdialog.cpp (1)
src/qt/guiutil_font.cpp (2)
  • setFont (340-348)
  • setFont (340-340)
src/qt/guiutil_font.h (1)
src/qt/guiutil_font.cpp (34)
  • FontInfo (127-133)
  • FontInfo (135-135)
  • GetBestMatch (210-224)
  • GetBestMatch (210-210)
  • RegisterFont (137-157)
  • RegisterFont (137-137)
  • WeightToIdx (525-534)
  • WeightToIdx (525-525)
  • IdxToWeight (518-523)
  • IdxToWeight (518-518)
  • SetFont (159-166)
  • SetFont (159-159)
  • weightFromArg (168-176)
  • weightFromArg (168-168)
  • weightToArg (178-182)
  • weightToArg (178-178)
  • loadFonts (241-298)
  • loadFonts (241-241)
  • fontsLoaded (300-303)
  • fontsLoaded (300-300)
  • setApplicationFont (305-338)
  • setApplicationFont (305-305)
  • setFont (340-348)
  • setFont (340-340)
  • updateFonts (350-445)
  • updateFonts (350-350)
  • getFont (447-501)
  • getFont (447-447)
  • getFont (503-506)
  • getFont (503-503)
  • getFontNormal (508-511)
  • getFontNormal (508-508)
  • getFontBold (513-516)
  • getFontBold (513-513)
src/qt/signverifymessagedialog.cpp (1)
src/qt/guiutil_font.cpp (2)
  • setFont (340-348)
  • setFont (340-340)
src/qt/guiutil.cpp (1)
src/qt/guiutil_font.cpp (2)
  • setFont (340-348)
  • setFont (340-340)
src/qt/guiutil_font.cpp (1)
src/qt/guiutil.cpp (2)
  • TextWidth (1284-1287)
  • TextWidth (1284-1284)
src/qt/masternodelist.cpp (1)
src/qt/guiutil_font.cpp (2)
  • setFont (340-348)
  • setFont (340-340)
src/qt/qrdialog.cpp (1)
src/qt/guiutil_font.cpp (2)
  • setFont (340-348)
  • setFont (340-340)
🪛 Cppcheck (2.19.0)
src/qt/guiutil_font.cpp

[error] 454-454: failed to evaluate #if condition, undefined function-like macro invocation

(syntaxError)


[error] 22-22: failed to evaluate #if condition, undefined function-like macro invocation

(syntaxError)


[error] 24-24: #error No known always_inline attribute for this platform.

(preprocessorErrorDirective)

src/qt/masternodelist.cpp

[error] 10-10: failed to evaluate #if condition, undefined function-like macro invocation

(syntaxError)

src/qt/qrdialog.cpp

[error] 24-24: #error No known always_inline attribute for this platform.

(preprocessorErrorDirective)

🪛 GitHub Actions: Clang Diff Format Check
src/qt/guiutil_font.h

[error] 1-1: Clang format differences found. Run 'git diff -U0 origin/develop -- $(git ls-files -- $(cat test/util/data/non-backported.txt)) | ./contrib/devtools/clang-format-diff.py -p1 > diff_output.txt' to generate a patch and apply formatting fixes.

src/qt/guiutil_font.cpp

[error] 1-1: Clang format differences found. Run 'git diff -U0 origin/develop -- $(git ls-files -- $(cat test/util/data/non-backported.txt)) | ./contrib/devtools/clang-format-diff.py -p1 > diff_output.txt' to generate a patch and apply formatting fixes.

src/qt/masternodelist.cpp

[error] 1-1: Clang format differences found. Run 'git diff -U0 origin/develop -- $(git ls-files -- $(cat test/util/data/non-backported.txt)) | ./contrib/devtools/clang-format-diff.py -p1 > diff_output.txt' to generate a patch and apply formatting fixes.

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
  • GitHub Check: win64-build / Build source
  • GitHub Check: linux64_tsan-build / Build source
  • GitHub Check: linux64_ubsan-build / Build source
  • GitHub Check: linux64-build / Build source
  • GitHub Check: linux64_fuzz-build / Build source
  • GitHub Check: linux64_sqlite-build / Build source
  • GitHub Check: arm-linux-build / Build source
  • GitHub Check: mac-build / Build source
  • GitHub Check: linux64_nowallet-build / Build source
  • GitHub Check: Lint / Run linters
🔇 Additional comments (27)
src/qt/askpassphrasedialog.cpp (1)

15-15: LGTM! Font registry migration is correct.

The changes properly migrate from the old FontWeight enum to the new FontRegistry-based approach, following the pattern used throughout the codebase.

Also applies to: 34-34

src/qt/bitcoin.cpp (2)

489-492: LGTM! CLI argument setup correctly references FontRegistry defaults.

The help text for font-related arguments properly displays the available fonts and default values from the FontRegistry. The use of Join(GUIUtil::g_fonts_known, ", ") ensures the help text stays in sync with supported fonts.


664-711: Font initialization and validation logic is well-structured.

The font loading and validation sequence is correct:

  1. Load fonts with error handling (lines 664-667)
  2. Validate and set font family with registry checks (lines 671-677)
  3. Validate and set normal/bold weights (lines 679-697)
  4. Validate and set font scale (lines 699-708)
  5. Apply fonts via updateFonts() and setApplicationFont() (lines 710-711)

The error messages are clear and user-friendly. Based on past review comments, the crash issue with invalid fonts has been resolved with proper error handling and arbitrary font support.

src/qt/guiutil_font.cpp (1)

1-535: LGTM! Comprehensive font subsystem implementation.

The new font module successfully encapsulates font management with:

  • Proper resource management using smart pointers
  • FontInfo class for per-font weight calculation
  • FontRegistry class for centralized font state
  • Lifecycle-aware widget tracking with QPointer
  • Platform-specific handling (macOS weight/style naming)
  • Robust font loading with validation

The implementation follows Qt 5 patterns and integrates well with the existing codebase.

Based on learnings, clang-format issues will be handled manually per developer preference in refactoring PRs.

src/qt/guiutil.cpp (1)

300-301: LGTM! Appearance setup correctly migrated to font registry.

The font weight specifications for heading and subheading properly use the registry-derived weights, maintaining the visual hierarchy while enabling dynamic font customization.

src/qt/qrdialog.cpp (1)

11-11: LGTM! Consistent font registry migration.

The QR dialog properly adopts the font registry pattern for its title label.

Also applies to: 24-24

src/qt/test/apptests.cpp (1)

11-11: LGTM! Test environment properly initializes fonts.

The addition of setApplicationFont() after loadFonts() ensures the test environment has properly configured fonts, matching the initialization sequence in the main application.

Also applies to: 83-83

src/qt/modaloverlay.cpp (1)

10-10: LGTM! Modal overlay font styling migrated correctly.

The multiple label widgets are properly styled with the registry-derived bold weight.

Also applies to: 32-32

src/qt/trafficgraphwidget.cpp (1)

9-9: LGTM! Traffic graph statistics fonts properly configured.

The font creation for the traffic statistics panel correctly uses the registry-derived weights with explicit sizes, maintaining the visual hierarchy between title and data labels.

Also applies to: 171-172

src/qt/sendcoinsentry.cpp (1)

16-42: Font registry integration in SendCoinsEntry looks correct

New qt/guiutil_font.h include and use of GUIUtil::g_font_registry.GetWeightNormal() in the setFont call are consistent with the new font subsystem; GUIUtil::updateFonts() is invoked once afterward, so behavior should be preserved.

src/qt/proposalwizard.cpp (1)

16-50: Header font change uses registry correctly

Including qt/guiutil_font.h and switching labelHeader to {GUIUtil::g_font_registry.GetWeightBold(), 16} aligns with the centralized font registry and keeps existing behavior.

src/qt/bitcoingui.cpp (1)

13-19: Toolbar/tab font use of FontRegistry is consistent

The added qt/guiutil_font.h include and use of GUIUtil::g_font_registry.GetWeightNormal()/GetWeightBold() for toolbar tab buttons and highlightTabButton are type‑correct and keep the prior visual semantics.

Also applies to: 757-770, 1239-1243

src/qt/receivecoinsdialog.cpp (1)

10-31: Receive dialog label fonts wired into registry correctly

The new qt/guiutil_font.h include and the two GUIUtil::setFont calls using g_font_registry (bold header + normal body labels) are straightforward and consistent with the new font infrastructure; GUIUtil::updateFonts() is called once after.

src/qt/masternodelist.cpp (1)

8-15: Includes and font registry usage in MasternodeList are sound

Adding <coins.h> matches the later use of Coin and ExtractDestination, and qt/guiutil_font.h is required for g_font_registry. The new setFont calls for the DIP3 header and filter labels are correct and applied via the existing GUIUtil::updateFonts() call at the end of the constructor.

Also applies to: 43-47, 94-95

src/qt/signverifymessagedialog.cpp (1)

11-12: Ctor font registry setup is consistent

Including qt/guiutil_font.h and using g_font_registry for the signature fields and status labels (with size and boolean flag where needed) fits the new font subsystem and is applied via the existing GUIUtil::updateFonts() call.

Also applies to: 57-61

src/qt/governancelist.cpp (2)

21-21: LGTM!

The inclusion of qt/guiutil_font.h is necessary for the font registry API usage below.


315-317: LGTM!

The migration from the old FontWeight enum to the FontRegistry API is correct and consistent with the broader refactoring.

src/qt/optionsmodel.cpp (4)

15-15: LGTM!

The inclusion of qt/guiutil_font.h is necessary for the font registry functionality used throughout this file.


100-158: LGTM!

The font initialization logic is well-structured with proper defensive fallbacks:

  • Registers and sets the font family with appropriate checks
  • Handles unsupported font weights by falling back to supported alternatives (lightest for normal, second lightest for bold)
  • Applies all font changes via updateFonts() after configuration

553-560: LGTM!

The FontWeightNormal data reading correctly retrieves the weight index with proper fallback to the default weight when the current weight isn't in the supported list.


561-568: LGTM!

The font weight data access logic (both reading and writing) correctly handles the conversion chain between UI indices, QFont::Weight values, and persistent storage format.

Also applies to: 805-817

src/qt/guiutil_font.h (6)

1-17: LGTM!

The header structure is correct with proper includes and header guards. The necessary <map> header is present.


18-32: LGTM!

The namespace constants, FontWeight enum, and FontAttrib struct are well-defined with appropriate defaults.


34-49: LGTM!

The FontInfo struct is well-designed with explicit construction requirements and appropriate encapsulation of weight calculation methods.


51-122: LGTM!

The FontRegistry class API is well-designed with:

  • Platform-specific constants for macOS font weight handling
  • Consistent setter/getter interface
  • Defensive fallbacks in getters while maintaining fail-fast assertions in setters (per established pattern)
  • Proper encapsulation of font state

Based on learnings, the intentional use of assert() in setters enforces invariants during development.


124-159: LGTM!

The external declarations and free function APIs provide a complete and coherent font management interface.


1-161: Ensure code conforms to clang-format standards.

Run the provided command to verify and apply formatting rules to this file.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
src/qt/guiutil_font.cpp (2)

110-115: Consider documenting the qstrprintf helper.

The qstrprintf template function is a useful utility that converts tinyformat output to QString. Consider adding a brief comment explaining its purpose for future maintainers.


521-522: Assertion assumes index fits in uint64_t range.

The assertion assert(vecWeights.size() > uint64_t(index)) assumes the weight vector size can be safely compared with a uint64_t cast of the index parameter (which is int). While practically safe, consider whether size_t would be more semantically correct for the index type throughout the codebase (though as noted in past comments, this may be out of scope for this PR).

Based on learnings, formatting and type consistency improvements are typically deferred in refactoring PRs.

📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 14137c6 and 6d2c2d9.

📒 Files selected for processing (36)
  • src/Makefile.qt.include
  • src/qt/addressbookpage.cpp
  • src/qt/addresstablemodel.cpp
  • src/qt/appearancewidget.cpp
  • src/qt/appearancewidget.h
  • src/qt/askpassphrasedialog.cpp
  • src/qt/bitcoin.cpp
  • src/qt/bitcoingui.cpp
  • src/qt/coincontroldialog.cpp
  • src/qt/governancelist.cpp
  • src/qt/guiutil.cpp
  • src/qt/guiutil.h
  • src/qt/guiutil_font.cpp
  • src/qt/guiutil_font.h
  • src/qt/masternodelist.cpp
  • src/qt/modaloverlay.cpp
  • src/qt/openuridialog.cpp
  • src/qt/optionsdialog.cpp
  • src/qt/optionsmodel.cpp
  • src/qt/overviewpage.cpp
  • src/qt/proposalwizard.cpp
  • src/qt/qrdialog.cpp
  • src/qt/qrimagewidget.cpp
  • src/qt/receivecoinsdialog.cpp
  • src/qt/receiverequestdialog.cpp
  • src/qt/rpcconsole.cpp
  • src/qt/sendcoinsdialog.cpp
  • src/qt/sendcoinsentry.cpp
  • src/qt/signverifymessagedialog.cpp
  • src/qt/splashscreen.cpp
  • src/qt/test/apptests.cpp
  • src/qt/trafficgraphwidget.cpp
  • src/qt/transactiondescdialog.cpp
  • src/qt/utilitydialog.cpp
  • src/qt/walletview.cpp
  • test/util/data/non-backported.txt
💤 Files with no reviewable changes (1)
  • src/qt/guiutil.h
🚧 Files skipped from review as they are similar to previous changes (22)
  • src/qt/addressbookpage.cpp
  • src/qt/receiverequestdialog.cpp
  • src/qt/test/apptests.cpp
  • src/qt/modaloverlay.cpp
  • src/qt/addresstablemodel.cpp
  • src/qt/splashscreen.cpp
  • src/qt/bitcoingui.cpp
  • src/qt/trafficgraphwidget.cpp
  • src/qt/sendcoinsentry.cpp
  • src/qt/rpcconsole.cpp
  • src/qt/proposalwizard.cpp
  • src/qt/appearancewidget.h
  • src/qt/transactiondescdialog.cpp
  • src/qt/overviewpage.cpp
  • src/qt/qrimagewidget.cpp
  • src/Makefile.qt.include
  • src/qt/utilitydialog.cpp
  • src/qt/sendcoinsdialog.cpp
  • src/qt/openuridialog.cpp
  • src/qt/governancelist.cpp
  • src/qt/walletview.cpp
  • test/util/data/non-backported.txt
🧰 Additional context used
📓 Path-based instructions (2)
src/**/*.{cpp,h,hpp,cc}

📄 CodeRabbit inference engine (CLAUDE.md)

Dash Core implementation must be written in C++20, requiring at least Clang 16 or GCC 11.1

Files:

  • src/qt/coincontroldialog.cpp
  • src/qt/optionsmodel.cpp
  • src/qt/appearancewidget.cpp
  • src/qt/receivecoinsdialog.cpp
  • src/qt/bitcoin.cpp
  • src/qt/askpassphrasedialog.cpp
  • src/qt/guiutil_font.cpp
  • src/qt/optionsdialog.cpp
  • src/qt/masternodelist.cpp
  • src/qt/signverifymessagedialog.cpp
  • src/qt/guiutil_font.h
  • src/qt/guiutil.cpp
  • src/qt/qrdialog.cpp
src/qt/**/*.{cpp,h}

📄 CodeRabbit inference engine (CLAUDE.md)

GUI implementation in src/qt/ must use Qt 5

Files:

  • src/qt/coincontroldialog.cpp
  • src/qt/optionsmodel.cpp
  • src/qt/appearancewidget.cpp
  • src/qt/receivecoinsdialog.cpp
  • src/qt/bitcoin.cpp
  • src/qt/askpassphrasedialog.cpp
  • src/qt/guiutil_font.cpp
  • src/qt/optionsdialog.cpp
  • src/qt/masternodelist.cpp
  • src/qt/signverifymessagedialog.cpp
  • src/qt/guiutil_font.h
  • src/qt/guiutil.cpp
  • src/qt/qrdialog.cpp
🧠 Learnings (26)
📓 Common learnings
Learnt from: kwvg
Repo: dashpay/dash PR: 7068
File: src/qt/guiutil_font.h:68-77
Timestamp: 2025-12-22T15:42:48.595Z
Learning: In the Dash Core Qt codebase (src/qt/guiutil_font.h), kwvg intentionally uses `assert()` in setter methods like `SetWeightBold` and `SetWeightNormal` to enforce invariants (e.g., `assert(m_weights.count(m_font))`). This fail-fast approach is preferred over defensive checks with fallbacks when an inconsistent state indicates a programming error that should be caught during development, rather than a runtime condition requiring graceful handling.
Learnt from: kwvg
Repo: dashpay/dash PR: 6761
File: src/chainlock/signing.cpp:15-250
Timestamp: 2025-07-23T09:28:32.783Z
Learning: In refactoring PRs like #6761, kwvg prefers to defer code formatting fixes to separate follow-up PRs when formatting is not the primary objective, to maintain focus on the structural changes and avoid scope creep.
Learnt from: kwvg
Repo: dashpay/dash PR: 6718
File: test/functional/test_framework/test_framework.py:2102-2102
Timestamp: 2025-06-09T16:43:20.996Z
Learning: In the test framework consolidation PR (#6718), user kwvg prefers to limit functional changes to those directly related to MasternodeInfo, avoiding scope creep even for minor improvements like error handling consistency.
Learnt from: PastaPastaPasta
Repo: dashpay/dash PR: 6804
File: src/qt/proposalwizard.cpp:40-42
Timestamp: 2025-08-11T17:16:36.654Z
Learning: In the Dash repository, when a PR adds new files that are not from Bitcoin backports, these files must be added to the list in test/util/data/non-backported.txt. This applies to newly created files like qt/proposalwizard.{h,cpp} and forms/proposalwizard.ui. Limited exemptions may exist for subtrees and similar cases.
📚 Learning: 2025-12-22T15:42:48.595Z
Learnt from: kwvg
Repo: dashpay/dash PR: 7068
File: src/qt/guiutil_font.h:68-77
Timestamp: 2025-12-22T15:42:48.595Z
Learning: In the Dash Core Qt codebase (src/qt/guiutil_font.h), kwvg intentionally uses `assert()` in setter methods like `SetWeightBold` and `SetWeightNormal` to enforce invariants (e.g., `assert(m_weights.count(m_font))`). This fail-fast approach is preferred over defensive checks with fallbacks when an inconsistent state indicates a programming error that should be caught during development, rather than a runtime condition requiring graceful handling.

Applied to files:

  • src/qt/coincontroldialog.cpp
  • src/qt/optionsmodel.cpp
  • src/qt/appearancewidget.cpp
  • src/qt/receivecoinsdialog.cpp
  • src/qt/bitcoin.cpp
  • src/qt/askpassphrasedialog.cpp
  • src/qt/guiutil_font.cpp
  • src/qt/optionsdialog.cpp
  • src/qt/masternodelist.cpp
  • src/qt/signverifymessagedialog.cpp
  • src/qt/guiutil.cpp
  • src/qt/qrdialog.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/qt/**/*.{cpp,h} : GUI implementation in src/qt/ must use Qt 5

Applied to files:

  • src/qt/coincontroldialog.cpp
  • src/qt/optionsmodel.cpp
  • src/qt/appearancewidget.cpp
  • src/qt/receivecoinsdialog.cpp
  • src/qt/bitcoin.cpp
  • src/qt/askpassphrasedialog.cpp
  • src/qt/guiutil_font.cpp
  • src/qt/optionsdialog.cpp
  • src/qt/masternodelist.cpp
  • src/qt/signverifymessagedialog.cpp
  • src/qt/guiutil_font.h
  • src/qt/guiutil.cpp
  • src/qt/qrdialog.cpp
📚 Learning: 2025-12-17T13:58:19.813Z
Learnt from: kwvg
Repo: dashpay/dash PR: 7072
File: src/qt/walletcontroller.cpp:520-528
Timestamp: 2025-12-17T13:58:19.813Z
Learning: In Dash Qt wallet code, prefer using existing Qt signals/slots (e.g., ShowProgress signals) for long-running operations instead of adding explicit QProgressDialog dialogs. This minimizes upstream deviations and simplifies backports. Apply this pattern to wallet-related Qt components (e.g., operations like rescanning) and rely on signal-based progress updates rather than bespoke dialogs.

Applied to files:

  • src/qt/coincontroldialog.cpp
  • src/qt/optionsmodel.cpp
  • src/qt/appearancewidget.cpp
  • src/qt/receivecoinsdialog.cpp
  • src/qt/bitcoin.cpp
  • src/qt/askpassphrasedialog.cpp
  • src/qt/guiutil_font.cpp
  • src/qt/optionsdialog.cpp
  • src/qt/masternodelist.cpp
  • src/qt/signverifymessagedialog.cpp
  • src/qt/guiutil.cpp
  • src/qt/qrdialog.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/wallet/**/*.{cpp,h} : Wallet implementation must use Berkeley DB and SQLite

Applied to files:

  • src/qt/coincontroldialog.cpp
  • src/qt/askpassphrasedialog.cpp
📚 Learning: 2025-07-23T09:28:32.783Z
Learnt from: kwvg
Repo: dashpay/dash PR: 6761
File: src/chainlock/signing.cpp:15-250
Timestamp: 2025-07-23T09:28:32.783Z
Learning: In refactoring PRs like #6761, kwvg prefers to defer code formatting fixes to separate follow-up PRs when formatting is not the primary objective, to maintain focus on the structural changes and avoid scope creep.

Applied to files:

  • src/qt/guiutil_font.cpp
  • src/qt/guiutil_font.h
📚 Learning: 2025-02-06T14:34:30.466Z
Learnt from: kwvg
Repo: dashpay/dash PR: 6543
File: src/wallet/receive.cpp:240-251
Timestamp: 2025-02-06T14:34:30.466Z
Learning: Pull request #6543 is focused on move-only changes and refactoring, specifically backporting from Bitcoin. Behavior changes should be proposed in separate PRs.

Applied to files:

  • src/qt/guiutil_font.cpp
📚 Learning: 2025-02-14T15:15:58.165Z
Learnt from: kwvg
Repo: dashpay/dash PR: 6529
File: src/rpc/governance.cpp:1074-1089
Timestamp: 2025-02-14T15:15:58.165Z
Learning: Code blocks marked with `// clang-format off` and `// clang-format on` directives should be excluded from clang-format suggestions as they are intentionally formatted manually for better readability.

Applied to files:

  • src/qt/guiutil_font.cpp
📚 Learning: 2025-08-19T14:57:31.801Z
Learnt from: knst
Repo: dashpay/dash PR: 6692
File: src/llmq/blockprocessor.cpp:217-224
Timestamp: 2025-08-19T14:57:31.801Z
Learning: In PR #6692, knst acknowledged a null pointer dereference issue in ProcessBlock() method where LookupBlockIndex may return nullptr but is passed to gsl::not_null, and created follow-up PR #6789 to address it, consistent with avoiding scope creep in performance-focused PRs.

Applied to files:

  • src/qt/guiutil_font.cpp
📚 Learning: 2025-07-09T15:05:36.250Z
Learnt from: kwvg
Repo: dashpay/dash PR: 6729
File: src/rpc/evo.cpp:1273-1273
Timestamp: 2025-07-09T15:05:36.250Z
Learning: When clang-format suggestions significantly harm readability (like splitting logical parameter groups across multiple lines), it's acceptable to use `// clang-format off` and `// clang-format on` directives to exclude the problematic section from automatic formatting, prioritizing code readability over strict line length compliance.

Applied to files:

  • src/qt/guiutil_font.cpp
📚 Learning: 2025-07-29T14:33:01.040Z
Learnt from: kwvg
Repo: dashpay/dash PR: 6761
File: src/wallet/wallet.cpp:0-0
Timestamp: 2025-07-29T14:33:01.040Z
Learning: In refactoring PRs like #6761, kwvg acknowledges code safety improvements (like null pointer checks and unused parameter warnings) but prefers to defer them to follow-up PRs to maintain focus on the primary refactoring objectives, avoiding scope creep.

Applied to files:

  • src/qt/guiutil_font.cpp
  • src/qt/guiutil_font.h
📚 Learning: 2025-07-29T14:32:48.369Z
Learnt from: kwvg
Repo: dashpay/dash PR: 6761
File: src/chainlock/signing.cpp:247-250
Timestamp: 2025-07-29T14:32:48.369Z
Learning: In PR #6761, kwvg acknowledged a null pointer check issue in ChainLockSigner::Cleanup() method but deferred it to follow-up, consistent with the pattern of avoiding scope creep in refactoring PRs.

Applied to files:

  • src/qt/guiutil_font.cpp
  • src/qt/guiutil_font.h
📚 Learning: 2025-10-13T12:37:12.357Z
Learnt from: knst
Repo: dashpay/dash PR: 6883
File: src/rpc/rawtransaction.cpp:1088-1125
Timestamp: 2025-10-13T12:37:12.357Z
Learning: In backport pull requests (especially from Bitcoin Core), treat "moved" or refactored code as out-of-scope for content-level review. Focus validation on verifying that code is moved correctly: no fields added, no fields removed, no fields reordered, and no unexpected changes beyond whitespace adjustments. Pre-existing issues in the upstream code should be preserved to maintain fidelity to the original implementation.

Applied to files:

  • src/qt/guiutil_font.cpp
📚 Learning: 2025-11-04T18:24:27.241Z
Learnt from: UdjinM6
Repo: dashpay/dash PR: 6933
File: src/llmq/utils.cpp:284-298
Timestamp: 2025-11-04T18:24:27.241Z
Learning: In consensus-critical code (such as quorum formation, block validation, or deployment activation logic), do not suggest changes to the logic itself even if the implementation appears theoretically incorrect or off-by-one. Consensus rules, once deployed on the Dash network, must be preserved exactly to avoid network forks. Refactoring PRs should maintain perfect behavioral equivalence. Only suggest logic changes if explicitly accompanied by a DIP (Dash Improvement Proposal) or if the maintainer indicates the consensus rule needs to be changed with appropriate activation logic.

Applied to files:

  • src/qt/guiutil_font.cpp
  • src/qt/guiutil_font.h
📚 Learning: 2025-06-09T16:43:20.996Z
Learnt from: kwvg
Repo: dashpay/dash PR: 6718
File: test/functional/test_framework/test_framework.py:2102-2102
Timestamp: 2025-06-09T16:43:20.996Z
Learning: In the test framework consolidation PR (#6718), user kwvg prefers to limit functional changes to those directly related to MasternodeInfo, avoiding scope creep even for minor improvements like error handling consistency.

Applied to files:

  • src/qt/guiutil_font.cpp
  • src/qt/guiutil_font.h
📚 Learning: 2025-10-25T07:08:51.918Z
Learnt from: knst
Repo: dashpay/dash PR: 6916
File: src/univalue/include/univalue.h:81-88
Timestamp: 2025-10-25T07:08:51.918Z
Learning: For backport PRs from bitcoin/bitcoin, bitcoin-core/gui, etc., backported changes should match the original upstream PRs even if they appear strange, modify vendored code, or seem to violate coding guidelines. Still flag genuine issues like bugs, undefined behavior, crashes, compilation errors, or linter failures.

Applied to files:

  • src/qt/guiutil_font.cpp
📚 Learning: 2025-10-05T20:38:28.457Z
Learnt from: knst
Repo: dashpay/dash PR: 6871
File: contrib/guix/libexec/build.sh:358-360
Timestamp: 2025-10-05T20:38:28.457Z
Learning: In the Dash repository, when backporting code from Bitcoin Core, typos and minor issues in comments should be kept as-is to reduce merge conflicts in future backports, even if they remain unfixed in Bitcoin Core's master branch.

Applied to files:

  • src/qt/guiutil_font.cpp
  • src/qt/guiutil_font.h
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/coinjoin/**/*.{cpp,h} : CoinJoin implementation must use masternode-coordinated mixing sessions with uniform denomination outputs

Applied to files:

  • src/qt/optionsdialog.cpp
  • src/qt/masternodelist.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/evo/evodb/**/*.{cpp,h} : Evolution Database (CEvoDb) must handle masternode snapshots, quorum state, governance objects with efficient differential updates for masternode lists

Applied to files:

  • src/qt/masternodelist.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/{masternode,evo,llmq,governance,coinjoin}/**/*.{cpp,h} : Use Dash-specific database implementations: CFlatDB for persistent storage (MasternodeMetaStore, GovernanceStore, SporkStore, NetFulfilledRequestStore) and CDBWrapper extensions for Evolution/DKG/InstantSend/Quorum/RecoveredSigs data

Applied to files:

  • src/qt/masternodelist.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/{masternode,llmq}/**/*.{cpp,h} : BLS integration must be used for cryptographic foundation of advanced masternode features

Applied to files:

  • src/qt/masternodelist.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/{masternode,evo}/**/*.{cpp,h} : Masternode lists must use immutable data structures (Immer library) for thread safety

Applied to files:

  • src/qt/masternodelist.cpp
📚 Learning: 2025-12-22T15:42:48.595Z
Learnt from: kwvg
Repo: dashpay/dash PR: 7068
File: src/qt/guiutil_font.h:68-77
Timestamp: 2025-12-22T15:42:48.595Z
Learning: In C++/Qt codebases, use fail-fast asserts in setters to enforce invariants (e.g., ensuring internal maps contain necessary keys). Prefer assert() for programmer errors that should be caught in development and debugging, rather than defensive runtime checks with fallbacks. This helps catch invariant violations early during development. Apply to header and source files where invariant-driven state mutations occur, especially in setters like SetWeightBold/SetWeightNormal that assume established relationships or preconditions.

Applied to files:

  • src/qt/guiutil_font.h
📚 Learning: 2025-07-17T15:48:29.418Z
Learnt from: kwvg
Repo: dashpay/dash PR: 6752
File: src/wallet/load.cpp:164-164
Timestamp: 2025-07-17T15:48:29.418Z
Learning: In Dash Core, kwvg prefers using assert() statements to document expected behavior in code paths, especially when the called function also has internal asserts. This is used as a defensive programming pattern rather than requiring conditional error handling.

Applied to files:

  • src/qt/guiutil_font.h
📚 Learning: 2025-12-17T13:58:26.891Z
Learnt from: kwvg
Repo: dashpay/dash PR: 7072
File: src/qt/walletcontroller.cpp:520-528
Timestamp: 2025-12-17T13:58:26.891Z
Learning: In Dash Qt wallet code, when leveraging upstream Bitcoin Core wallet capabilities (especially for operations like rescanning), prefer using the inherited signal-based mechanisms (e.g., ShowProgress signals) over adding explicit Qt progress dialogs to minimize upstream deviation and simplify future backports.

Applied to files:

  • src/qt/guiutil_font.h
📚 Learning: 2025-08-11T17:16:36.654Z
Learnt from: PastaPastaPasta
Repo: dashpay/dash PR: 6804
File: src/qt/proposalwizard.cpp:40-42
Timestamp: 2025-08-11T17:16:36.654Z
Learning: In the Dash repository, when a PR adds new files that are not from Bitcoin backports, these files must be added to the list in test/util/data/non-backported.txt. This applies to newly created files like qt/proposalwizard.{h,cpp} and forms/proposalwizard.ui. Limited exemptions may exist for subtrees and similar cases.

Applied to files:

  • src/qt/guiutil_font.h
🧬 Code graph analysis (11)
src/qt/optionsmodel.cpp (1)
src/qt/guiutil_font.cpp (10)
  • fontsLoaded (300-303)
  • fontsLoaded (300-300)
  • setApplicationFont (305-338)
  • setApplicationFont (305-305)
  • weightToArg (178-182)
  • weightToArg (178-178)
  • weightFromArg (168-176)
  • weightFromArg (168-168)
  • updateFonts (350-445)
  • updateFonts (350-350)
src/qt/appearancewidget.cpp (1)
src/qt/guiutil_font.cpp (4)
  • setApplicationFont (305-338)
  • setApplicationFont (305-305)
  • updateFonts (350-445)
  • updateFonts (350-350)
src/qt/receivecoinsdialog.cpp (1)
src/qt/guiutil_font.cpp (2)
  • setFont (340-348)
  • setFont (340-340)
src/qt/bitcoin.cpp (1)
src/qt/guiutil_font.cpp (8)
  • weightToArg (178-182)
  • weightToArg (178-178)
  • weightFromArg (168-176)
  • weightFromArg (168-168)
  • updateFonts (350-445)
  • updateFonts (350-350)
  • setApplicationFont (305-338)
  • setApplicationFont (305-305)
src/qt/askpassphrasedialog.cpp (1)
src/qt/guiutil_font.cpp (2)
  • setFont (340-348)
  • setFont (340-340)
src/qt/guiutil_font.cpp (1)
src/qt/guiutil.cpp (2)
  • TextWidth (1284-1287)
  • TextWidth (1284-1284)
src/qt/optionsdialog.cpp (1)
src/qt/guiutil_font.cpp (2)
  • setFont (340-348)
  • setFont (340-340)
src/qt/signverifymessagedialog.cpp (1)
src/qt/guiutil_font.cpp (2)
  • setFont (340-348)
  • setFont (340-340)
src/qt/guiutil_font.h (1)
src/qt/guiutil_font.cpp (34)
  • FontInfo (127-133)
  • FontInfo (135-135)
  • GetBestMatch (210-224)
  • GetBestMatch (210-210)
  • RegisterFont (137-157)
  • RegisterFont (137-137)
  • WeightToIdx (525-534)
  • WeightToIdx (525-525)
  • IdxToWeight (518-523)
  • IdxToWeight (518-518)
  • SetFont (159-166)
  • SetFont (159-159)
  • weightFromArg (168-176)
  • weightFromArg (168-168)
  • weightToArg (178-182)
  • weightToArg (178-178)
  • loadFonts (241-298)
  • loadFonts (241-241)
  • fontsLoaded (300-303)
  • fontsLoaded (300-300)
  • setApplicationFont (305-338)
  • setApplicationFont (305-305)
  • setFont (340-348)
  • setFont (340-340)
  • updateFonts (350-445)
  • updateFonts (350-350)
  • getFont (447-501)
  • getFont (447-447)
  • getFont (503-506)
  • getFont (503-503)
  • getFontNormal (508-511)
  • getFontNormal (508-508)
  • getFontBold (513-516)
  • getFontBold (513-513)
src/qt/guiutil.cpp (1)
src/qt/guiutil_font.cpp (2)
  • setFont (340-348)
  • setFont (340-340)
src/qt/qrdialog.cpp (1)
src/qt/guiutil_font.cpp (2)
  • setFont (340-348)
  • setFont (340-340)
🪛 Cppcheck (2.19.0)
src/qt/appearancewidget.cpp

[error] 24-24: #error No known always_inline attribute for this platform.

(preprocessorErrorDirective)

src/qt/guiutil_font.cpp

[error] 454-454: failed to evaluate #if condition, undefined function-like macro invocation

(syntaxError)


[error] 22-22: failed to evaluate #if condition, undefined function-like macro invocation

(syntaxError)


[error] 24-24: #error No known always_inline attribute for this platform.

(preprocessorErrorDirective)

src/qt/masternodelist.cpp

[error] 10-10: failed to evaluate #if condition, undefined function-like macro invocation

(syntaxError)

src/qt/qrdialog.cpp

[error] 24-24: #error No known always_inline attribute for this platform.

(preprocessorErrorDirective)

🪛 GitHub Actions: Clang Diff Format Check
src/qt/guiutil_font.cpp

[error] 1-1: Clang format differences found. Diff between before/after formatting detected by clang-format-diff.py.

src/qt/masternodelist.cpp

[error] 1-1: Clang format differences found. Diff between before/after formatting detected by clang-format-diff.py.

src/qt/guiutil_font.h

[error] 1-1: Clang format differences found. Diff between before/after formatting detected by clang-format-diff.py.

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (9)
  • GitHub Check: linux64_nowallet-build / Build source
  • GitHub Check: win64-build / Build source
  • GitHub Check: linux64_ubsan-build / Build source
  • GitHub Check: linux64_fuzz-build / Build source
  • GitHub Check: linux64-build / Build source
  • GitHub Check: linux64_sqlite-build / Build source
  • GitHub Check: arm-linux-build / Build source
  • GitHub Check: mac-build / Build source
  • GitHub Check: linux64_tsan-build / Build source
🔇 Additional comments (25)
src/qt/guiutil.cpp (1)

300-301: LGTM! Font calls correctly migrated to FontRegistry API.

The font setting calls have been properly updated to use the new FontAttrib struct syntax with registry-based weights. The italic flag on line 301 correctly uses the third parameter.

src/qt/askpassphrasedialog.cpp (1)

15-15: LGTM! Consistent font registry migration.

The include and font-setting call properly use the new FontRegistry API.

Also applies to: 34-34

src/qt/optionsdialog.cpp (1)

17-17: LGTM! Proper FontRegistry integration.

All font-setting calls correctly use the registry-based weights with the FontAttrib struct syntax.

Also applies to: 53-53, 400-401

src/qt/bitcoin.cpp (2)

664-677: LGTM! Robust font loading with proper error handling.

The font loading logic properly handles failures:

  • Fatal error with clear message if loadFonts() fails
  • Font registration and setting are both validated
  • User-friendly error message displays the problematic font name

This addresses the past review concern about crashes with invalid fonts.


678-711: LGTM! Complete font configuration with validation.

All font parameters (weight-normal, weight-bold, font-scale) are properly validated with:

  • Clear error messages showing valid ranges
  • Registry-based setters
  • Final font application via updateFonts() and setApplicationFont()
src/qt/qrdialog.cpp (1)

11-11: LGTM! Standard font registry migration.

The include and font-setting call are consistent with the FontRegistry pattern used throughout the PR.

Also applies to: 24-24

src/qt/coincontroldialog.cpp (1)

16-16: LGTM! Consistent FontRegistry usage.

The font-setting call properly uses g_font_registry.GetWeightBold() with the FontAttrib struct.

Also applies to: 61-61

src/qt/receivecoinsdialog.cpp (1)

10-10: LGTM! Proper FontRegistry integration.

Both font-setting calls correctly use registry-based weights with appropriate sizes and widget lists.

Also applies to: 26-29

src/qt/masternodelist.cpp (2)

45-46: Font weight migration looks good.

The transition from GUIUtil::FontWeight::Bold/Normal to GUIUtil::g_font_registry.GetWeightBold()/GetWeightNormal() correctly adopts the new registry-based font management pattern.


8-8: No action required for coins.h include.

The #include <coins.h> is necessary—the Coin type is used in the file (line 182).

Likely an incorrect or invalid review comment.

src/qt/signverifymessagedialog.cpp (1)

11-11: LGTM! Registry-based font weights correctly applied.

The include addition and migration of font weight access to GUIUtil::g_font_registry.GetWeightNormal()/GetWeightBold() is consistent with the refactoring pattern across the codebase.

Also applies to: 57-59, 115-116

src/qt/appearancewidget.cpp (3)

23-28: Good state preservation pattern.

The constructor correctly captures the initial font registry state (theme, scale, font family, and both weight values) for potential restoration in the destructor. This ensures preview changes can be rolled back if not accepted.


64-80: Proper state restoration on reject.

The destructor correctly restores all font-related settings to their previous values when !fAcceptChanges, ensuring preview changes are rolled back. The sequence of restoring font, scale, and weights followed by updateFonts() is appropriate.


165-165: Verify fallback condition logic.

The condition checks !IsValidWeight(prevWeightNormal) || !IsValidWeight(prevWeightBold) to decide whether to reset to defaults. Ensure this correctly handles edge cases where only one of the two weights is invalid, since the code resets both to defaults even if only one is invalid.

src/qt/optionsmodel.cpp (5)

126-131: Solid fallback logic for unsupported normal weights.

The code correctly validates whether the configured normal weight is supported by the current font. If not, it falls back to the lightest supported weight (GetSupportedWeights().front()), ensuring a valid weight is always set. This prevents crashes from assertion failures mentioned in the PR description.


143-150: Good fallback for bold weights with preference for heavier weight.

The bold weight fallback uses the second lightest weight when available, or falls back to the lightest if only one weight is supported. This maintains a visual distinction between normal and bold when possible.


156-158: Explicit font update application is necessary.

Calling GUIUtil::updateFonts() after all font settings are initialized ensures the registry state is propagated to all widgets. This is the correct pattern for applying font configuration changes.


554-559: Handle invalid weight index gracefully.

The code returns a fallback default index when WeightToIdx() returns -1. However, the subsequent assert(nIndex != -1) will still trigger if both the configured weight and the default weight are invalid. Consider whether the assertion is appropriate here or if additional defensive logic is needed.

Based on learnings, assertions are intentional for enforcing invariants during development.


103-105: The font registry is designed to handle failures gracefully. RegisterFont() returns false if a font doesn't exist, and SetFont() checks the precondition before modifying state. The code uses short-circuit evaluation—if either call fails, setApplicationFont() is never invoked, allowing the application to continue with its previous font. No inconsistent state is possible.

Likely an incorrect or invalid review comment.

src/qt/guiutil_font.cpp (6)

186-204: Clever weight detection via text width measurement.

The CalcSupportedWeights method uses an innovative approach: rendering test text at different weights and measuring width differences to determine which weights the font actually supports. This is more robust than relying on font metadata alone.


232-238: Smart differentiation between normal and bold defaults.

When the best matches for normal and bold target weights are identical, the code automatically selects the next heavier weight for bold. This ensures visual distinction between the two font weights even when exact matches aren't available.


315-325: Platform-specific font handling is appropriate.

The macOS-specific logic for Montserrat font application (using getFontNormal() when weight differs from target, or setting weight directly) correctly handles platform differences in font naming and weight handling.


363-382: Proper cleanup of invalid widget references.

The code correctly uses QPointer::isNull() to detect deleted widgets and removes their entries from both mapWidgetDefaultFontSizes and mapFontUpdates. This prevents memory leaks and stale references.


454-475: Platform-dependent Montserrat font construction.

The code handles platform differences in Montserrat font application:

  • macOS: Uses setStyleName() with variant names (e.g., "Bold Italic")
  • Other platforms: Uses family name concatenation for non-Normal/Bold weights

This approach accommodates Qt's platform-specific font handling behavior. Ensure this has been tested on both macOS and Linux/Windows platforms.


263-267: Verify font loading failure handling in test code.

The main application code in bitcoin.cpp:664-667 properly handles loadFonts() failure by checking the return value and displaying a critical error before exiting. However, the test code in apptests.cpp:82 calls loadFonts() without checking its return value. Verify that test code either handles the failure case or explicitly documents why it's safe to proceed without checking.

@kwvg kwvg requested a review from UdjinM6 December 23, 2025 22:31
kwvg and others added 21 commits December 29, 2025 12:02
The current enum-based approach is rigid and doesn't bode well for
extensibility, we need to distance key functions from relying on
`FontFamily` before we can get rid of it outright.
mapping:

getFontFamily() -> g_font_registry.GetFont()
getFontWeightBold() -> g_font_registry.GetWeightBold()
getFontWeightBoldDefault() -> FontRegistry::TARGET_WEIGHT_BOLD
getFontWeightNormal() -> g_font_registry.GetWeightNormal()
getFontWeightNormalDefault() -> FontRegistry::TARGET_WEIGHT_NORMAL
getFontScale() -> g_font_registry.GetFontScale()
getScaledFontSize() -> g_font_registry.GetScaledFontSize()
getSupportedFontWeightBoldDefault() -> g_font_registry.GetWeightBoldDefault()
getSupportedFontWeightNormalDefault() -> g_font_registry.GetWeightNormalDefault()
getSupportedWeights() -> g_font_registry.GetSupportedWeights()
This commit is intentionally suboptimal as it faithfully replaces the
functions with what was called internally, we will remove avoidable
calls later.
Also get rid of `g_font_registry_default` and just constexpr the
defaults. Easier and less fragile.
We don't need these many, especially if we're updating the font registry
in rapid succession
They got lost in refactoring and are causing test failures on CI, bring
them back.
This is to prevent potential inconsistency or glitching
Update weight sliders to show actual runtime weights when font-family is
CLI-overridden but weights are not, instead of showing stale QSettings
values.

Co-authored-by: UdjinM6 <[email protected]>
Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
When `-font-family` is specified without explicit weight arguments,
use the font's default weights instead of QSettings weights which may
be from a different font, preventing the validation code in bitcoin.cpp
from overwriting font-specific defaults.

Co-authored-by: UdjinM6 <[email protected]>
Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
Add setApplicationFont() calls in weight update handlers to ensure
qApp->font() reflects the new weight, particularly important for
Montserrat on macOS where style names must be updated.

Don't call updateFonts() during OptionsModel::Init() as no widgets exist
yet at that point.

Co-authored-by: UdjinM6 <[email protected]>
Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
setWeight() doesn't work for this font.

Co-authored-by: UdjinM6 <[email protected]>
Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
src/qt/masternodelist.cpp (1)

1-100: Fix reported clang‑format diff on this file

CI flags src/qt/masternodelist.cpp for formatting differences. Please run your usual clang‑format workflow (e.g. clang-format-diff.py -p1) to align this file with the project style.

src/qt/appearancewidget.cpp (1)

59-83: Destructor rollback logic correctly restores theme and font registry state

If fAcceptChanges is false, the destructor:

  • Restores the previous theme via updateTheme(prevTheme).
  • Restores font family, scale, and weights in g_font_registry and reapplies them via setApplicationFont() and updateFonts().

This cleanly undoes any live changes made while the widget was open without touching persistent settings (since the mapper uses ManualSubmit).

You may optionally drop the first GUIUtil::setApplicationFont(); inside the prevFontFamily branch and rely on the final setApplicationFont() call to avoid calling it twice in the rollback path.

📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 19344a0 and db3d1b8.

📒 Files selected for processing (26)
  • src/qt/appearancewidget.cpp
  • src/qt/appearancewidget.h
  • src/qt/askpassphrasedialog.cpp
  • src/qt/bitcoin.cpp
  • src/qt/bitcoingui.cpp
  • src/qt/coincontroldialog.cpp
  • src/qt/governancelist.cpp
  • src/qt/guiutil.cpp
  • src/qt/guiutil_font.cpp
  • src/qt/guiutil_font.h
  • src/qt/masternodelist.cpp
  • src/qt/modaloverlay.cpp
  • src/qt/optionsdialog.cpp
  • src/qt/optionsmodel.cpp
  • src/qt/optionsmodel.h
  • src/qt/overviewpage.cpp
  • src/qt/proposalwizard.cpp
  • src/qt/qrdialog.cpp
  • src/qt/receivecoinsdialog.cpp
  • src/qt/rpcconsole.cpp
  • src/qt/sendcoinsdialog.cpp
  • src/qt/sendcoinsentry.cpp
  • src/qt/signverifymessagedialog.cpp
  • src/qt/test/apptests.cpp
  • src/qt/trafficgraphwidget.cpp
  • src/qt/walletview.cpp
✅ Files skipped from review due to trivial changes (1)
  • src/qt/optionsdialog.cpp
🚧 Files skipped from review as they are similar to previous changes (11)
  • src/qt/governancelist.cpp
  • src/qt/sendcoinsdialog.cpp
  • src/qt/appearancewidget.h
  • src/qt/rpcconsole.cpp
  • src/qt/sendcoinsentry.cpp
  • src/qt/modaloverlay.cpp
  • src/qt/receivecoinsdialog.cpp
  • src/qt/overviewpage.cpp
  • src/qt/trafficgraphwidget.cpp
  • src/qt/askpassphrasedialog.cpp
  • src/qt/walletview.cpp
🧰 Additional context used
📓 Path-based instructions (2)
src/**/*.{cpp,h,hpp,cc}

📄 CodeRabbit inference engine (CLAUDE.md)

Dash Core implementation must be written in C++20, requiring at least Clang 16 or GCC 11.1

Files:

  • src/qt/coincontroldialog.cpp
  • src/qt/optionsmodel.h
  • src/qt/proposalwizard.cpp
  • src/qt/bitcoingui.cpp
  • src/qt/optionsmodel.cpp
  • src/qt/bitcoin.cpp
  • src/qt/signverifymessagedialog.cpp
  • src/qt/test/apptests.cpp
  • src/qt/guiutil_font.h
  • src/qt/guiutil.cpp
  • src/qt/appearancewidget.cpp
  • src/qt/guiutil_font.cpp
  • src/qt/masternodelist.cpp
  • src/qt/qrdialog.cpp
src/qt/**/*.{cpp,h}

📄 CodeRabbit inference engine (CLAUDE.md)

GUI implementation in src/qt/ must use Qt 5

Files:

  • src/qt/coincontroldialog.cpp
  • src/qt/optionsmodel.h
  • src/qt/proposalwizard.cpp
  • src/qt/bitcoingui.cpp
  • src/qt/optionsmodel.cpp
  • src/qt/bitcoin.cpp
  • src/qt/signverifymessagedialog.cpp
  • src/qt/test/apptests.cpp
  • src/qt/guiutil_font.h
  • src/qt/guiutil.cpp
  • src/qt/appearancewidget.cpp
  • src/qt/guiutil_font.cpp
  • src/qt/masternodelist.cpp
  • src/qt/qrdialog.cpp
🧠 Learnings (28)
📓 Common learnings
Learnt from: kwvg
Repo: dashpay/dash PR: 7068
File: src/qt/guiutil_font.h:68-77
Timestamp: 2025-12-22T15:42:51.679Z
Learning: In the Dash Core Qt codebase (src/qt/guiutil_font.h), kwvg intentionally uses `assert()` in setter methods like `SetWeightBold` and `SetWeightNormal` to enforce invariants (e.g., `assert(m_weights.count(m_font))`). This fail-fast approach is preferred over defensive checks with fallbacks when an inconsistent state indicates a programming error that should be caught during development, rather than a runtime condition requiring graceful handling.
Learnt from: kwvg
Repo: dashpay/dash PR: 6761
File: src/chainlock/signing.cpp:15-250
Timestamp: 2025-07-23T09:28:32.783Z
Learning: In refactoring PRs like #6761, kwvg prefers to defer code formatting fixes to separate follow-up PRs when formatting is not the primary objective, to maintain focus on the structural changes and avoid scope creep.
Learnt from: kwvg
Repo: dashpay/dash PR: 6718
File: test/functional/test_framework/test_framework.py:2102-2102
Timestamp: 2025-06-09T16:43:20.996Z
Learning: In the test framework consolidation PR (#6718), user kwvg prefers to limit functional changes to those directly related to MasternodeInfo, avoiding scope creep even for minor improvements like error handling consistency.
Learnt from: kwvg
Repo: dashpay/dash PR: 7072
File: src/qt/walletcontroller.cpp:520-528
Timestamp: 2025-12-17T13:58:26.891Z
Learning: In Dash Qt wallet code, when leveraging upstream Bitcoin Core wallet capabilities (especially for operations like rescanning), prefer using the inherited signal-based mechanisms (e.g., ShowProgress signals) over adding explicit Qt progress dialogs to minimize upstream deviation and simplify future backports.
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/qt/**/*.{cpp,h} : GUI implementation in src/qt/ must use Qt 5
📚 Learning: 2025-12-22T15:42:51.679Z
Learnt from: kwvg
Repo: dashpay/dash PR: 7068
File: src/qt/guiutil_font.h:68-77
Timestamp: 2025-12-22T15:42:51.679Z
Learning: In the Dash Core Qt codebase (src/qt/guiutil_font.h), kwvg intentionally uses `assert()` in setter methods like `SetWeightBold` and `SetWeightNormal` to enforce invariants (e.g., `assert(m_weights.count(m_font))`). This fail-fast approach is preferred over defensive checks with fallbacks when an inconsistent state indicates a programming error that should be caught during development, rather than a runtime condition requiring graceful handling.

Applied to files:

  • src/qt/coincontroldialog.cpp
  • src/qt/proposalwizard.cpp
  • src/qt/bitcoingui.cpp
  • src/qt/optionsmodel.cpp
  • src/qt/bitcoin.cpp
  • src/qt/signverifymessagedialog.cpp
  • src/qt/test/apptests.cpp
  • src/qt/guiutil.cpp
  • src/qt/appearancewidget.cpp
  • src/qt/guiutil_font.cpp
  • src/qt/masternodelist.cpp
  • src/qt/qrdialog.cpp
📚 Learning: 2025-12-17T13:58:19.813Z
Learnt from: kwvg
Repo: dashpay/dash PR: 7072
File: src/qt/walletcontroller.cpp:520-528
Timestamp: 2025-12-17T13:58:19.813Z
Learning: In Dash Qt wallet code, prefer using existing Qt signals/slots (e.g., ShowProgress signals) for long-running operations instead of adding explicit QProgressDialog dialogs. This minimizes upstream deviations and simplifies backports. Apply this pattern to wallet-related Qt components (e.g., operations like rescanning) and rely on signal-based progress updates rather than bespoke dialogs.

Applied to files:

  • src/qt/coincontroldialog.cpp
  • src/qt/proposalwizard.cpp
  • src/qt/bitcoingui.cpp
  • src/qt/optionsmodel.cpp
  • src/qt/bitcoin.cpp
  • src/qt/signverifymessagedialog.cpp
  • src/qt/test/apptests.cpp
  • src/qt/guiutil.cpp
  • src/qt/appearancewidget.cpp
  • src/qt/guiutil_font.cpp
  • src/qt/masternodelist.cpp
  • src/qt/qrdialog.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/qt/**/*.{cpp,h} : GUI implementation in src/qt/ must use Qt 5

Applied to files:

  • src/qt/coincontroldialog.cpp
  • src/qt/proposalwizard.cpp
  • src/qt/bitcoingui.cpp
  • src/qt/optionsmodel.cpp
  • src/qt/bitcoin.cpp
  • src/qt/signverifymessagedialog.cpp
  • src/qt/test/apptests.cpp
  • src/qt/guiutil_font.h
  • src/qt/guiutil.cpp
  • src/qt/appearancewidget.cpp
  • src/qt/guiutil_font.cpp
  • src/qt/masternodelist.cpp
  • src/qt/qrdialog.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/wallet/**/*.{cpp,h} : Wallet implementation must use Berkeley DB and SQLite

Applied to files:

  • src/qt/coincontroldialog.cpp
📚 Learning: 2025-12-22T15:42:48.595Z
Learnt from: kwvg
Repo: dashpay/dash PR: 7068
File: src/qt/guiutil_font.h:68-77
Timestamp: 2025-12-22T15:42:48.595Z
Learning: In C++/Qt codebases, use fail-fast asserts in setters to enforce invariants (e.g., ensuring internal maps contain necessary keys). Prefer assert() for programmer errors that should be caught in development and debugging, rather than defensive runtime checks with fallbacks. This helps catch invariant violations early during development. Apply to header and source files where invariant-driven state mutations occur, especially in setters like SetWeightBold/SetWeightNormal that assume established relationships or preconditions.

Applied to files:

  • src/qt/optionsmodel.h
  • src/qt/guiutil_font.h
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/{test,wallet/test}/**/*.{cpp,h} : Unit tests in src/test/ and src/wallet/test/ must use Boost::Test framework

Applied to files:

  • src/qt/test/apptests.cpp
📚 Learning: 2025-10-05T20:38:28.457Z
Learnt from: knst
Repo: dashpay/dash PR: 6871
File: contrib/guix/libexec/build.sh:358-360
Timestamp: 2025-10-05T20:38:28.457Z
Learning: In the Dash repository, when backporting code from Bitcoin Core, typos and minor issues in comments should be kept as-is to reduce merge conflicts in future backports, even if they remain unfixed in Bitcoin Core's master branch.

Applied to files:

  • src/qt/guiutil_font.h
  • src/qt/guiutil_font.cpp
📚 Learning: 2025-07-17T15:48:29.418Z
Learnt from: kwvg
Repo: dashpay/dash PR: 6752
File: src/wallet/load.cpp:164-164
Timestamp: 2025-07-17T15:48:29.418Z
Learning: In Dash Core, kwvg prefers using assert() statements to document expected behavior in code paths, especially when the called function also has internal asserts. This is used as a defensive programming pattern rather than requiring conditional error handling.

Applied to files:

  • src/qt/guiutil_font.h
📚 Learning: 2025-07-29T14:33:01.040Z
Learnt from: kwvg
Repo: dashpay/dash PR: 6761
File: src/wallet/wallet.cpp:0-0
Timestamp: 2025-07-29T14:33:01.040Z
Learning: In refactoring PRs like #6761, kwvg acknowledges code safety improvements (like null pointer checks and unused parameter warnings) but prefers to defer them to follow-up PRs to maintain focus on the primary refactoring objectives, avoiding scope creep.

Applied to files:

  • src/qt/guiutil_font.h
  • src/qt/guiutil_font.cpp
📚 Learning: 2025-07-23T09:28:32.783Z
Learnt from: kwvg
Repo: dashpay/dash PR: 6761
File: src/chainlock/signing.cpp:15-250
Timestamp: 2025-07-23T09:28:32.783Z
Learning: In refactoring PRs like #6761, kwvg prefers to defer code formatting fixes to separate follow-up PRs when formatting is not the primary objective, to maintain focus on the structural changes and avoid scope creep.

Applied to files:

  • src/qt/guiutil_font.h
  • src/qt/guiutil_font.cpp
📚 Learning: 2025-07-29T14:32:48.369Z
Learnt from: kwvg
Repo: dashpay/dash PR: 6761
File: src/chainlock/signing.cpp:247-250
Timestamp: 2025-07-29T14:32:48.369Z
Learning: In PR #6761, kwvg acknowledged a null pointer check issue in ChainLockSigner::Cleanup() method but deferred it to follow-up, consistent with the pattern of avoiding scope creep in refactoring PRs.

Applied to files:

  • src/qt/guiutil_font.h
  • src/qt/guiutil_font.cpp
📚 Learning: 2025-06-09T16:43:20.996Z
Learnt from: kwvg
Repo: dashpay/dash PR: 6718
File: test/functional/test_framework/test_framework.py:2102-2102
Timestamp: 2025-06-09T16:43:20.996Z
Learning: In the test framework consolidation PR (#6718), user kwvg prefers to limit functional changes to those directly related to MasternodeInfo, avoiding scope creep even for minor improvements like error handling consistency.

Applied to files:

  • src/qt/guiutil_font.h
  • src/qt/guiutil_font.cpp
📚 Learning: 2025-11-04T18:24:27.241Z
Learnt from: UdjinM6
Repo: dashpay/dash PR: 6933
File: src/llmq/utils.cpp:284-298
Timestamp: 2025-11-04T18:24:27.241Z
Learning: In consensus-critical code (such as quorum formation, block validation, or deployment activation logic), do not suggest changes to the logic itself even if the implementation appears theoretically incorrect or off-by-one. Consensus rules, once deployed on the Dash network, must be preserved exactly to avoid network forks. Refactoring PRs should maintain perfect behavioral equivalence. Only suggest logic changes if explicitly accompanied by a DIP (Dash Improvement Proposal) or if the maintainer indicates the consensus rule needs to be changed with appropriate activation logic.

Applied to files:

  • src/qt/guiutil_font.h
  • src/qt/guiutil_font.cpp
📚 Learning: 2025-12-17T13:58:26.891Z
Learnt from: kwvg
Repo: dashpay/dash PR: 7072
File: src/qt/walletcontroller.cpp:520-528
Timestamp: 2025-12-17T13:58:26.891Z
Learning: In Dash Qt wallet code, when leveraging upstream Bitcoin Core wallet capabilities (especially for operations like rescanning), prefer using the inherited signal-based mechanisms (e.g., ShowProgress signals) over adding explicit Qt progress dialogs to minimize upstream deviation and simplify future backports.

Applied to files:

  • src/qt/guiutil_font.h
📚 Learning: 2025-08-11T17:16:36.654Z
Learnt from: PastaPastaPasta
Repo: dashpay/dash PR: 6804
File: src/qt/proposalwizard.cpp:40-42
Timestamp: 2025-08-11T17:16:36.654Z
Learning: In the Dash repository, when a PR adds new files that are not from Bitcoin backports, these files must be added to the list in test/util/data/non-backported.txt. This applies to newly created files like qt/proposalwizard.{h,cpp} and forms/proposalwizard.ui. Limited exemptions may exist for subtrees and similar cases.

Applied to files:

  • src/qt/guiutil_font.h
📚 Learning: 2025-02-14T15:15:58.165Z
Learnt from: kwvg
Repo: dashpay/dash PR: 6529
File: src/rpc/governance.cpp:1074-1089
Timestamp: 2025-02-14T15:15:58.165Z
Learning: Code blocks marked with `// clang-format off` and `// clang-format on` directives should be excluded from clang-format suggestions as they are intentionally formatted manually for better readability.

Applied to files:

  • src/qt/guiutil_font.h
  • src/qt/guiutil_font.cpp
📚 Learning: 2025-11-24T19:52:02.686Z
Learnt from: UdjinM6
Repo: dashpay/dash PR: 7004
File: src/llmq/signing_shares.cpp:201-204
Timestamp: 2025-11-24T19:52:02.686Z
Learning: In Dash Core, assertions cannot be disabled during compilation. The codebase always has assertions enabled, so concerns about release builds continuing past assert statements are not applicable.

Applied to files:

  • src/qt/appearancewidget.cpp
📚 Learning: 2025-02-06T14:34:30.466Z
Learnt from: kwvg
Repo: dashpay/dash PR: 6543
File: src/wallet/receive.cpp:240-251
Timestamp: 2025-02-06T14:34:30.466Z
Learning: Pull request #6543 is focused on move-only changes and refactoring, specifically backporting from Bitcoin. Behavior changes should be proposed in separate PRs.

Applied to files:

  • src/qt/guiutil_font.cpp
📚 Learning: 2025-08-19T14:57:31.801Z
Learnt from: knst
Repo: dashpay/dash PR: 6692
File: src/llmq/blockprocessor.cpp:217-224
Timestamp: 2025-08-19T14:57:31.801Z
Learning: In PR #6692, knst acknowledged a null pointer dereference issue in ProcessBlock() method where LookupBlockIndex may return nullptr but is passed to gsl::not_null, and created follow-up PR #6789 to address it, consistent with avoiding scope creep in performance-focused PRs.

Applied to files:

  • src/qt/guiutil_font.cpp
📚 Learning: 2025-07-09T15:05:36.250Z
Learnt from: kwvg
Repo: dashpay/dash PR: 6729
File: src/rpc/evo.cpp:1273-1273
Timestamp: 2025-07-09T15:05:36.250Z
Learning: When clang-format suggestions significantly harm readability (like splitting logical parameter groups across multiple lines), it's acceptable to use `// clang-format off` and `// clang-format on` directives to exclude the problematic section from automatic formatting, prioritizing code readability over strict line length compliance.

Applied to files:

  • src/qt/guiutil_font.cpp
📚 Learning: 2025-10-13T12:37:12.357Z
Learnt from: knst
Repo: dashpay/dash PR: 6883
File: src/rpc/rawtransaction.cpp:1088-1125
Timestamp: 2025-10-13T12:37:12.357Z
Learning: In backport pull requests (especially from Bitcoin Core), treat "moved" or refactored code as out-of-scope for content-level review. Focus validation on verifying that code is moved correctly: no fields added, no fields removed, no fields reordered, and no unexpected changes beyond whitespace adjustments. Pre-existing issues in the upstream code should be preserved to maintain fidelity to the original implementation.

Applied to files:

  • src/qt/guiutil_font.cpp
📚 Learning: 2025-10-25T07:08:51.918Z
Learnt from: knst
Repo: dashpay/dash PR: 6916
File: src/univalue/include/univalue.h:81-88
Timestamp: 2025-10-25T07:08:51.918Z
Learning: For backport PRs from bitcoin/bitcoin, bitcoin-core/gui, etc., backported changes should match the original upstream PRs even if they appear strange, modify vendored code, or seem to violate coding guidelines. Still flag genuine issues like bugs, undefined behavior, crashes, compilation errors, or linter failures.

Applied to files:

  • src/qt/guiutil_font.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/evo/evodb/**/*.{cpp,h} : Evolution Database (CEvoDb) must handle masternode snapshots, quorum state, governance objects with efficient differential updates for masternode lists

Applied to files:

  • src/qt/masternodelist.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/coinjoin/**/*.{cpp,h} : CoinJoin implementation must use masternode-coordinated mixing sessions with uniform denomination outputs

Applied to files:

  • src/qt/masternodelist.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/{masternode,evo,llmq,governance,coinjoin}/**/*.{cpp,h} : Use Dash-specific database implementations: CFlatDB for persistent storage (MasternodeMetaStore, GovernanceStore, SporkStore, NetFulfilledRequestStore) and CDBWrapper extensions for Evolution/DKG/InstantSend/Quorum/RecoveredSigs data

Applied to files:

  • src/qt/masternodelist.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/{masternode,evo}/**/*.{cpp,h} : Masternode lists must use immutable data structures (Immer library) for thread safety

Applied to files:

  • src/qt/masternodelist.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/{masternode,llmq}/**/*.{cpp,h} : BLS integration must be used for cryptographic foundation of advanced masternode features

Applied to files:

  • src/qt/masternodelist.cpp
🧬 Code graph analysis (12)
src/qt/proposalwizard.cpp (1)
src/qt/guiutil_font.cpp (2)
  • setFont (335-343)
  • setFont (335-335)
src/qt/bitcoingui.cpp (1)
src/qt/guiutil_font.cpp (2)
  • setFont (335-343)
  • setFont (335-335)
src/qt/optionsmodel.cpp (2)
src/qt/guiutil_font.cpp (8)
  • fontsLoaded (300-303)
  • fontsLoaded (300-300)
  • setApplicationFont (305-333)
  • setApplicationFont (305-305)
  • weightToArg (178-182)
  • weightToArg (178-178)
  • weightFromArg (168-176)
  • weightFromArg (168-168)
src/qt/optionsmodel.h (1)
  • isOptionOverridden (117-117)
src/qt/bitcoin.cpp (1)
src/qt/guiutil_font.cpp (8)
  • weightToArg (178-182)
  • weightToArg (178-178)
  • weightFromArg (168-176)
  • weightFromArg (168-168)
  • updateFonts (345-440)
  • updateFonts (345-345)
  • setApplicationFont (305-333)
  • setApplicationFont (305-305)
src/qt/signverifymessagedialog.cpp (1)
src/qt/guiutil_font.cpp (2)
  • setFont (335-343)
  • setFont (335-335)
src/qt/test/apptests.cpp (1)
src/qt/guiutil_font.cpp (2)
  • setApplicationFont (305-333)
  • setApplicationFont (305-305)
src/qt/guiutil_font.h (1)
src/qt/guiutil_font.cpp (34)
  • FontInfo (127-133)
  • FontInfo (135-135)
  • GetBestMatch (210-224)
  • GetBestMatch (210-210)
  • RegisterFont (137-157)
  • RegisterFont (137-137)
  • WeightToIdx (520-529)
  • WeightToIdx (520-520)
  • IdxToWeight (513-518)
  • IdxToWeight (513-513)
  • SetFont (159-166)
  • SetFont (159-159)
  • weightFromArg (168-176)
  • weightFromArg (168-168)
  • weightToArg (178-182)
  • weightToArg (178-178)
  • loadFonts (241-298)
  • loadFonts (241-241)
  • fontsLoaded (300-303)
  • fontsLoaded (300-300)
  • setApplicationFont (305-333)
  • setApplicationFont (305-305)
  • setFont (335-343)
  • setFont (335-335)
  • updateFonts (345-440)
  • updateFonts (345-345)
  • getFont (442-496)
  • getFont (442-442)
  • getFont (498-501)
  • getFont (498-498)
  • getFontNormal (503-506)
  • getFontNormal (503-503)
  • getFontBold (508-511)
  • getFontBold (508-508)
src/qt/guiutil.cpp (1)
src/qt/guiutil_font.cpp (2)
  • setFont (335-343)
  • setFont (335-335)
src/qt/appearancewidget.cpp (1)
src/qt/guiutil_font.cpp (4)
  • setApplicationFont (305-333)
  • setApplicationFont (305-305)
  • updateFonts (345-440)
  • updateFonts (345-345)
src/qt/guiutil_font.cpp (1)
src/qt/guiutil.cpp (2)
  • TextWidth (1284-1287)
  • TextWidth (1284-1284)
src/qt/masternodelist.cpp (1)
src/qt/guiutil_font.cpp (2)
  • setFont (335-343)
  • setFont (335-335)
src/qt/qrdialog.cpp (1)
src/qt/guiutil_font.cpp (2)
  • setFont (335-343)
  • setFont (335-335)
🪛 Cppcheck (2.19.0)
src/qt/appearancewidget.cpp

[error] 24-24: #error No known always_inline attribute for this platform.

(preprocessorErrorDirective)

src/qt/guiutil_font.cpp

[error] 454-454: failed to evaluate #if condition, undefined function-like macro invocation

(syntaxError)


[error] 22-22: failed to evaluate #if condition, undefined function-like macro invocation

(syntaxError)


[error] 24-24: #error No known always_inline attribute for this platform.

(preprocessorErrorDirective)

src/qt/masternodelist.cpp

[error] 10-10: failed to evaluate #if condition, undefined function-like macro invocation

(syntaxError)

src/qt/qrdialog.cpp

[error] 24-24: #error No known always_inline attribute for this platform.

(preprocessorErrorDirective)

🪛 GitHub Actions: Clang Diff Format Check
src/qt/guiutil_font.h

[error] 1-1: Clang format differences found in 'src/qt/guiutil_font.h'. Run 'clang-format-diff.py -p1' or apply formatting changes.

src/qt/guiutil_font.cpp

[error] 1-1: Clang format differences found in 'src/qt/guiutil_font.cpp'. Run 'clang-format-diff.py -p1' or apply formatting changes.

src/qt/masternodelist.cpp

[error] 1-1: Clang format differences found in 'src/qt/masternodelist.cpp'. Run 'clang-format-diff.py -p1' or apply formatting changes.

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (11)
  • GitHub Check: linux64_multiprocess / Build depends
  • GitHub Check: win64-build / Build source
  • GitHub Check: linux64_fuzz-build / Build source
  • GitHub Check: linux64_ubsan-build / Build source
  • GitHub Check: linux64_sqlite-build / Build source
  • GitHub Check: linux64-build / Build source
  • GitHub Check: arm-linux-build / Build source
  • GitHub Check: mac-build / Build source
  • GitHub Check: linux64_nowallet-build / Build source
  • GitHub Check: Lint / Run linters
  • GitHub Check: predict_conflicts
🔇 Additional comments (45)
src/qt/guiutil_font.cpp (9)

110-115: LGTM: Helper function for formatted debug output.

The qstrprintf template wrapper is clean and serves its purpose well for converting tinyformat output to QString for debug logging.


127-135: LGTM: FontInfo initialization is correct.

The constructor properly calculates supported and default weights before initializing the weight members. The defaulted destructor is appropriate.


137-157: LGTM: Font registration logic is sound.

The registration flow correctly checks for existing fonts, validates availability when needed, and maintains consistency between m_weights and g_fonts_known.


168-182: LGTM: Weight conversion functions are consistent.

weightFromArg provides safe conversion with error checking, while weightToArg uses an assert to enforce the invariant that only valid weights are converted. This aligns with the established pattern in the codebase.

Based on learnings, this fail-fast approach is intentional.


241-298: LGTM: Font loading logic is comprehensive.

The function correctly:

  • Preserves the system default font
  • Loads all Montserrat variants with proper error checking
  • Provides extensive debug output when enabled
  • Registers all known fonts after successful loading

305-333: LGTM: Application font setup handles platform differences correctly.

The function properly handles different font families and includes platform-specific logic for macOS, which is necessary due to Qt limitations on that platform.


345-440: LGTM: Font update logic is robust.

The function:

  • Properly cleans up deleted widgets using QPointer
  • Uses a two-phase update to avoid font inheritance issues (well documented)
  • Handles both per-widget and per-class font updates
  • Includes comprehensive debug output

442-511: LGTM: Font retrieval logic handles platform differences correctly.

The getFont functions properly handle:

  • Different font families (Montserrat, OS default, custom)
  • Platform-specific Montserrat handling for macOS
  • Font scaling via the registry
  • Optional debug output

The convenience wrappers getFontNormal() and getFontBold() provide clean API access.


513-529: LGTM: Weight/index conversion functions are correct.

IdxToWeight uses an assert for bounds checking (line 516), consistent with the fail-fast pattern. WeightToIdx defensively returns -1 when the weight isn't found, which is appropriate for a lookup operation.

Based on learnings, the assert is intentional.

src/qt/guiutil_font.h (3)

18-32: LGTM: Font constants and structures are well-defined.

The use of constexpr QStringView for font names is appropriate for Qt 5. The FontAttrib structure provides a clean interface for passing font properties.


34-122: LGTM: FontInfo and FontRegistry are well-designed.

The class design properly separates:

  • Public constants and interface
  • Private implementation details
  • Static font defaults with platform-specific values

The setter/getter pattern (asserts in setters, defensive checks in getters) is intentional and consistent with established patterns.

Based on learnings, the assert usage is by design.


124-159: LGTM: Public API is clean and well-documented.

The free functions provide a comprehensive interface for:

  • Weight conversion (weightFromArg, weightToArg)
  • Font lifecycle (loadFonts, fontsLoaded)
  • Font application (setApplicationFont, setFont, updateFonts)
  • Font retrieval (getFont overloads, getFontNormal, getFontBold)
src/qt/test/apptests.cpp (2)

11-11: LGTM: Include added correctly.

The addition of <qt/guiutil_font.h> is necessary for accessing the font management APIs.


82-83: LGTM: Font initialization sequence is correct.

The addition of GUIUtil::setApplicationFont() after GUIUtil::loadFonts() properly completes the font initialization workflow in the test setup.

src/qt/qrdialog.cpp (1)

11-11: LGTM: Migration to registry-based font weight is correct.

The changes properly migrate from the old FontWeight::Bold enum to the new registry-based g_font_registry.GetWeightBold() API, maintaining the same functional behavior.

Also applies to: 24-24

src/qt/optionsmodel.h (1)

117-117: LGTM: Helper method for checking command-line overrides.

The isOptionOverridden() method provides a clean interface for querying whether a specific option was overridden via command-line arguments, complementing the existing getOverriddenByCommandLine() method.

src/qt/guiutil.cpp (1)

300-301: LGTM: setupAppearance migrated to registry-based font API.

The font weight retrieval correctly uses the new registry-based API (g_font_registry.GetWeightBold() and g_font_registry.GetWeightNormal()), maintaining the same functional behavior while using the centralized font management system.

src/qt/proposalwizard.cpp (1)

16-16: LGTM: Font weight migration is correct.

The changes properly migrate from the enum-based font weight to the registry-based API, maintaining consistent behavior.

Also applies to: 47-47

src/qt/coincontroldialog.cpp (1)

16-16: LGTM: Font weight migration completed correctly.

The changes properly migrate to the registry-based font weight API. The setFont call now uses g_font_registry.GetWeightBold() in place of the old enum value.

Also applies to: 55-61

src/qt/bitcoingui.cpp (3)

13-13: Font registry include wiring looks correct

Including <qt/guiutil_font.h> here is appropriate now that this file uses GUIUtil::g_font_registry and GUIUtil::setFont with FontAttrib.


760-762: Toolbar tab font initialization correctly uses registry weights

Using GUIUtil::setFont({button}, {GUIUtil::g_font_registry.GetWeightNormal(), 16}); aligns with the new FontAttrib API and centralizes the actual weight mapping in FontRegistry.


1239-1243: Tab highlight logic now registry‑driven and consistent

highlightTabButton correctly switches between GetWeightBold() / GetWeightNormal() and defers actual application to GUIUtil::updateFonts(), matching the new global font update model.

src/qt/masternodelist.cpp (2)

8-12: Includes updated appropriately for Coin and font registry

Adding <coins.h> for Coin and <qt/guiutil_font.h> for GUIUtil::g_font_registry makes the dependencies explicit and avoids relying on transitive includes.


43-47: Label fonts migrated cleanly to FontRegistry

The two GUIUtil::setFont calls now use GetWeightBold() / GetWeightNormal() with explicit point sizes, matching the registry‑driven font system and keeping the construction simple.

src/qt/signverifymessagedialog.cpp (3)

11-11: Header dependency for font registry is correctly added

Including <qt/guiutil_font.h> is required now that this dialog uses g_font_registry via GUIUtil::setFont.


57-60: Dialog font styling correctly migrated to FontRegistry

The new setFont calls for signature fields and status labels use GetWeightNormal() / GetWeightBold() with appropriate sizes and italics, matching the shared font configuration semantics.


107-117: Active/inactive tab button fonts are updated in a registry‑safe way

showPage() now styles the active button with GetWeightBold() and the others with GetWeightNormal(), then calls GUIUtil::updateFonts(). This is consistent with the centralized font update pipeline.

src/qt/appearancewidget.cpp (8)

23-28: Capturing previous appearance state in the ctor is a good safeguard

Initializing prevTheme, prevScale, prevFontFamily, prevWeightNormal, and prevWeightBold from GUIUtil::getActiveTheme() / g_font_registry at construction time provides a robust basis for later rollback on cancel.


36-40: Font family list is now registry‑driven

Populating fontFamily from GUIUtil::g_fonts_known with the index as userData keeps the combo box in sync with the registry’s notion of known fonts and avoids hard‑coded entries.


87-135: Model mapping and CLI override handling look consistent

setModel:

  • Attaches a QDataWidgetMapper for theme, font family, scale, and weights.
  • Uses QSignalBlocker to avoid triggering update slots during initial population.
  • Disables and forces values for fontFamily, fontScaleSlider, and the weight sliders when the respective -font-* options are overridden on the command line.
  • Uses registry helpers (WeightToIdx, GetWeight*) so sliders always reflect a valid weight index.

This structure keeps UI state, options, and the registry coherent, and correctly respects CLI overrides.


155-161: Font family updates correctly validate via registry and apply fonts

updateFontFamily sets the font through g_font_registry.SetFont(...) with an assert on the returned bool, then calls setApplicationFont() and updateFonts(), followed by updateWeightSlider(true).

This matches the preferred fail‑fast style for invariants while ensuring the UI immediately reflects the change.


164-168: Font scale updates are applied through the registry and global updater

updateFontScale delegates to g_font_registry.SetFontScale(nScale) and then calls GUIUtil::updateFonts(), which is exactly what’s needed to rescale existing widgets without reinitializing the registry.


170-181: Normal weight slider logic enforces ordering and syncs with registry

updateFontWeightNormal:

  • Enforces normal <= bold unless fForce is true.
  • Uses QSignalBlocker on the slider to avoid recursion.
  • Updates g_font_registry via IdxToWeight(...) and then reapplies the application font and widget fonts.

The symmetry with updateFontWeightBold keeps the weight range invariant intact.


183-194: Bold weight slider logic mirrors normal weight handling

updateFontWeightBold mirrors the normal path, enforcing bold >= normal and updating both the slider and the registry + fonts in one place, which keeps the two sliders tightly coupled and avoids impossible configurations.


196-212: Weight slider limits and defaulting behavior are reasonable

updateWeightSlider:

  • Sets both sliders’ min/max based on GetSupportedWeights().size() - 1.
  • When forced, or when previous weights are invalid, reinitializes to registry default normal/bold weights via WeightToIdx(GetWeight*Default()) and the updateFontWeight* helpers.

This ensures the UI always reflects a valid index range and gracefully recovers from unsupported stored weights.

src/qt/optionsmodel.cpp (5)

15-15: Font utilities header inclusion is appropriate

Including <qt/guiutil_font.h> here is necessary now that OptionsModel interacts with GUIUtil::FontRegistry and helpers like weightFromArg / weightToArg.


100-171: Font family/scale/weight initialization is now registry‑centric and robust

The new initialization logic:

  • Seeds fontFamily, fontScale, and both weights from FontRegistry defaults when missing.
  • Uses SoftSetArg + addOverriddenOption to track CLI overrides.
  • Calls GUIUtil::fontsLoaded() before touching g_font_registry, then:
    • Registers/sets the family.
    • Applies the font scale from CLI/settings.
    • For weights, initializes QFont::Weight to GetWeight*Default(), optionally overrides from CLI/settings via weightFromArg, and falls back to supported weights if the chosen weight isn’t available for the current font.
  • Finishes by calling GUIUtil::setApplicationFont() once.

This fully addresses the earlier uninitialized‑weight issue and gracefully handles corrupted or unsupported stored weights.


133-167: CLI font‑family override interaction with weights is handled sensibly

Using override_family{isOptionOverridden("-font-family")} and only applying weightFromArg when either the family is not CLI‑overridden or the specific weight option is overridden gives:

  • Default weights for arbitrary fonts chosen via CLI -font-family, unless the user also explicitly overrides weights.
  • Validated, range‑checked weights via IsValidWeight + GetSupportedWeights() fallback.

This matches the intended separation of duties between family and weight options.


566-579: data() for font weights now safely defaults and uses registry mapping

For FontWeightNormal / FontWeightBold:

  • weight is initialized from GetWeight*Default().
  • weightFromArg optionally adjusts it from stored settings.
  • The resulting weight is mapped to a slider index via WeightToIdx, with an assert ensuring a valid mapping.

This avoids undefined behavior on malformed settings and keeps the UI in sync with the registry’s supported weights.


816-829: setData() correctly translates slider indices back to stored weight args

In setData:

  • The slider index is converted to a QFont::Weight via IdxToWeight.
  • That weight is serialized to an integer arg with weightToArg and written to QSettings.

This keeps the persistent representation aligned with the registry’s internal mapping and with the CLI parsing (weightFromArg).

src/qt/bitcoin.cpp (5)

25-25: Font registry header is correctly added to the Qt entry point

Including <qt/guiutil_font.h> here is required now that GuiMain manipulates the global FontRegistry directly for CLI validation and application.


485-492: UI args for fonts are now documented from registry defaults

The updated SetupUIArgs:

  • Uses Join(GUIUtil::g_fonts_known, ", ") for the -font-family help text.
  • References FontRegistry::DEFAULT_FONT, DEFAULT_FONT_SCALE, and TARGET_WEIGHT_* via weightToArg(...) for defaults.

This keeps CLI help aligned with the registry’s actual capabilities and default configuration.

Please just double‑check that Join(GUIUtil::g_fonts_known, ", ") and the %1 substitution work as expected with the concrete type of g_fonts_known in your tree; if not, QStringList::join(", ") may be a simpler alternative.


664-667: Early abort on font loading failure is appropriate

Bailing out with a critical message box when GUIUtil::loadFonts() fails prevents the app from running with partially initialized font state, which is safer than attempting to continue.


669-677: CLI font‑family validation now fails fast with a clear error

After loading fonts and creating the options model, the -font-family argument is revalidated via RegisterFont and SetFont, with a user‑facing error and EXIT_FAILURE on failure. This addresses prior crash scenarios when an invalid family was passed on the command line.


679-711: CLI validation for weights and scale is thorough and consistent

The new blocks:

  • Parse -font-weight-normal / -font-weight-bold with weightFromArg, erroring out on invalid values before using the result.
  • Parse -font-scale and enforce [-100, 100], exiting on out‑of‑range values.
  • Apply validated values to g_font_registry and finally call GUIUtil::updateFonts() followed by GUIUtil::setApplicationFont().

This gives a clean, deterministic startup path for font CLI options and avoids undefined behavior from malformed arguments.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
src/qt/appearancewidget.cpp (1)

67-82: Consider removing the redundant setApplicationFont() call.

setApplicationFont() is called on line 70 after reverting the font family, and then again on line 81 after all reverts. The first call (line 70) may be redundant since the final call (line 81) will apply the complete reverted state.

🔎 Proposed optimization
         if (prevFontFamily != GUIUtil::g_font_registry.GetFont()) {
             const bool setfont_ret{GUIUtil::g_font_registry.SetFont(prevFontFamily)};
             assert(setfont_ret);
-            GUIUtil::setApplicationFont();
         }
         if (prevScale != GUIUtil::g_font_registry.GetFontScale()) {
             GUIUtil::g_font_registry.SetFontScale(prevScale);
📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between db3d1b8 and b6d418a.

📒 Files selected for processing (37)
  • src/Makefile.qt.include
  • src/qt/addressbookpage.cpp
  • src/qt/addresstablemodel.cpp
  • src/qt/appearancewidget.cpp
  • src/qt/appearancewidget.h
  • src/qt/askpassphrasedialog.cpp
  • src/qt/bitcoin.cpp
  • src/qt/bitcoingui.cpp
  • src/qt/coincontroldialog.cpp
  • src/qt/governancelist.cpp
  • src/qt/guiutil.cpp
  • src/qt/guiutil.h
  • src/qt/guiutil_font.cpp
  • src/qt/guiutil_font.h
  • src/qt/masternodelist.cpp
  • src/qt/modaloverlay.cpp
  • src/qt/openuridialog.cpp
  • src/qt/optionsdialog.cpp
  • src/qt/optionsmodel.cpp
  • src/qt/optionsmodel.h
  • src/qt/overviewpage.cpp
  • src/qt/proposalwizard.cpp
  • src/qt/qrdialog.cpp
  • src/qt/qrimagewidget.cpp
  • src/qt/receivecoinsdialog.cpp
  • src/qt/receiverequestdialog.cpp
  • src/qt/rpcconsole.cpp
  • src/qt/sendcoinsdialog.cpp
  • src/qt/sendcoinsentry.cpp
  • src/qt/signverifymessagedialog.cpp
  • src/qt/splashscreen.cpp
  • src/qt/test/apptests.cpp
  • src/qt/trafficgraphwidget.cpp
  • src/qt/transactiondescdialog.cpp
  • src/qt/utilitydialog.cpp
  • src/qt/walletview.cpp
  • test/util/data/non-backported.txt
💤 Files with no reviewable changes (1)
  • src/qt/guiutil.h
✅ Files skipped from review due to trivial changes (2)
  • src/qt/receiverequestdialog.cpp
  • test/util/data/non-backported.txt
🚧 Files skipped from review as they are similar to previous changes (15)
  • src/qt/proposalwizard.cpp
  • src/Makefile.qt.include
  • src/qt/qrimagewidget.cpp
  • src/qt/overviewpage.cpp
  • src/qt/sendcoinsdialog.cpp
  • src/qt/optionsdialog.cpp
  • src/qt/coincontroldialog.cpp
  • src/qt/askpassphrasedialog.cpp
  • src/qt/sendcoinsentry.cpp
  • src/qt/signverifymessagedialog.cpp
  • src/qt/optionsmodel.h
  • src/qt/walletview.cpp
  • src/qt/transactiondescdialog.cpp
  • src/qt/rpcconsole.cpp
  • src/qt/test/apptests.cpp
🧰 Additional context used
📓 Path-based instructions (2)
src/**/*.{cpp,h,hpp,cc}

📄 CodeRabbit inference engine (CLAUDE.md)

Dash Core implementation must be written in C++20, requiring at least Clang 16 or GCC 11.1

Files:

  • src/qt/governancelist.cpp
  • src/qt/receivecoinsdialog.cpp
  • src/qt/modaloverlay.cpp
  • src/qt/appearancewidget.h
  • src/qt/bitcoingui.cpp
  • src/qt/openuridialog.cpp
  • src/qt/splashscreen.cpp
  • src/qt/masternodelist.cpp
  • src/qt/appearancewidget.cpp
  • src/qt/trafficgraphwidget.cpp
  • src/qt/optionsmodel.cpp
  • src/qt/addresstablemodel.cpp
  • src/qt/guiutil_font.h
  • src/qt/addressbookpage.cpp
  • src/qt/guiutil.cpp
  • src/qt/bitcoin.cpp
  • src/qt/utilitydialog.cpp
  • src/qt/guiutil_font.cpp
  • src/qt/qrdialog.cpp
src/qt/**/*.{cpp,h}

📄 CodeRabbit inference engine (CLAUDE.md)

GUI implementation in src/qt/ must use Qt 5

Files:

  • src/qt/governancelist.cpp
  • src/qt/receivecoinsdialog.cpp
  • src/qt/modaloverlay.cpp
  • src/qt/appearancewidget.h
  • src/qt/bitcoingui.cpp
  • src/qt/openuridialog.cpp
  • src/qt/splashscreen.cpp
  • src/qt/masternodelist.cpp
  • src/qt/appearancewidget.cpp
  • src/qt/trafficgraphwidget.cpp
  • src/qt/optionsmodel.cpp
  • src/qt/addresstablemodel.cpp
  • src/qt/guiutil_font.h
  • src/qt/addressbookpage.cpp
  • src/qt/guiutil.cpp
  • src/qt/bitcoin.cpp
  • src/qt/utilitydialog.cpp
  • src/qt/guiutil_font.cpp
  • src/qt/qrdialog.cpp
🧠 Learnings (27)
📓 Common learnings
Learnt from: kwvg
Repo: dashpay/dash PR: 7068
File: src/qt/guiutil_font.h:68-77
Timestamp: 2025-12-22T15:42:51.679Z
Learning: In the Dash Core Qt codebase (src/qt/guiutil_font.h), kwvg intentionally uses `assert()` in setter methods like `SetWeightBold` and `SetWeightNormal` to enforce invariants (e.g., `assert(m_weights.count(m_font))`). This fail-fast approach is preferred over defensive checks with fallbacks when an inconsistent state indicates a programming error that should be caught during development, rather than a runtime condition requiring graceful handling.
Learnt from: kwvg
Repo: dashpay/dash PR: 6761
File: src/chainlock/signing.cpp:15-250
Timestamp: 2025-07-23T09:28:32.783Z
Learning: In refactoring PRs like #6761, kwvg prefers to defer code formatting fixes to separate follow-up PRs when formatting is not the primary objective, to maintain focus on the structural changes and avoid scope creep.
Learnt from: kwvg
Repo: dashpay/dash PR: 6718
File: test/functional/test_framework/test_framework.py:2102-2102
Timestamp: 2025-06-09T16:43:20.996Z
Learning: In the test framework consolidation PR (#6718), user kwvg prefers to limit functional changes to those directly related to MasternodeInfo, avoiding scope creep even for minor improvements like error handling consistency.
Learnt from: kwvg
Repo: dashpay/dash PR: 6761
File: src/wallet/wallet.cpp:0-0
Timestamp: 2025-07-29T14:33:01.040Z
Learning: In refactoring PRs like #6761, kwvg acknowledges code safety improvements (like null pointer checks and unused parameter warnings) but prefers to defer them to follow-up PRs to maintain focus on the primary refactoring objectives, avoiding scope creep.
Learnt from: kwvg
Repo: dashpay/dash PR: 7072
File: src/qt/walletcontroller.cpp:520-528
Timestamp: 2025-12-17T13:58:26.891Z
Learning: In Dash Qt wallet code, when leveraging upstream Bitcoin Core wallet capabilities (especially for operations like rescanning), prefer using the inherited signal-based mechanisms (e.g., ShowProgress signals) over adding explicit Qt progress dialogs to minimize upstream deviation and simplify future backports.
Learnt from: PastaPastaPasta
Repo: dashpay/dash PR: 6804
File: src/qt/proposalwizard.cpp:40-42
Timestamp: 2025-08-11T17:16:36.654Z
Learning: In the Dash repository, when a PR adds new files that are not from Bitcoin backports, these files must be added to the list in test/util/data/non-backported.txt. This applies to newly created files like qt/proposalwizard.{h,cpp} and forms/proposalwizard.ui. Limited exemptions may exist for subtrees and similar cases.
Learnt from: kwvg
Repo: dashpay/dash PR: 6543
File: src/wallet/receive.cpp:240-251
Timestamp: 2025-02-06T14:34:30.466Z
Learning: Pull request #6543 is focused on move-only changes and refactoring, specifically backporting from Bitcoin. Behavior changes should be proposed in separate PRs.
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/qt/**/*.{cpp,h} : GUI implementation in src/qt/ must use Qt 5
📚 Learning: 2025-12-22T15:42:51.679Z
Learnt from: kwvg
Repo: dashpay/dash PR: 7068
File: src/qt/guiutil_font.h:68-77
Timestamp: 2025-12-22T15:42:51.679Z
Learning: In the Dash Core Qt codebase (src/qt/guiutil_font.h), kwvg intentionally uses `assert()` in setter methods like `SetWeightBold` and `SetWeightNormal` to enforce invariants (e.g., `assert(m_weights.count(m_font))`). This fail-fast approach is preferred over defensive checks with fallbacks when an inconsistent state indicates a programming error that should be caught during development, rather than a runtime condition requiring graceful handling.

Applied to files:

  • src/qt/governancelist.cpp
  • src/qt/receivecoinsdialog.cpp
  • src/qt/modaloverlay.cpp
  • src/qt/bitcoingui.cpp
  • src/qt/splashscreen.cpp
  • src/qt/masternodelist.cpp
  • src/qt/appearancewidget.cpp
  • src/qt/trafficgraphwidget.cpp
  • src/qt/optionsmodel.cpp
  • src/qt/addresstablemodel.cpp
  • src/qt/guiutil.cpp
  • src/qt/bitcoin.cpp
  • src/qt/guiutil_font.cpp
  • src/qt/qrdialog.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/qt/**/*.{cpp,h} : GUI implementation in src/qt/ must use Qt 5

Applied to files:

  • src/qt/governancelist.cpp
  • src/qt/receivecoinsdialog.cpp
  • src/qt/modaloverlay.cpp
  • src/qt/appearancewidget.h
  • src/qt/bitcoingui.cpp
  • src/qt/openuridialog.cpp
  • src/qt/splashscreen.cpp
  • src/qt/masternodelist.cpp
  • src/qt/appearancewidget.cpp
  • src/qt/trafficgraphwidget.cpp
  • src/qt/optionsmodel.cpp
  • src/qt/addresstablemodel.cpp
  • src/qt/guiutil_font.h
  • src/qt/addressbookpage.cpp
  • src/qt/guiutil.cpp
  • src/qt/bitcoin.cpp
  • src/qt/utilitydialog.cpp
  • src/qt/guiutil_font.cpp
  • src/qt/qrdialog.cpp
📚 Learning: 2025-12-17T13:58:19.813Z
Learnt from: kwvg
Repo: dashpay/dash PR: 7072
File: src/qt/walletcontroller.cpp:520-528
Timestamp: 2025-12-17T13:58:19.813Z
Learning: In Dash Qt wallet code, prefer using existing Qt signals/slots (e.g., ShowProgress signals) for long-running operations instead of adding explicit QProgressDialog dialogs. This minimizes upstream deviations and simplifies backports. Apply this pattern to wallet-related Qt components (e.g., operations like rescanning) and rely on signal-based progress updates rather than bespoke dialogs.

Applied to files:

  • src/qt/governancelist.cpp
  • src/qt/receivecoinsdialog.cpp
  • src/qt/modaloverlay.cpp
  • src/qt/bitcoingui.cpp
  • src/qt/openuridialog.cpp
  • src/qt/splashscreen.cpp
  • src/qt/masternodelist.cpp
  • src/qt/appearancewidget.cpp
  • src/qt/trafficgraphwidget.cpp
  • src/qt/optionsmodel.cpp
  • src/qt/addresstablemodel.cpp
  • src/qt/addressbookpage.cpp
  • src/qt/guiutil.cpp
  • src/qt/bitcoin.cpp
  • src/qt/utilitydialog.cpp
  • src/qt/guiutil_font.cpp
  • src/qt/qrdialog.cpp
📚 Learning: 2025-12-22T15:42:48.595Z
Learnt from: kwvg
Repo: dashpay/dash PR: 7068
File: src/qt/guiutil_font.h:68-77
Timestamp: 2025-12-22T15:42:48.595Z
Learning: In C++/Qt codebases, use fail-fast asserts in setters to enforce invariants (e.g., ensuring internal maps contain necessary keys). Prefer assert() for programmer errors that should be caught in development and debugging, rather than defensive runtime checks with fallbacks. This helps catch invariant violations early during development. Apply to header and source files where invariant-driven state mutations occur, especially in setters like SetWeightBold/SetWeightNormal that assume established relationships or preconditions.

Applied to files:

  • src/qt/appearancewidget.h
  • src/qt/guiutil_font.h
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/wallet/**/*.{cpp,h} : Wallet implementation must use Berkeley DB and SQLite

Applied to files:

  • src/qt/splashscreen.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/evo/evodb/**/*.{cpp,h} : Evolution Database (CEvoDb) must handle masternode snapshots, quorum state, governance objects with efficient differential updates for masternode lists

Applied to files:

  • src/qt/masternodelist.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/{masternode,evo,llmq,governance,coinjoin}/**/*.{cpp,h} : Use Dash-specific database implementations: CFlatDB for persistent storage (MasternodeMetaStore, GovernanceStore, SporkStore, NetFulfilledRequestStore) and CDBWrapper extensions for Evolution/DKG/InstantSend/Quorum/RecoveredSigs data

Applied to files:

  • src/qt/masternodelist.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/{masternode,evo}/**/*.{cpp,h} : Masternode lists must use immutable data structures (Immer library) for thread safety

Applied to files:

  • src/qt/masternodelist.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/coinjoin/**/*.{cpp,h} : CoinJoin implementation must use masternode-coordinated mixing sessions with uniform denomination outputs

Applied to files:

  • src/qt/masternodelist.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/{masternode,llmq}/**/*.{cpp,h} : BLS integration must be used for cryptographic foundation of advanced masternode features

Applied to files:

  • src/qt/masternodelist.cpp
📚 Learning: 2025-11-24T19:52:02.686Z
Learnt from: UdjinM6
Repo: dashpay/dash PR: 7004
File: src/llmq/signing_shares.cpp:201-204
Timestamp: 2025-11-24T19:52:02.686Z
Learning: In Dash Core, assertions cannot be disabled during compilation. The codebase always has assertions enabled, so concerns about release builds continuing past assert statements are not applicable.

Applied to files:

  • src/qt/appearancewidget.cpp
📚 Learning: 2025-10-05T20:38:28.457Z
Learnt from: knst
Repo: dashpay/dash PR: 6871
File: contrib/guix/libexec/build.sh:358-360
Timestamp: 2025-10-05T20:38:28.457Z
Learning: In the Dash repository, when backporting code from Bitcoin Core, typos and minor issues in comments should be kept as-is to reduce merge conflicts in future backports, even if they remain unfixed in Bitcoin Core's master branch.

Applied to files:

  • src/qt/guiutil_font.h
  • src/qt/guiutil_font.cpp
📚 Learning: 2025-07-17T15:48:29.418Z
Learnt from: kwvg
Repo: dashpay/dash PR: 6752
File: src/wallet/load.cpp:164-164
Timestamp: 2025-07-17T15:48:29.418Z
Learning: In Dash Core, kwvg prefers using assert() statements to document expected behavior in code paths, especially when the called function also has internal asserts. This is used as a defensive programming pattern rather than requiring conditional error handling.

Applied to files:

  • src/qt/guiutil_font.h
📚 Learning: 2025-07-29T14:33:01.040Z
Learnt from: kwvg
Repo: dashpay/dash PR: 6761
File: src/wallet/wallet.cpp:0-0
Timestamp: 2025-07-29T14:33:01.040Z
Learning: In refactoring PRs like #6761, kwvg acknowledges code safety improvements (like null pointer checks and unused parameter warnings) but prefers to defer them to follow-up PRs to maintain focus on the primary refactoring objectives, avoiding scope creep.

Applied to files:

  • src/qt/guiutil_font.h
  • src/qt/guiutil_font.cpp
📚 Learning: 2025-07-23T09:28:32.783Z
Learnt from: kwvg
Repo: dashpay/dash PR: 6761
File: src/chainlock/signing.cpp:15-250
Timestamp: 2025-07-23T09:28:32.783Z
Learning: In refactoring PRs like #6761, kwvg prefers to defer code formatting fixes to separate follow-up PRs when formatting is not the primary objective, to maintain focus on the structural changes and avoid scope creep.

Applied to files:

  • src/qt/guiutil_font.h
  • src/qt/guiutil_font.cpp
📚 Learning: 2025-07-29T14:32:48.369Z
Learnt from: kwvg
Repo: dashpay/dash PR: 6761
File: src/chainlock/signing.cpp:247-250
Timestamp: 2025-07-29T14:32:48.369Z
Learning: In PR #6761, kwvg acknowledged a null pointer check issue in ChainLockSigner::Cleanup() method but deferred it to follow-up, consistent with the pattern of avoiding scope creep in refactoring PRs.

Applied to files:

  • src/qt/guiutil_font.h
  • src/qt/guiutil_font.cpp
📚 Learning: 2025-06-09T16:43:20.996Z
Learnt from: kwvg
Repo: dashpay/dash PR: 6718
File: test/functional/test_framework/test_framework.py:2102-2102
Timestamp: 2025-06-09T16:43:20.996Z
Learning: In the test framework consolidation PR (#6718), user kwvg prefers to limit functional changes to those directly related to MasternodeInfo, avoiding scope creep even for minor improvements like error handling consistency.

Applied to files:

  • src/qt/guiutil_font.h
  • src/qt/guiutil_font.cpp
📚 Learning: 2025-11-04T18:24:27.241Z
Learnt from: UdjinM6
Repo: dashpay/dash PR: 6933
File: src/llmq/utils.cpp:284-298
Timestamp: 2025-11-04T18:24:27.241Z
Learning: In consensus-critical code (such as quorum formation, block validation, or deployment activation logic), do not suggest changes to the logic itself even if the implementation appears theoretically incorrect or off-by-one. Consensus rules, once deployed on the Dash network, must be preserved exactly to avoid network forks. Refactoring PRs should maintain perfect behavioral equivalence. Only suggest logic changes if explicitly accompanied by a DIP (Dash Improvement Proposal) or if the maintainer indicates the consensus rule needs to be changed with appropriate activation logic.

Applied to files:

  • src/qt/guiutil_font.h
  • src/qt/guiutil_font.cpp
📚 Learning: 2025-12-17T13:58:26.891Z
Learnt from: kwvg
Repo: dashpay/dash PR: 7072
File: src/qt/walletcontroller.cpp:520-528
Timestamp: 2025-12-17T13:58:26.891Z
Learning: In Dash Qt wallet code, when leveraging upstream Bitcoin Core wallet capabilities (especially for operations like rescanning), prefer using the inherited signal-based mechanisms (e.g., ShowProgress signals) over adding explicit Qt progress dialogs to minimize upstream deviation and simplify future backports.

Applied to files:

  • src/qt/guiutil_font.h
📚 Learning: 2025-08-11T17:16:36.654Z
Learnt from: PastaPastaPasta
Repo: dashpay/dash PR: 6804
File: src/qt/proposalwizard.cpp:40-42
Timestamp: 2025-08-11T17:16:36.654Z
Learning: In the Dash repository, when a PR adds new files that are not from Bitcoin backports, these files must be added to the list in test/util/data/non-backported.txt. This applies to newly created files like qt/proposalwizard.{h,cpp} and forms/proposalwizard.ui. Limited exemptions may exist for subtrees and similar cases.

Applied to files:

  • src/qt/guiutil_font.h
📚 Learning: 2025-02-14T15:15:58.165Z
Learnt from: kwvg
Repo: dashpay/dash PR: 6529
File: src/rpc/governance.cpp:1074-1089
Timestamp: 2025-02-14T15:15:58.165Z
Learning: Code blocks marked with `// clang-format off` and `// clang-format on` directives should be excluded from clang-format suggestions as they are intentionally formatted manually for better readability.

Applied to files:

  • src/qt/guiutil_font.h
  • src/qt/guiutil_font.cpp
📚 Learning: 2025-02-06T14:34:30.466Z
Learnt from: kwvg
Repo: dashpay/dash PR: 6543
File: src/wallet/receive.cpp:240-251
Timestamp: 2025-02-06T14:34:30.466Z
Learning: Pull request #6543 is focused on move-only changes and refactoring, specifically backporting from Bitcoin. Behavior changes should be proposed in separate PRs.

Applied to files:

  • src/qt/guiutil_font.cpp
📚 Learning: 2025-08-19T14:57:31.801Z
Learnt from: knst
Repo: dashpay/dash PR: 6692
File: src/llmq/blockprocessor.cpp:217-224
Timestamp: 2025-08-19T14:57:31.801Z
Learning: In PR #6692, knst acknowledged a null pointer dereference issue in ProcessBlock() method where LookupBlockIndex may return nullptr but is passed to gsl::not_null, and created follow-up PR #6789 to address it, consistent with avoiding scope creep in performance-focused PRs.

Applied to files:

  • src/qt/guiutil_font.cpp
📚 Learning: 2025-07-09T15:05:36.250Z
Learnt from: kwvg
Repo: dashpay/dash PR: 6729
File: src/rpc/evo.cpp:1273-1273
Timestamp: 2025-07-09T15:05:36.250Z
Learning: When clang-format suggestions significantly harm readability (like splitting logical parameter groups across multiple lines), it's acceptable to use `// clang-format off` and `// clang-format on` directives to exclude the problematic section from automatic formatting, prioritizing code readability over strict line length compliance.

Applied to files:

  • src/qt/guiutil_font.cpp
📚 Learning: 2025-10-13T12:37:12.357Z
Learnt from: knst
Repo: dashpay/dash PR: 6883
File: src/rpc/rawtransaction.cpp:1088-1125
Timestamp: 2025-10-13T12:37:12.357Z
Learning: In backport pull requests (especially from Bitcoin Core), treat "moved" or refactored code as out-of-scope for content-level review. Focus validation on verifying that code is moved correctly: no fields added, no fields removed, no fields reordered, and no unexpected changes beyond whitespace adjustments. Pre-existing issues in the upstream code should be preserved to maintain fidelity to the original implementation.

Applied to files:

  • src/qt/guiutil_font.cpp
📚 Learning: 2025-10-25T07:08:51.918Z
Learnt from: knst
Repo: dashpay/dash PR: 6916
File: src/univalue/include/univalue.h:81-88
Timestamp: 2025-10-25T07:08:51.918Z
Learning: For backport PRs from bitcoin/bitcoin, bitcoin-core/gui, etc., backported changes should match the original upstream PRs even if they appear strange, modify vendored code, or seem to violate coding guidelines. Still flag genuine issues like bugs, undefined behavior, crashes, compilation errors, or linter failures.

Applied to files:

  • src/qt/guiutil_font.cpp
🧬 Code graph analysis (11)
src/qt/governancelist.cpp (1)
src/qt/guiutil_font.cpp (2)
  • setFont (335-343)
  • setFont (335-335)
src/qt/receivecoinsdialog.cpp (1)
src/qt/guiutil_font.cpp (2)
  • setFont (335-343)
  • setFont (335-335)
src/qt/bitcoingui.cpp (1)
src/qt/guiutil_font.cpp (2)
  • setFont (335-343)
  • setFont (335-335)
src/qt/masternodelist.cpp (1)
src/qt/guiutil_font.cpp (2)
  • setFont (335-343)
  • setFont (335-335)
src/qt/appearancewidget.cpp (1)
src/qt/guiutil_font.cpp (4)
  • setApplicationFont (305-333)
  • setApplicationFont (305-305)
  • updateFonts (345-440)
  • updateFonts (345-345)
src/qt/trafficgraphwidget.cpp (1)
src/qt/guiutil_font.cpp (4)
  • getFont (442-496)
  • getFont (442-442)
  • getFont (498-501)
  • getFont (498-498)
src/qt/optionsmodel.cpp (2)
src/qt/guiutil_font.cpp (8)
  • fontsLoaded (300-303)
  • fontsLoaded (300-300)
  • setApplicationFont (305-333)
  • setApplicationFont (305-305)
  • weightToArg (178-182)
  • weightToArg (178-178)
  • weightFromArg (168-176)
  • weightFromArg (168-168)
src/qt/optionsmodel.h (1)
  • isOptionOverridden (117-117)
src/qt/guiutil_font.h (1)
src/qt/guiutil_font.cpp (34)
  • FontInfo (127-133)
  • FontInfo (135-135)
  • GetBestMatch (210-224)
  • GetBestMatch (210-210)
  • RegisterFont (137-157)
  • RegisterFont (137-137)
  • WeightToIdx (520-529)
  • WeightToIdx (520-520)
  • IdxToWeight (513-518)
  • IdxToWeight (513-513)
  • SetFont (159-166)
  • SetFont (159-159)
  • weightFromArg (168-176)
  • weightFromArg (168-168)
  • weightToArg (178-182)
  • weightToArg (178-178)
  • loadFonts (241-298)
  • loadFonts (241-241)
  • fontsLoaded (300-303)
  • fontsLoaded (300-300)
  • setApplicationFont (305-333)
  • setApplicationFont (305-305)
  • setFont (335-343)
  • setFont (335-335)
  • updateFonts (345-440)
  • updateFonts (345-345)
  • getFont (442-496)
  • getFont (442-442)
  • getFont (498-501)
  • getFont (498-498)
  • getFontNormal (503-506)
  • getFontNormal (503-503)
  • getFontBold (508-511)
  • getFontBold (508-508)
src/qt/guiutil.cpp (1)
src/qt/guiutil_font.cpp (2)
  • setFont (335-343)
  • setFont (335-335)
src/qt/guiutil_font.cpp (1)
src/qt/guiutil.cpp (2)
  • TextWidth (1284-1287)
  • TextWidth (1284-1284)
src/qt/qrdialog.cpp (1)
src/qt/guiutil_font.cpp (2)
  • setFont (335-343)
  • setFont (335-335)
🪛 Cppcheck (2.19.0)
src/qt/masternodelist.cpp

[error] 10-10: failed to evaluate #if condition, undefined function-like macro invocation

(syntaxError)

src/qt/appearancewidget.cpp

[error] 24-24: #error No known always_inline attribute for this platform.

(preprocessorErrorDirective)

src/qt/guiutil_font.cpp

[error] 454-454: failed to evaluate #if condition, undefined function-like macro invocation

(syntaxError)


[error] 22-22: failed to evaluate #if condition, undefined function-like macro invocation

(syntaxError)


[error] 24-24: #error No known always_inline attribute for this platform.

(preprocessorErrorDirective)

src/qt/qrdialog.cpp

[error] 24-24: #error No known always_inline attribute for this platform.

(preprocessorErrorDirective)

🪛 GitHub Actions: Clang Diff Format Check
src/qt/guiutil_font.cpp

[error] 1-1: Clang format differences detected between before/after formatting. Run the provided clang-format-diff step to fix formatting issues. Command failed with exit code 1.

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
  • GitHub Check: linux64_multiprocess-build / Build source
  • GitHub Check: linux64_tsan-build / Build source
  • GitHub Check: linux64_nowallet-build / Build source
  • GitHub Check: linux64-build / Build source
  • GitHub Check: linux64_fuzz-build / Build source
  • GitHub Check: linux64_ubsan-build / Build source
  • GitHub Check: linux64_sqlite-build / Build source
  • GitHub Check: win64-build / Build source
  • GitHub Check: arm-linux-build / Build source
  • GitHub Check: mac-build / Build source
🔇 Additional comments (33)
src/qt/guiutil_font.h (2)

1-122: LGTM! Clean font infrastructure design.

The header structure is well-organized with proper encapsulation. The FontInfo and FontRegistry classes provide a comprehensive font management system. The defensive getters with fallback values and the platform-specific defaults for macOS are good design choices.


124-161: LGTM! Comprehensive public API.

The function declarations provide a complete interface for font management. The API covers loading, validation, application-wide setting, per-widget customization, and convenience accessors.

src/qt/addresstablemodel.cpp (1)

9-9: LGTM! Include added for font registry support.

The include is necessary for the GUIUtil::getFontNormal() call on line 217.

src/qt/utilitydialog.cpp (1)

15-15: LGTM! Include added for consistency.

The include brings in font utilities for potential use by this dialog.

src/qt/splashscreen.cpp (1)

19-19: LGTM! Include added to support font calls.

The include is necessary for GUIUtil::getFontNormal() and GUIUtil::getFontBold() calls on lines 61-62.

src/qt/addressbookpage.cpp (1)

17-17: LGTM! Include added for font utilities.

The include prepares this file for font registry usage.

src/qt/qrdialog.cpp (1)

11-11: LGTM! Successfully migrated to registry-based font weight.

The change from GUIUtil::FontWeight::Bold to GUIUtil::g_font_registry.GetWeightBold() aligns with the font registry refactoring. The braced initialization correctly provides weight and size to match the FontAttrib structure.

Also applies to: 24-24

src/qt/trafficgraphwidget.cpp (1)

9-9: LGTM! Font calls migrated to registry-based approach.

The changes correctly migrate from the old getFont signature to the new FontAttrib-based signature. The braced initializers properly provide {weight, point_size, is_italic} matching the FontAttrib structure (lines 28-32 in guiutil_font.h).

Also applies to: 171-172

src/qt/guiutil_font.cpp (6)

24-116: LGTM! Well-organized global state and helper structures.

The anonymous namespace properly encapsulates global state. The compile-time initialization of mapWeightArgs and the qstrprintf helper are nice touches. Data structures are clearly organized and documented.


118-239: LGTM! Robust font weight detection and management.

The weight detection logic is well-implemented:

  • CalcSupportedWeights cleverly uses text width testing to detect actual weight differences
  • GetBestMatch finds the closest supported weight via minimum distance
  • CalcDefaultWeights ensures distinct normal and bold weights when possible

The weightToArg assert (line 180) is appropriate as this is an internal mapping that should only receive valid weights from the registry.


241-303: LGTM! Font loading implementation is thorough and safe.

The function properly:

  • Preserves the default font before making changes
  • Imports all Montserrat variants systematically
  • Validates all imports succeeded before proceeding
  • Guards debug logging appropriately
  • Registers fonts with validation skipped since they were just loaded

The fail-safe behavior of resetting g_default_font to nullptr on failure is good practice.


305-343: LGTM! Application font setting with platform-specific handling.

The implementation correctly handles different platforms:

  • macOS uses getFontNormal() which handles style names differently (see lines 451-463 for the macOS-specific style name setting)
  • Other platforms set family and weight separately

The setFont function properly maintains the widget-to-font-attribute mapping, updating existing entries when called multiple times on the same widget.


345-440: LGTM! Comprehensive font update logic with smart two-phase application.

The function is well-structured:

  • Properly cleans up deleted widgets via QPointer.isNull()
  • Two-phase update (calculate then apply) prevents font inheritance issues
  • Maintains default font sizes per widget
  • Handles class-level font scaling separately

Note: The assert at line 390 was previously flagged and marked as addressed in commits 828927e to 14137c6 according to past comments.


442-530: LGTM! Complete font getter implementation with platform handling.

The implementation properly handles:

  • Platform-specific Montserrat style name vs family+variant approach
  • Fallback to system default font
  • Custom font families
  • Font scaling via registry
  • Weight-to-index mapping with defensive return

The macOS-specific handling (lines 451-463, 477-483) addresses platform font rendering differences. The WeightToIdx/IdxToWeight functions form a proper bidirectional mapping, with WeightToIdx returning -1 for invalid weights and IdxToWeight asserting valid indices.

src/qt/openuridialog.cpp (1)

10-10: LGTM!

The include addition for guiutil_font.h is appropriate since GUIUtil::updateFonts() is used in this file's constructor.

src/qt/modaloverlay.cpp (1)

10-10: LGTM!

The migration to registry-based font weights is correct. The brace-init {GUIUtil::g_font_registry.GetWeightBold()} properly constructs a FontAttrib with the bold weight from the registry.

Also applies to: 32-32

src/qt/receivecoinsdialog.cpp (1)

10-10: LGTM!

The font registry migration correctly uses brace-initialized FontAttrib with weight and size parameters. The pattern is consistent with other files in this PR.

Also applies to: 26-29

src/qt/governancelist.cpp (1)

21-21: LGTM!

The font registry integration follows the established pattern, using registry-derived weights with explicit font sizes.

Also applies to: 316-317

src/qt/bitcoingui.cpp (1)

13-13: LGTM!

The font registry integration is well-implemented:

  • Initial tab button fonts use normal weight (line 761)
  • Dynamic bold/normal switching on tab selection works correctly via the ternary (line 1243)

Also applies to: 761-761, 1243-1243

src/qt/masternodelist.cpp (2)

12-12: LGTM!

The font registry migration is correctly implemented with consistent brace-init syntax for FontAttrib construction.

Also applies to: 43-46


8-8: The #include <coins.h> is necessary and should be retained.

The Coin type is used at line 182 of the file, and coins.h is the header that defines it. While this include is unrelated to the font infrastructure changes, it is not accidental and is required for compilation.

Likely an incorrect or invalid review comment.

src/qt/appearancewidget.h (1)

51-55: Verify all members are initialized in the constructor.

The members now lack in-class initializers. This is appropriate since they're initialized from the font registry in the constructor, but ensure all paths through construction properly initialize these values.

src/qt/appearancewidget.cpp (5)

21-28: LGTM!

Member initialization from the font registry in the constructor is well-structured and ensures consistent state capture for potential reversion.


36-38: LGTM!

The font family population now correctly iterates over g_fonts_known with index-based item data, enabling proper lookup when selection changes.


87-136: LGTM!

The setModel implementation properly:

  • Uses signal blockers to prevent spurious updates during initialization
  • Handles command-line overrides by disabling UI controls and syncing values from the registry
  • Correctly initializes weight sliders using WeightToIdx for proper slider positioning

155-161: LGTM!

The assert pattern for SetFont return value follows the established convention from past review feedback.


196-212: LGTM!

The weight slider update logic correctly uses registry methods to determine valid weight ranges and defaults, with appropriate assertions for invariants.

src/qt/optionsmodel.cpp (3)

100-171: LGTM! Font initialization properly integrates with FontRegistry.

The font initialization flow correctly:

  • Registers fonts and applies settings from both QSettings and command-line args
  • Initializes weight variables to defaults before use (lines 136, 156), addressing the previous uninitialized variable concern
  • Handles the interaction between CLI font-family and weight overrides intelligently: when font-family is overridden via CLI but weight is not, it uses the font's default weight (lines 137-138, 157-158) rather than a potentially incompatible saved weight
  • Applies fallback to supported weights when needed (lines 139-143, 159-164)
  • Finalizes with setApplicationFont() after all settings are processed

566-579: LGTM! Weight retrieval in data() properly handles invalid settings.

Both FontWeightNormal and FontWeightBold cases:

  • Initialize weight to registry defaults before calling weightFromArg (lines 567, 574)
  • Provide fallback when WeightToIdx returns -1, ensuring valid indices even for corrupted settings
  • Use assertions to verify the final index is valid

The pattern of ignoring weightFromArg's return value is appropriate here—unlike the CLI validation in bitcoin.cpp, these methods gracefully handle invalid stored values by falling back to defaults rather than failing fast.


816-829: LGTM! Font weight persistence correctly maps indices to settings values.

The setData() handlers for both normal and bold weights properly:

  • Convert UI indices to QFont::Weight via IdxToWeight
  • Convert weights to integer args via weightToArg for QSettings persistence
  • Follow the standard Qt model pattern of checking before setting
src/qt/bitcoin.cpp (2)

492-495: LGTM! Command-line argument setup properly references FontRegistry constants.

The font-related argument definitions correctly use:

  • g_fonts_known for the list of available fonts
  • FontRegistry::DEFAULT_FONT and DEFAULT_FONT_SCALE for defaults
  • TARGET_WEIGHT_BOLD and TARGET_WEIGHT_NORMAL via weightToArg for weight ranges

667-714: LGTM! Font initialization and CLI validation flow is correct.

The sequence properly:

  1. Loads fonts (line 667) with error handling
  2. Creates OptionsModel (line 672), which performs initial font setup via Init()
  3. Validates CLI arguments (lines 674-711) with early, user-friendly error messages
  4. Applies final font configuration (lines 712-714)

The CLI validation after OptionsModel::Init() might seem redundant, but it provides fail-fast validation with clear error messages before the GUI fully initializes, which is good UX.

Note on weight initialization: Variables weight at lines 683 and 693 are declared uninitialized, but this is safe—if weightFromArg returns false, EXIT_FAILURE is returned immediately (lines 685-687, 695-697), so the uninitialized value is never used.

src/qt/guiutil.cpp (1)

300-301: LGTM! Appearance setup correctly uses registry-based font weights.

The setFont calls now properly reference the current configured weights via g_font_registry.GetWeightBold() and GetWeightNormal() instead of hardcoded enums, ensuring the appearance setup dialog respects user-configured font weights.

Copy link

@UdjinM6 UdjinM6 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Light ACK b6d418a

@PastaPastaPasta PastaPastaPasta merged commit 297c9cc into dashpay:develop Dec 29, 2025
79 of 85 checks passed
PastaPastaPasta added a commit that referenced this pull request Dec 30, 2025
…to valid index

8bba1d2 fix: don't assume that successful `weightFromArg` links to valid index (Kittywhiskers Van Gogh)

Pull request description:

  ## Additional Information

  [dash#7068](#7068) introduced a regression where Qt clients with no GUI settings are unable to run at all due to failed weight to index conversion. This was covered in 9cd9d44 but made an incorrect assumption that earlier iterations of the fix (see ef34868) did not make.

  The assumption made that resulted in this regression was that if the argument to weight conversion is successful, then the weight to index conversion will also be successful.

  The earlier iteration of the fix checked the return value of the index conversion and set a sane default if it was invalid. The final iteration set the default weight value to the sane weight, expecting `weightFromArg()` to fail (hence using the sane weight), not `supportedWeightToIndex()` (which might not be able to process even a valid weight from argument).

  This was not caught in testing as over the course of working on [dash#6833](#6833), my GUI settings were migrated to `settings.json`, which has precedence over `QSettings` and therefore, the client always ran with known good Montserrat parameters.

  Fix can be verified by deleting your QSettings parameters and running the client anew.

  ## Breaking Changes

  None expected.

  ## Checklist

  - [x] I have performed a self-review of my own code
  - [x] I have commented my code, particularly in hard-to-understand areas **(note: N/A)**
  - [x] I have added or updated relevant unit/integration/functional/e2e tests **(note: N/A)**
  - [x] I have made corresponding changes to the documentation **(note: N/A)**
  - [x] I have assigned this pull request to a milestone _(for repository code-owners and collaborators only)_

ACKs for top commit:
  UdjinM6:
    utACK 8bba1d2
  PastaPastaPasta:
    utACK 8bba1d2

Tree-SHA512: 6772d59a8cffb43427ea83b5ff2e725efbfc741e890c40e059ffe2fe3405fbe535f975f4ebbd78fbe44bdf671deaeb1a329b3c29530a8de4cceab02f5ce6009c
PastaPastaPasta added a commit that referenced this pull request Jan 3, 2026
…nt font for overview page balances)

636e7a6 refactor: remove redundant preview and simplify font handling (UdjinM6)
b59b0f7 feat(qt): add live preview for monospace font in appearance settings (UdjinM6)
83af951 fix: set money font when setting wallet model instead of ctor (Kittywhiskers Van Gogh)
658905b qt: add non-monospace option and use it as default (Kittywhiskers Van Gogh)
e0513ff qt: add horizontal spacer for visual consistency (Kittywhiskers Van Gogh)
e5a8d05 refactor: move monospace font selector to appearance widget (Kittywhiskers Van Gogh)
41c69e9 merge bitcoin-core/gui#497: Enable users to configure their monospace font specifically (Kittywhiskers Van Gogh)
da5804e merge bitcoin-core/gui#79: Embed monospaced font (Kittywhiskers Van Gogh)
eac4f52 qt: adjust padding and font size of monospace font selector (Kittywhiskers Van Gogh)
9c315c3 qt: add monospaced font settings (Kittywhiskers Van Gogh)
34211b6 qt: apply monospace font to overview page balances and CoinJoin elements (Kittywhiskers Van Gogh)
6ed53d6 qt: allow overriding font registry for specific widgets (Kittywhiskers Van Gogh)
800cf66 qt: recognize system monospace font as non-selectable font (Kittywhiskers Van Gogh)
85b49b9 qt: add "Roboto Mono" as non-selectable font (Kittywhiskers Van Gogh)

Pull request description:

  ## Additional Information

  * Depends on #7068

  * Depends on #7084

  * Dependency for #6833

  | [dash#7084](#7084) (8bba1d2)  | This PR (636e7a6) |
  | ------------------- | ------------------- |
  | ![image](https://github.com/user-attachments/assets/0208ffb7-d511-4211-a304-6a0aa4d6c367) | ![image](https://github.com/user-attachments/assets/d1f42ec7-f1ee-4856-9c42-04b4c0b103aa) |
  | ![image](https://github.com/user-attachments/assets/1ce9c72b-d6a1-43ed-b86d-d76cbd52f2b8) | ![image](https://github.com/user-attachments/assets/e8e6bae2-1825-4132-9f78-385dbda31a61) |
  | ![image](https://github.com/user-attachments/assets/fac6e70f-1ebb-407b-bd16-85ea8ebef84f) | ![image](https://github.com/user-attachments/assets/b8f1d5f8-63a1-4e50-8314-0bc29000959a) |

  * Based on review suggestions given ([comment](#6831 (comment))), [bitcoin-core/gui#497](bitcoin-core/gui#497) was also backported to allow arbitrary font specification. This also allowed us to offer a "Use existing font" option that _doesn't_ use any monospace font but instead inherits whatever font is used in the rest of the application. This is set as the default ([source](https://github.com/kwvg/dash/blob/89aa2c4b2390ada504fd5b45e16d2cd379074138/src/qt/optionsmodel.cpp#L73)), rendering monospace balance counters opt-in.

  * Unlike Bitcoin, Dash has a dedicated appearance widget for managing font settings specifically. We have opted to deviate from upstream by moving the money font control from "Display" to "Appearance" for the sake of consistency.

  * We set the money font when setting the wallet model as client model updates happen after the UI is visible to the user while wallet model updates happen _before_, there is little point in setting them to any values in the constructor as during construction, we don't have access to the options model and thus don't know _what_ font is supposed to be used to begin with.

  * If a font is passed through the command line, it is considered "selectable" ([source](https://github.com/kwvg/dash/blob/89aa2c4b2390ada504fd5b45e16d2cd379074138/src/qt/bitcoin.cpp#L676-L679)) because we still need to populate that font in the drop-down menu so that we don't report stale data. Though, the font cannot be _set_ to that overridden value because command-line overridden controls are auto-disabled to prevent settings corruption (see 2f30002), which makes the "selectable" state more-or-less an internal detail.

    An example is that the user tries to run Dash Core, the embedded monospace font, Roboto Mono, is _not_ a selectable font (i.e. you cannot ordinarily set your client to use Roboto Mono, see below).

    <details>

    <summary>Screenshot:</summary>

    ![image](https://github.com/user-attachments/assets/cf005084-c184-4c61-8d37-4106102108f1)

    </details>

    But if an override is done, it will be respected, the client will start with Roboto Mono and the selectable status will be overwritten so that it is presented in the drop-down menu, albeit, with the menu disabled so it doesn't contaminate UI settings.

    <details>

    <summary>Screenshot:</summary>

    ![image](https://github.com/user-attachments/assets/a4479dc3-60e0-4c8b-bf41-f89ce2012539)

    </details>

  ## Breaking Changes

  None expected.

  ## Checklist

  - [x] I have performed a self-review of my own code
  - [x] I have commented my code, particularly in hard-to-understand areas
  - [x] I have added or updated relevant unit/integration/functional/e2e tests **(note: N/A)**
  - [x] I have made corresponding changes to the documentation **(note: N/A)**
  - [x] I have assigned this pull request to a milestone _(for repository code-owners and collaborators only)_

ACKs for top commit:
  UdjinM6:
    ACK 636e7a6

Tree-SHA512: a8b23c14aec0ccac126bdc7a6db0a4583da3bda52e02f72d213431bbaa80c633a432ed02c4a33d71e3e4d2503d076624196c3e6e50c9bb7fd8e3b50ae4e9ec35
PastaPastaPasta added a commit that referenced this pull request Jan 5, 2026
…603 (migrate some QSettings to settings.json)

076ce3d fix: only reset GUI-managed settings in -resetguisettings (Kittywhiskers Van Gogh)
0c3b224 merge bitcoin-core/gui#603: Add settings.json prune-prev, proxy-prev, onion-prev settings (Kittywhiskers Van Gogh)
45976c7 merge bitcoin-core/gui#701: Persist Mask Values option (Kittywhiskers Van Gogh)
e429437 qt: migrate `-font-weight-bold` from QSettings to settings.json (Kittywhiskers Van Gogh)
70ff8ef qt: migrate `-font-weight-normal` from QSettings to settings.json (Kittywhiskers Van Gogh)
c3a5ba1 qt: migrate `-font-scale` setting from QSettings to settings.json (Kittywhiskers Van Gogh)
a5b5ede qt: migrate `-font-family` setting from QSettings to settings.json (Kittywhiskers Van Gogh)
2bb8106 qt: migrate `-enablecoinjoin` setting from QSettings to settings.json (Kittywhiskers Van Gogh)
da15040 qt: migrate `-coinjoindenomshardcap` setting from QSettings to settings.json (Kittywhiskers Van Gogh)
4f744c2 qt: migrate `-coinjoindenomsgoal` setting from QSettings to settings.json (Kittywhiskers Van Gogh)
ea60d79 qt: migrate `-coinjoinmultisession` setting from QSettings to settings.json (Kittywhiskers Van Gogh)
fb97375 qt: migrate `-coinjoinamount` setting from QSettings to settings.json (Kittywhiskers Van Gogh)
2174fc6 qt: migrate `-coinjoinrounds` setting from QSettings to settings.json (Kittywhiskers Van Gogh)
44833d9 qt: migrate `-coinjoinsessions` setting from QSettings to settings.json (Kittywhiskers Van Gogh)
eed631a refactor: spin-off list of option IDs that require string workaround (Kittywhiskers Van Gogh)
dd21992 merge bitcoin-core/gui#602: Unify bitcoin-qt and bitcoind persistent settings (Kittywhiskers Van Gogh)
d7cc771 qt: move Prune{,Size} handling outside `ENABLE_WALLET` gate (Kittywhiskers Van Gogh)
bb2efec qt: remove PrivateSend -> CoinJoin migration logic, remove old values (Kittywhiskers Van Gogh)
4fc25af merge bitcoin-core/gui#601: Pass interfaces::Node references to OptionsModel constructor (Kittywhiskers Van Gogh)
6c9f1ae merge bitcoin-core/gui#600: Add OptionsModel getOption/setOption methods (Kittywhiskers Van Gogh)

Pull request description:

  ## Additional Information

  * Depends on #6901

  * Depends on #7068

  * Depends on #6831

  ## Breaking Changes

  See release notes.

  ## Checklist

  - [x] I have performed a self-review of my own code
  - [x] I have commented my code, particularly in hard-to-understand areas
  - [x] I have added or updated relevant unit/integration/functional/e2e tests
  - [x] I have made corresponding changes to the documentation
  - [x] I have assigned this pull request to a milestone _(for repository code-owners and collaborators only)_

ACKs for top commit:
  UdjinM6:
    ACK 076ce3d

Tree-SHA512: 5ee94e3fbad13792fa01ae4269f2184356a9359aba9ee1e0b0d5195fa1c32febeed56d41aa2add121c1cbc5d20dc0305bf3a617dea0c8eb35e92b29fd2974f42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants