Skip to content

qt: add Tahoe styled icons for macOS, runtime styling for each network type, update bundle icon, add mask-based tray icon, generation scripts#7180

Merged
PastaPastaPasta merged 5 commits intodashpay:developfrom
kwvg:mac_icons
Feb 27, 2026

Conversation

@kwvg
Copy link
Collaborator

@kwvg kwvg commented Feb 27, 2026

Additional Information

Runtime Icons

mainnet testnet regtest devnet
develop
This PR

Tray

develop This PR
Dark Mode
Light Mode See above

Breaking Changes

None expected.

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.1 milestone Feb 27, 2026
@github-actions
Copy link

github-actions bot commented Feb 27, 2026

✅ No Merge Conflicts Detected

This PR currently has no conflicts with other open PRs.

@coderabbitai
Copy link

coderabbitai bot commented Feb 27, 2026

Walkthrough

This change adds a macOS icon generation script (contrib/devtools/gen_macos_icons.py), registers new macOS icon resources in Qt build files (src/Makefile.qt.include and src/qt/dash.qrc), and extends NetworkStyle and BitcoinGUI to load and prefer macOS-specific window and tray icons at runtime when available. NetworkStyle gains macIconPath support, new accessors (getMacIcon, getMacTray) and platform-guarded macOS members; its constructor signature is updated. BitcoinGUI selects macOS-specific icons on macOS when present. The script validates inputs, requires macOS tools (sips, iconutil), generates PNGs and an ICNS bundle, and places outputs for use by the Qt resources.

Sequence Diagram(s)

sequenceDiagram
    participant DevTools as gen_macos_icons.py
    participant SIPS as sips (system)
    participant ICONUTIL as iconutil (system)
    participant FS as Filesystem

    DevTools->>FS: Validate source assets (SVG/PNG)
    DevTools->>FS: Create output dirs / tmp iconset
    DevTools->>SIPS: Resample/pad PNGs (multiple sizes)
    SIPS-->>FS: Write PNG outputs
    DevTools->>SIPS: Convert SVG -> PNG for tray sizes
    SIPS-->>FS: Write tray PNGs
    DevTools->>ICONUTIL: Generate .icns from iconset
    ICONUTIL-->>FS: Write .icns bundle
    DevTools->>FS: Place generated assets into resources
Loading
sequenceDiagram
    participant App as Application
    participant NS as NetworkStyle
    participant BG as BitcoinGUI
    participant Qt as Qt Icon System

    App->>NS: Instantiate (with macIconPath)
    NS->>NS: Load macOS icons (m_macos_icon, m_macos_tray) if on macOS
    App->>BG: Create BitcoinGUI
    BG->>NS: getTrayAndWindowIcon()
    NS-->>BG: Return base icon
    alt On macOS and mac icons present
        BG->>NS: getMacIcon() / getMacTray()
        NS-->>BG: Return macOS icons
        BG->>Qt: Set window and tray icons to macOS variants
    else
        BG->>Qt: Set window and tray icons to base icon
    end
    Qt-->>App: Display icons
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title comprehensively summarizes the main changes: adding Tahoe-styled macOS icons, runtime styling per network type, bundle icon updates, mask-based tray icons, and generation scripts.
Description check ✅ Passed The description is directly related to the changeset, providing visual comparisons of runtime icons across network types, tray icon improvements, and confirming no breaking changes.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 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: 1

Caution

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

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

103-114: ⚠️ Potential issue | 🟠 Major

titleAddText fallback is currently being bypassed.

The local titleAddText declared on Line 109 shadows the fallback value from Line 103, so non-mainnet suffixes can be unintentionally dropped.

Suggested fix
-    std::string titleAddText = networkId == CBaseChainParams::MAIN ? "" : strprintf("[%s]", networkId);
     for (const auto& network_style : network_styles)
     {
         if (networkId == network_style.networkId)
         {
             std::string appName = network_style.appName;
-            std::string titleAddText = network_style.titleAddText;
+            std::string titleAddText = network_style.titleAddText.empty()
+                ? (networkId == CBaseChainParams::MAIN ? "" : strprintf("[%s]", networkId))
+                : network_style.titleAddText;
 
             if (networkId == CBaseChainParams::DEVNET.c_str()) {
                 appName = strprintf(appName, gArgs.GetDevNetName());
                 titleAddText = strprintf(titleAddText, gArgs.GetDevNetName());
             }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/qt/networkstyle.cpp` around lines 103 - 114, The local declaration of
titleAddText inside the loop shadows the fallback titleAddText defined above,
causing the fallback suffix to be lost; remove the inner "std::string" so you
assign to the outer titleAddText (i.e. change the inner "std::string
titleAddText" to "titleAddText = ...") when matching network_styles in the loop
(use the existing titleAddText variable alongside appName and handle the DEVNET
branch with gArgs.GetDevNetName() to format both appName and titleAddText).
🧹 Nitpick comments (1)
src/qt/networkstyle.cpp (1)

93-97: Only set macOS icon optionals when resources actually load.

Right now optionals are engaged even for null pixmaps, which can block fallback icons with an empty icon object.

Suggested hardening
 `#ifdef` Q_OS_MAC
     if (_macIconPath) {
-        m_macos_icon = QIcon(QPixmap(_macIconPath));
+        const QPixmap mac_icon_pixmap(_macIconPath);
+        if (!mac_icon_pixmap.isNull()) {
+            m_macos_icon = QIcon(mac_icon_pixmap);
+        }
     }
-    m_macos_tray = QIcon(QPixmap(":/icons/dash_macos_tray"));
-    m_macos_tray->setIsMask(true);
+    const QPixmap tray_pixmap(":/icons/dash_macos_tray");
+    if (!tray_pixmap.isNull()) {
+        m_macos_tray = QIcon(tray_pixmap);
+        m_macos_tray->setIsMask(true);
+    }
 `#endif` // Q_OS_MAC
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/qt/networkstyle.cpp` around lines 93 - 97, Only assign and modify the
macOS icon optionals when the QPixmap actually loaded: create a QPixmap from
_macIconPath and only set m_macos_icon = QIcon(pixmap) if !pixmap.isNull();
likewise create a QPixmap for the resource ":/icons/dash_macos_tray" and only
set m_macos_tray (and call setIsMask(true) on it) if that pixmap is not null;
this avoids constructing empty QIcon objects that block fallbacks. Ensure you
reference the existing symbols _macIconPath, m_macos_icon, m_macos_tray, QPixmap
and setIsMask when making the checks and assignments.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@contrib/devtools/gen_macos_icons.py`:
- Around line 87-90: The script currently validates ICONS but not the TRAY
source (variable TRAY / path built with DIR_SRC), so add the same existence
check used for ICONS: before any sips/processing steps (both where the ICONS
loop runs and the later block around the TRAY usage), call os.path.join(DIR_SRC,
TRAY), verify os.path.isfile(...) and call sys.exit with a clear error message
like "Error: Tray source not found: <path>" if missing; update both locations
that use TRAY to perform this pre-check so the script fails fast with a clear
message instead of later sips errors.

---

Outside diff comments:
In `@src/qt/networkstyle.cpp`:
- Around line 103-114: The local declaration of titleAddText inside the loop
shadows the fallback titleAddText defined above, causing the fallback suffix to
be lost; remove the inner "std::string" so you assign to the outer titleAddText
(i.e. change the inner "std::string titleAddText" to "titleAddText = ...") when
matching network_styles in the loop (use the existing titleAddText variable
alongside appName and handle the DEVNET branch with gArgs.GetDevNetName() to
format both appName and titleAddText).

---

Nitpick comments:
In `@src/qt/networkstyle.cpp`:
- Around line 93-97: Only assign and modify the macOS icon optionals when the
QPixmap actually loaded: create a QPixmap from _macIconPath and only set
m_macos_icon = QIcon(pixmap) if !pixmap.isNull(); likewise create a QPixmap for
the resource ":/icons/dash_macos_tray" and only set m_macos_tray (and call
setIsMask(true) on it) if that pixmap is not null; this avoids constructing
empty QIcon objects that block fallbacks. Ensure you reference the existing
symbols _macIconPath, m_macos_icon, m_macos_tray, QPixmap and setIsMask when
making the checks and assignments.

ℹ️ Review info

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e6e9a3e and 171af5b.

⛔ Files ignored due to path filters (11)
  • src/qt/res/icons/dash_macos_devnet.png is excluded by !**/*.png
  • src/qt/res/icons/dash_macos_mainnet.png is excluded by !**/*.png
  • src/qt/res/icons/dash_macos_regtest.png is excluded by !**/*.png
  • src/qt/res/icons/dash_macos_testnet.png is excluded by !**/*.png
  • src/qt/res/icons/dash_macos_tray.png is excluded by !**/*.png
  • src/qt/res/icons/dash_macos_tray@2x.png is excluded by !**/*.png
  • src/qt/res/src/macos_devnet.png is excluded by !**/*.png
  • src/qt/res/src/macos_mainnet.png is excluded by !**/*.png
  • src/qt/res/src/macos_regtest.png is excluded by !**/*.png
  • src/qt/res/src/macos_testnet.png is excluded by !**/*.png
  • src/qt/res/src/tray.svg is excluded by !**/*.svg
📒 Files selected for processing (7)
  • contrib/devtools/gen_macos_icons.py
  • src/Makefile.qt.include
  • src/qt/bitcoingui.cpp
  • src/qt/dash.qrc
  • src/qt/networkstyle.cpp
  • src/qt/networkstyle.h
  • src/qt/res/icons/dash.icns

@UdjinM6
Copy link

UdjinM6 commented Feb 27, 2026

pls see 418b955 and 93ac9aa

@kwvg
Copy link
Collaborator Author

kwvg commented Feb 27, 2026

@UdjinM6 the icons were intentionally taken at double the usual export resolution without any compression to compensate for not uploading the Icon Composer files themselves, keeping around a higher fidelity copy if a future 1024@2x output is required (essentially, 2048px), remaining changes squashed in.

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

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/qt/networkstyle.cpp`:
- Around line 93-97: The code unconditionally constructs and stores QIcon
optionals (m_macos_icon, m_macos_tray) from QPixmap resources and then calls
setIsMask on the tray icon, but it doesn't check for failed loads; update the
logic to load QPixmap from _macIconPath and from ":/icons/dash_macos_tray", call
isNull() on each QPixmap, and only emplace the corresponding optional
(m_macos_icon, m_macos_tray) when the pixmap is valid; after emplacing
m_macos_tray, then call setIsMask(true) on the stored QIcon (not on a
possibly-empty optional) so setIsMask is only invoked after a successful load.

ℹ️ Review info

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 171af5b and accfa41.

⛔ Files ignored due to path filters (3)
  • src/qt/res/icons/dash_macos_tray.png is excluded by !**/*.png
  • src/qt/res/icons/dash_macos_tray@2x.png is excluded by !**/*.png
  • src/qt/res/src/tray.svg is excluded by !**/*.svg
📒 Files selected for processing (6)
  • contrib/devtools/gen_macos_icons.py
  • src/Makefile.qt.include
  • src/qt/bitcoingui.cpp
  • src/qt/dash.qrc
  • src/qt/networkstyle.cpp
  • src/qt/networkstyle.h
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/Makefile.qt.include
  • src/qt/bitcoingui.cpp

Comment on lines +93 to +97
if (_macIconPath) {
m_macos_icon = QIcon(QPixmap(_macIconPath));
}
m_macos_tray = QIcon(QPixmap(":/icons/dash_macos_tray"));
m_macos_tray->setIsMask(true);
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# First, let's examine the networkstyle.cpp file around the specified lines
head -120 src/qt/networkstyle.cpp | tail -40

Repository: dashpay/dash

Length of output: 1630


🏁 Script executed:

# Get the complete context around lines 93-97
sed -n '80,110p' src/qt/networkstyle.cpp

Repository: dashpay/dash

Length of output: 1217


🏁 Script executed:

# Check the getter implementations for the macOS icons
rg -n 'getMacIcon|getMacTray|m_macos_icon|m_macos_tray' src/qt/networkstyle.cpp -A 3

Repository: dashpay/dash

Length of output: 257


🏁 Script executed:

# Run the verification scripts from the review comment to see how icons are consumed
rg -nP -C3 '\bgetMacIcon\s*\(|\bgetMacTray\s*\(' --type=cpp --type=h src/qt

Repository: dashpay/dash

Length of output: 1409


🏁 Script executed:

# Check if call sites verify isNull before using the icons
rg -nP -C3 '\bisNull\s*\(\)' --type=cpp --type=h src/qt

Repository: dashpay/dash

Length of output: 4222


🏁 Script executed:

# Check the header file to understand the optional types and getter signatures
rg -n 'getMacIcon|getMacTray|m_macos_icon|m_macos_tray' src/qt/networkstyle.h -B 2 -A 2

Repository: dashpay/dash

Length of output: 476


Guard against null icon loads before populating optionals.

At Line 93-97, icon load success is not validated. If resource loading fails, QIcon instances are created with null pixmaps but still stored in the optional, allowing has_value() checks at call sites (bitcoingui.cpp:122, 1126) to incorrectly treat failed loads as success. Additionally, Line 97 calls ->setIsMask(true) on the unconditionally-stored optional, relying on undefined behavior if loading fails.

Validate icon state with isNull() before populating the optionals, and defer non-default operations (e.g., setIsMask) until after successful load.

Proposed hardening patch
 `#ifdef` Q_OS_MACOS
-    if (_macIconPath) {
-        m_macos_icon = QIcon(QPixmap(_macIconPath));
+    if (_macIconPath) {
+        const QIcon mac_icon(QString::fromUtf8(_macIconPath));
+        if (!mac_icon.isNull()) {
+            m_macos_icon = mac_icon;
+        }
     }
-    m_macos_tray = QIcon(QPixmap(":/icons/dash_macos_tray"));
-    m_macos_tray->setIsMask(true);
+    const QIcon mac_tray_icon(QStringLiteral(":/icons/dash_macos_tray"));
+    if (!mac_tray_icon.isNull()) {
+        mac_tray_icon.setIsMask(true);
+        m_macos_tray = mac_tray_icon;
+    }
 `#endif` // Q_OS_MACOS
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (_macIconPath) {
m_macos_icon = QIcon(QPixmap(_macIconPath));
}
m_macos_tray = QIcon(QPixmap(":/icons/dash_macos_tray"));
m_macos_tray->setIsMask(true);
`#ifdef` Q_OS_MACOS
if (_macIconPath) {
const QIcon mac_icon(QString::fromUtf8(_macIconPath));
if (!mac_icon.isNull()) {
m_macos_icon = mac_icon;
}
}
QIcon mac_tray_icon(QStringLiteral(":/icons/dash_macos_tray"));
if (!mac_tray_icon.isNull()) {
mac_tray_icon.setIsMask(true);
m_macos_tray = mac_tray_icon;
}
`#endif` // Q_OS_MACOS
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/qt/networkstyle.cpp` around lines 93 - 97, The code unconditionally
constructs and stores QIcon optionals (m_macos_icon, m_macos_tray) from QPixmap
resources and then calls setIsMask on the tray icon, but it doesn't check for
failed loads; update the logic to load QPixmap from _macIconPath and from
":/icons/dash_macos_tray", call isNull() on each QPixmap, and only emplace the
corresponding optional (m_macos_icon, m_macos_tray) when the pixmap is valid;
after emplacing m_macos_tray, then call setIsMask(true) on the stored QIcon (not
on a possibly-empty optional) so setIsMask is only invoked after a successful
load.

@UdjinM6
Copy link

UdjinM6 commented Feb 27, 2026

@UdjinM6 the icons were intentionally taken at double the usual export resolution without any compression to compensate for not uploading the Icon Composer files themselves, keeping around a higher fidelity copy if a future 1024@2x output is required (essentially, 2048px), remaining changes squashed in.

consider 00a6205 then

@kwvg kwvg requested review from UdjinM6 and removed request for UdjinM6 February 27, 2026 17:06
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.

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

92-98: ⚠️ Potential issue | 🟡 Minor

Guard against null icon loads before populating optionals.

The current implementation stores QIcon instances in the optionals without verifying the underlying QPixmap loaded successfully. If resource loading fails, has_value() checks at call sites will pass but return a null icon.

Proposed fix to validate icon loads
 `#ifdef` Q_OS_MACOS
     if (_macIconPath) {
-        m_macos_icon = QIcon(QPixmap(_macIconPath));
+        QIcon mac_icon(QPixmap(_macIconPath));
+        if (!mac_icon.isNull()) {
+            m_macos_icon = mac_icon;
+        }
+    }
+    {
+        QIcon mac_tray(QPixmap(":/icons/dash_macos_tray"));
+        if (!mac_tray.isNull()) {
+            mac_tray.setIsMask(true);
+            m_macos_tray = mac_tray;
+        }
     }
-    m_macos_tray = QIcon(QPixmap(":/icons/dash_macos_tray"));
-    m_macos_tray->setIsMask(true);
 `#endif` // Q_OS_MACOS
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/qt/networkstyle.cpp` around lines 92 - 98, The code stores QIcon
instances into optionals (m_macos_icon, m_macos_tray) without checking that the
underlying QPixmap actually loaded, so has_value() can be true but hold a null
icon; update the Q_OS_MACOS block to first construct QPixmap objects from
_macIconPath and the resource string, check pixmap.isNull() before creating and
assigning QIcon to m_macos_icon or m_macos_tray, and only call setIsMask(true)
on m_macos_tray after verifying the icon was created successfully.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@src/qt/networkstyle.cpp`:
- Around line 92-98: The code stores QIcon instances into optionals
(m_macos_icon, m_macos_tray) without checking that the underlying QPixmap
actually loaded, so has_value() can be true but hold a null icon; update the
Q_OS_MACOS block to first construct QPixmap objects from _macIconPath and the
resource string, check pixmap.isNull() before creating and assigning QIcon to
m_macos_icon or m_macos_tray, and only call setIsMask(true) on m_macos_tray
after verifying the icon was created successfully.

ℹ️ Review info

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between accfa41 and 54cde9b.

⛔ Files ignored due to path filters (11)
  • src/qt/res/icons/dash_macos_devnet.png is excluded by !**/*.png
  • src/qt/res/icons/dash_macos_mainnet.png is excluded by !**/*.png
  • src/qt/res/icons/dash_macos_regtest.png is excluded by !**/*.png
  • src/qt/res/icons/dash_macos_testnet.png is excluded by !**/*.png
  • src/qt/res/icons/dash_macos_tray.png is excluded by !**/*.png
  • src/qt/res/icons/dash_macos_tray@2x.png is excluded by !**/*.png
  • src/qt/res/src/macos_devnet.png is excluded by !**/*.png
  • src/qt/res/src/macos_mainnet.png is excluded by !**/*.png
  • src/qt/res/src/macos_regtest.png is excluded by !**/*.png
  • src/qt/res/src/macos_testnet.png is excluded by !**/*.png
  • src/qt/res/src/tray.svg is excluded by !**/*.svg
📒 Files selected for processing (7)
  • contrib/devtools/gen_macos_icons.py
  • src/Makefile.qt.include
  • src/qt/bitcoingui.cpp
  • src/qt/dash.qrc
  • src/qt/networkstyle.cpp
  • src/qt/networkstyle.h
  • src/qt/res/icons/dash.icns
🚧 Files skipped from review as they are similar to previous changes (4)
  • src/Makefile.qt.include
  • src/qt/dash.qrc
  • src/qt/networkstyle.h
  • src/qt/bitcoingui.cpp

Copy link
Member

@PastaPastaPasta PastaPastaPasta left a comment

Choose a reason for hiding this comment

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

utACK 54cde9b

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.

utACK 54cde9b

@PastaPastaPasta PastaPastaPasta merged commit 4000876 into dashpay:develop Feb 27, 2026
43 of 46 checks passed
thepastaclaw pushed a commit to thepastaclaw/dash that referenced this pull request Feb 27, 2026
…ling for each network type, update bundle icon, add mask-based tray icon, generation scripts

54cde9b qt: drop unused networkId param in `networkstyle.{cpp,h}` (UdjinM6)
6c23752 qt: generate tray icons for macOS, update script, set at runtime (Kittywhiskers Van Gogh)
4a1e939 qt: apply new runtime icons if running on macOS (Kittywhiskers Van Gogh)
3bc2ee6 qt: generate macOS icon assets, commit resizing and creation script (Kittywhiskers Van Gogh)
0bef769 res: add 8-bit color Icon Composer exports for Tahoe styled icons (Kittywhiskers Van Gogh)

Pull request description:

  ## Additional Information

  ### Runtime Icons

  |  | mainnet | testnet | regtest | devnet |
  |-|-|-|-|-|
  | **`develop`** | ![](https://github.com/user-attachments/assets/85aebf23-6f62-44a6-95ae-36ed95d427e3) | ![](https://github.com/user-attachments/assets/f1c59195-5197-4eae-b5ac-ce44998ccecb) | ![](https://github.com/user-attachments/assets/5f6ed3de-dfe8-4e62-90eb-a8e4733ab206) | ![](https://github.com/user-attachments/assets/19df389a-e551-4c45-8290-5fbba96a282f) |
  | **This PR** | ![](https://github.com/user-attachments/assets/82446f92-d703-4588-8659-9ed135504a30) | ![](https://github.com/user-attachments/assets/1f679583-dfae-4c98-b2fb-722bd91dd959) | ![](https://github.com/user-attachments/assets/e00894f7-ad79-4731-8223-f7a447930d6c) | ![](https://github.com/user-attachments/assets/d2691dc4-cf0d-4473-94d2-60f6d608e4c8) |

  ### Tray

  |   | `develop` | This PR |
  | - | -------- | ------- |
  | **Dark Mode** | ![](https://github.com/user-attachments/assets/93f4988f-e2fa-4f8e-a8d4-8a24577b2c93) | ![](https://github.com/user-attachments/assets/78c3eb86-531c-4125-9739-c6ffe3273f43) |
  | **Light Mode** | See above | ![](https://github.com/user-attachments/assets/4e540e9c-775f-43d1-953b-e6a155afed95) |

  ## 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:
  PastaPastaPasta:
    utACK 54cde9b
  UdjinM6:
    utACK 54cde9b

Tree-SHA512: af23ab7558b724f192f9b4107cbbbe60098274feec53e31e0b4a8e964ae8a05c64315247c8a3a46ae3ef1e957b3301bed12dad69adfbb8c498862ebbb530a87a
PastaPastaPasta added a commit that referenced this pull request Mar 3, 2026
00f590d Merge #7180: qt: add Tahoe styled icons for macOS, runtime styling for each network type, update bundle icon, add mask-based tray icon, generation scripts (pasta)
60dda51 Merge #7176: perf: do linear lookup instead building 2 heavy Hash-Maps (pasta)
df1ca87 Merge #7159: feat(qt): UI refresh (5/n, add proposal information widget to information, donut chart for proposal allocation) (pasta)
9061ad0 Merge #7118: feat(qt): UI refresh (4/n, introduce distinct widgets for Dash-specific reporting in debug window) (pasta)
64cc4f2 Merge #7160: feat(interfaces): consolidate masternode counts into one struct, expose chainlock, instantsend, credit pool, quorum statistics (pasta)
5d28a69 Merge #7157: fix(qt): prevent banned masternodes from returning status=0 (pasta)
e0b7386 Merge #7146: feat(qt): introduce framework for sourcing and applying data, use for `{Masternode,Proposal}List`s (pasta)
8fd53cd Merge #7144: feat(qt): add support for reporting `OP_RETURN` payloads as Data Transactions (pasta)
cc6f0bb Merge #7154: fix: MN update notifications had old_list/new_list swapped (pasta)
33f0138 Merge #7145: fix(qt): move labelError styling from proposalcreate.ui into general.css (pasta)
1bdbde6 Merge #7148: feat(qt): persist filter preferences in masternode list (pasta)
96bb601 Merge #7147: fix(qt): prevent overview page font double scaling, recalculate minimum width correctly, `SERVICE` and `STATUS` sorting, fix common types filtering (pasta)

Pull request description:

  ## Backport PRs for v23.1.1

  Cherry-picks the following 12 PRs (labeled `backport-candidate-23.1.x`) from `develop` onto `v23.1.x`, in merge order:

  | PR | Title |
  |---|---|
  | #7147 | fix(qt): prevent overview page font double scaling, recalculate minimum width correctly, `SERVICE` and `STATUS` sorting, fix common types filtering |
  | #7148 | feat(qt): persist filter preferences in masternode list |
  | #7145 | fix(qt): move labelError styling from proposalcreate.ui into general.css |
  | #7154 | fix: MN update notifications had old_list/new_list swapped |
  | #7144 | feat(qt): add support for reporting `OP_RETURN` payloads as Data Transactions |
  | #7146 | feat(qt): introduce framework for sourcing and applying data, use for `{Masternode,Proposal}List`s |
  | #7157 | fix(qt): prevent banned masternodes from returning status=0 |
  | #7160 | feat(interfaces): consolidate masternode counts into one struct, expose chainlock, instantsend, credit pool, quorum statistics |
  | #7118 | feat(qt): UI refresh (4/n, introduce distinct widgets for Dash-specific reporting in debug window) |
  | #7159 | feat(qt): UI refresh (5/n, add proposal information widget to information, donut chart for proposal allocation) |
  | #7176 | perf: do linear lookup instead building 2 heavy Hash-Maps |
  | #7180 | qt: add Tahoe styled icons for macOS, runtime styling for each network type, update bundle icon, add mask-based tray icon, generation scripts |

  All 12 cherry-picked cleanly (no conflicts).

  ## Notes
  - Used `git cherry-pick -m 1 <merge-sha>` for each (all were merge commits on develop)
  - Applied in chronological merge order to respect dependency chains
  - Version bump and release notes are separate steps per the release process

ACKs for top commit:
  kwvg:
    utACK 00f590d
  UdjinM6:
    utACK 00f590d

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants