From ce17861dc419b0d1fc1d933000f484dd08bacf5b Mon Sep 17 00:00:00 2001
From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com>
Date: Wed, 7 Apr 2021 09:29:57 +0300
Subject: [PATCH 01/12] qt: Make PlatformStyle aware of runtime palette change

This change is a prerequisite to support changeable appearance on macOS.
---
 src/qt/platformstyle.cpp | 27 +++++++++++++++------------
 src/qt/platformstyle.h   |  7 ++-----
 2 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/src/qt/platformstyle.cpp b/src/qt/platformstyle.cpp
index 1d0605c9030..2257c2ad4f6 100644
--- a/src/qt/platformstyle.cpp
+++ b/src/qt/platformstyle.cpp
@@ -71,25 +71,28 @@ PlatformStyle::PlatformStyle(const QString &_name, bool _imagesOnButtons, bool _
     name(_name),
     imagesOnButtons(_imagesOnButtons),
     colorizeIcons(_colorizeIcons),
-    useExtraSpacing(_useExtraSpacing),
-    singleColor(0,0,0),
-    textColor(0,0,0)
+    useExtraSpacing(_useExtraSpacing)
+{
+}
+
+QColor PlatformStyle::TextColor() const
+{
+    return QApplication::palette().color(QPalette::WindowText);
+}
+
+QColor PlatformStyle::SingleColor() const
 {
-    // Determine icon highlighting color
     if (colorizeIcons) {
         const QColor colorHighlightBg(QApplication::palette().color(QPalette::Highlight));
         const QColor colorHighlightFg(QApplication::palette().color(QPalette::HighlightedText));
         const QColor colorText(QApplication::palette().color(QPalette::WindowText));
         const int colorTextLightness = colorText.lightness();
-        QColor colorbase;
-        if (abs(colorHighlightBg.lightness() - colorTextLightness) < abs(colorHighlightFg.lightness() - colorTextLightness))
-            colorbase = colorHighlightBg;
-        else
-            colorbase = colorHighlightFg;
-        singleColor = colorbase;
+        if (abs(colorHighlightBg.lightness() - colorTextLightness) < abs(colorHighlightFg.lightness() - colorTextLightness)) {
+            return colorHighlightBg;
+        }
+        return colorHighlightFg;
     }
-    // Determine text color
-    textColor = QColor(QApplication::palette().color(QPalette::WindowText));
+    return {0, 0, 0};
 }
 
 QImage PlatformStyle::SingleColorImage(const QString& filename) const
diff --git a/src/qt/platformstyle.h b/src/qt/platformstyle.h
index 53632e56e2e..9df0a1f9854 100644
--- a/src/qt/platformstyle.h
+++ b/src/qt/platformstyle.h
@@ -21,8 +21,8 @@ class PlatformStyle
     bool getImagesOnButtons() const { return imagesOnButtons; }
     bool getUseExtraSpacing() const { return useExtraSpacing; }
 
-    QColor TextColor() const { return textColor; }
-    QColor SingleColor() const { return singleColor; }
+    QColor TextColor() const;
+    QColor SingleColor() const;
 
     /** Colorize an image (given filename) with the icon color */
     QImage SingleColorImage(const QString& filename) const;
@@ -43,9 +43,6 @@ class PlatformStyle
     bool imagesOnButtons;
     bool colorizeIcons;
     bool useExtraSpacing;
-    QColor singleColor;
-    QColor textColor;
-    /* ... more to come later */
 };
 
 #endif // BITCOIN_QT_PLATFORMSTYLE_H

From f1083826e3e68803da86af6efba21c4080769b5c Mon Sep 17 00:00:00 2001
From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com>
Date: Wed, 7 Apr 2021 09:50:26 +0300
Subject: [PATCH 02/12] qt: Make BitcoinGUI aware of runtime palette change

This change fixes the GUI when changing appearance on macOS.
---
 src/qt/bitcoingui.cpp | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp
index 3e29d8e1326..48fc09bfdf3 100644
--- a/src/qt/bitcoingui.cpp
+++ b/src/qt/bitcoingui.cpp
@@ -1138,7 +1138,17 @@ void BitcoinGUI::message(const QString& title, QString message, unsigned int sty
 
 void BitcoinGUI::changeEvent(QEvent *e)
 {
+#ifdef Q_OS_MACOS
+    if (e->type() == QEvent::PaletteChange) {
+        overviewAction->setIcon(platformStyle->SingleColorIcon(QStringLiteral(":/icons/overview")));
+        sendCoinsAction->setIcon(platformStyle->SingleColorIcon(QStringLiteral(":/icons/send")));
+        receiveCoinsAction->setIcon(platformStyle->SingleColorIcon(QStringLiteral(":/icons/receiving_addresses")));
+        historyAction->setIcon(platformStyle->SingleColorIcon(QStringLiteral(":/icons/history")));
+    }
+#endif
+
     QMainWindow::changeEvent(e);
+
 #ifndef Q_OS_MAC // Ignored on Mac
     if(e->type() == QEvent::WindowStateChange)
     {

From fa18d28e1242c2948814df1082ee12c2fecf5403 Mon Sep 17 00:00:00 2001
From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com>
Date: Thu, 8 Apr 2021 12:17:05 +0300
Subject: [PATCH 03/12] qt: Make RPCConsole aware of runtime palette change

This change fixes the GUI when changing appearance on macOS.
---
 src/qt/rpcconsole.cpp | 19 +++++++++++++++++++
 src/qt/rpcconsole.h   |  1 +
 2 files changed, 20 insertions(+)

diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp
index 006f60e7a1c..d5fc4b995cd 100644
--- a/src/qt/rpcconsole.cpp
+++ b/src/qt/rpcconsole.cpp
@@ -817,6 +817,25 @@ void RPCConsole::keyPressEvent(QKeyEvent *event)
     }
 }
 
+void RPCConsole::changeEvent(QEvent* e)
+{
+#ifdef Q_OS_MACOS
+    if (e->type() == QEvent::PaletteChange) {
+        ui->clearButton->setIcon(platformStyle->SingleColorIcon(QStringLiteral(":/icons/remove")));
+        ui->fontBiggerButton->setIcon(platformStyle->SingleColorIcon(QStringLiteral(":/icons/fontbigger")));
+        ui->fontSmallerButton->setIcon(platformStyle->SingleColorIcon(QStringLiteral(":/icons/fontsmaller")));
+        ui->promptIcon->setIcon(platformStyle->SingleColorIcon(QStringLiteral(":/icons/prompticon")));
+
+        for (int i = 0; ICON_MAPPING[i].url; ++i) {
+            ui->messagesWidget->document()->addResource(
+                QTextDocument::ImageResource,
+                QUrl(ICON_MAPPING[i].url),
+                platformStyle->SingleColorImage(ICON_MAPPING[i].source).scaled(QSize(consoleFontSize * 2, consoleFontSize * 2), Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
+        }
+    }
+#endif
+}
+
 void RPCConsole::message(int category, const QString &message, bool html)
 {
     QTime time = QTime::currentTime();
diff --git a/src/qt/rpcconsole.h b/src/qt/rpcconsole.h
index 5182d60a0d7..7ef8b6b0f16 100644
--- a/src/qt/rpcconsole.h
+++ b/src/qt/rpcconsole.h
@@ -74,6 +74,7 @@ class RPCConsole: public QWidget
 protected:
     virtual bool eventFilter(QObject* obj, QEvent *event) override;
     void keyPressEvent(QKeyEvent *) override;
+    void changeEvent(QEvent* e) override;
 
 private Q_SLOTS:
     void on_lineEdit_returnPressed();

From 0dcc3fac433b341eb6e1d3a2fb4d2de1595e8e88 Mon Sep 17 00:00:00 2001
From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com>
Date: Thu, 8 Apr 2021 12:31:16 +0300
Subject: [PATCH 04/12] qt: Make SendCoinsEntry aware of runtime palette change

This change fixes the GUI when changing appearance on macOS.
---
 src/qt/sendcoinsentry.cpp | 13 +++++++++++++
 src/qt/sendcoinsentry.h   |  3 +++
 2 files changed, 16 insertions(+)

diff --git a/src/qt/sendcoinsentry.cpp b/src/qt/sendcoinsentry.cpp
index 444dc79a2e1..f701bb96156 100644
--- a/src/qt/sendcoinsentry.cpp
+++ b/src/qt/sendcoinsentry.cpp
@@ -236,6 +236,19 @@ void SendCoinsEntry::updateDisplayUnit()
     }
 }
 
+void SendCoinsEntry::changeEvent(QEvent* e)
+{
+#ifdef Q_OS_MACOS
+    if (e->type() == QEvent::PaletteChange) {
+        ui->addressBookButton->setIcon(platformStyle->SingleColorIcon(QStringLiteral(":/icons/address-book")));
+        ui->pasteButton->setIcon(platformStyle->SingleColorIcon(QStringLiteral(":/icons/editpaste")));
+        ui->deleteButton->setIcon(platformStyle->SingleColorIcon(QStringLiteral(":/icons/remove")));
+        ui->deleteButton_is->setIcon(platformStyle->SingleColorIcon(QStringLiteral(":/icons/remove")));
+        ui->deleteButton_s->setIcon(platformStyle->SingleColorIcon(QStringLiteral(":/icons/remove")));
+    }
+#endif
+}
+
 bool SendCoinsEntry::updateLabel(const QString &address)
 {
     if(!model)
diff --git a/src/qt/sendcoinsentry.h b/src/qt/sendcoinsentry.h
index 254cc186e20..e682e6423aa 100644
--- a/src/qt/sendcoinsentry.h
+++ b/src/qt/sendcoinsentry.h
@@ -69,6 +69,9 @@ private Q_SLOTS:
     void on_pasteButton_clicked();
     void updateDisplayUnit();
 
+protected:
+    void changeEvent(QEvent* e) override;
+
 private:
     SendCoinsRecipient recipient;
     Ui::SendCoinsEntry *ui;

From c054720e08b5549913f54b9b4bc4e4002617ff23 Mon Sep 17 00:00:00 2001
From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com>
Date: Thu, 8 Apr 2021 12:37:25 +0300
Subject: [PATCH 05/12] qt: Make SignVerifyMessageDialog aware of runtime
 palette change

This change fixes the GUI when changing appearance on macOS.
---
 src/qt/signverifymessagedialog.cpp | 16 ++++++++++++++++
 src/qt/signverifymessagedialog.h   |  1 +
 2 files changed, 17 insertions(+)

diff --git a/src/qt/signverifymessagedialog.cpp b/src/qt/signverifymessagedialog.cpp
index 2e7df605740..b982cc577dd 100644
--- a/src/qt/signverifymessagedialog.cpp
+++ b/src/qt/signverifymessagedialog.cpp
@@ -283,3 +283,19 @@ bool SignVerifyMessageDialog::eventFilter(QObject *object, QEvent *event)
     }
     return QDialog::eventFilter(object, event);
 }
+
+void SignVerifyMessageDialog::changeEvent(QEvent* e)
+{
+#ifdef Q_OS_MACOS
+    if (e->type() == QEvent::PaletteChange) {
+        ui->addressBookButton_SM->setIcon(platformStyle->SingleColorIcon(QStringLiteral(":/icons/address-book")));
+        ui->pasteButton_SM->setIcon(platformStyle->SingleColorIcon(QStringLiteral(":/icons/editpaste")));
+        ui->copySignatureButton_SM->setIcon(platformStyle->SingleColorIcon(QStringLiteral(":/icons/editcopy")));
+        ui->signMessageButton_SM->setIcon(platformStyle->SingleColorIcon(QStringLiteral(":/icons/edit")));
+        ui->clearButton_SM->setIcon(platformStyle->SingleColorIcon(QStringLiteral(":/icons/remove")));
+        ui->addressBookButton_VM->setIcon(platformStyle->SingleColorIcon(QStringLiteral(":/icons/address-book")));
+        ui->verifyMessageButton_VM->setIcon(platformStyle->SingleColorIcon(QStringLiteral(":/icons/transaction_0")));
+        ui->clearButton_VM->setIcon(platformStyle->SingleColorIcon(QStringLiteral(":/icons/remove")));
+    }
+#endif
+}
diff --git a/src/qt/signverifymessagedialog.h b/src/qt/signverifymessagedialog.h
index d98cb290a12..3d2d5f281ea 100644
--- a/src/qt/signverifymessagedialog.h
+++ b/src/qt/signverifymessagedialog.h
@@ -31,6 +31,7 @@ class SignVerifyMessageDialog : public QDialog
 
 protected:
     bool eventFilter(QObject *object, QEvent *event) override;
+    void changeEvent(QEvent* e) override;
 
 private:
     Ui::SignVerifyMessageDialog *ui;

From d99ef327a885874fed1c4e35e0f47b10290c6bd9 Mon Sep 17 00:00:00 2001
From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com>
Date: Thu, 8 Apr 2021 14:27:14 +0300
Subject: [PATCH 06/12] qt: Add GUIUtil::ThemedLabel class

The ThemedLabel class correctly handles appearance changes on macOS.
---
 src/qt/guiutil.cpp | 31 +++++++++++++++++++++++++++++++
 src/qt/guiutil.h   | 20 ++++++++++++++++++++
 2 files changed, 51 insertions(+)

diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp
index d10bf9f9aeb..3c4f3df89d0 100644
--- a/src/qt/guiutil.cpp
+++ b/src/qt/guiutil.cpp
@@ -6,6 +6,7 @@
 
 #include <qt/bitcoinaddressvalidator.h>
 #include <qt/bitcoinunits.h>
+#include <qt/platformstyle.h>
 #include <qt/qvalidatedlineedit.h>
 #include <qt/sendcoinsrecipient.h>
 
@@ -61,6 +62,7 @@
 #include <QUrlQuery>
 #include <QtGlobal>
 
+#include <cassert>
 #include <chrono>
 
 #if defined(Q_OS_MAC)
@@ -786,6 +788,35 @@ qreal calculateIdealFontSize(int width, const QString& text, QFont font, qreal m
     return font_size;
 }
 
+ThemedLabel::ThemedLabel(const PlatformStyle* platform_style, QWidget* parent)
+    : QLabel{parent}, m_platform_style{platform_style}
+{
+    assert(m_platform_style);
+}
+
+void ThemedLabel::setThemedPixmap(const QString& image_filename, int width, int height)
+{
+    m_image_filename = image_filename;
+    m_pixmap_width = width;
+    m_pixmap_height = height;
+    updateThemedPixmap();
+}
+
+void ThemedLabel::changeEvent(QEvent* e)
+{
+#ifdef Q_OS_MACOS
+    if (e->type() == QEvent::PaletteChange) {
+        updateThemedPixmap();
+    }
+#endif
+    QLabel::changeEvent(e);
+}
+
+void ThemedLabel::updateThemedPixmap()
+{
+    setPixmap(m_platform_style->SingleColorIcon(m_image_filename).pixmap(m_pixmap_width, m_pixmap_height));
+}
+
 void ClickableLabel::mouseReleaseEvent(QMouseEvent *event)
 {
     Q_EMIT clicked(event->pos());
diff --git a/src/qt/guiutil.h b/src/qt/guiutil.h
index a1cf2743549..31e7aa73355 100644
--- a/src/qt/guiutil.h
+++ b/src/qt/guiutil.h
@@ -27,6 +27,7 @@
 #include <chrono>
 #include <utility>
 
+class PlatformStyle;
 class QValidatedLineEdit;
 class SendCoinsRecipient;
 
@@ -221,6 +222,25 @@ namespace GUIUtil
 
     qreal calculateIdealFontSize(int width, const QString& text, QFont font, qreal minPointSize = 4, qreal startPointSize = 14);
 
+    class ThemedLabel : public QLabel
+    {
+        Q_OBJECT
+
+    public:
+        explicit ThemedLabel(const PlatformStyle* platform_style, QWidget* parent = nullptr);
+        void setThemedPixmap(const QString& image_filename, int width, int height);
+
+    protected:
+        void changeEvent(QEvent* e) override;
+
+    private:
+        const PlatformStyle* m_platform_style;
+        QString m_image_filename;
+        int m_pixmap_width;
+        int m_pixmap_height;
+        void updateThemedPixmap();
+    };
+
     class ClickableLabel : public QLabel
     {
         Q_OBJECT

From ff530a2093c294a1093e1b00fb66ab0a98851c04 Mon Sep 17 00:00:00 2001
From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com>
Date: Wed, 7 Apr 2021 20:30:18 +0300
Subject: [PATCH 07/12] qt: Use GUIUtil::ThemedLabel class

This change fixes the GUI when changing appearance on macOS.
---
 src/qt/bitcoingui.cpp | 10 +++++-----
 src/qt/bitcoingui.h   |  5 +++--
 2 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp
index 48fc09bfdf3..5c3f16aab09 100644
--- a/src/qt/bitcoingui.cpp
+++ b/src/qt/bitcoingui.cpp
@@ -150,8 +150,8 @@ BitcoinGUI::BitcoinGUI(interfaces::Node& node, const PlatformStyle *_platformSty
     frameBlocksLayout->setContentsMargins(3,0,3,0);
     frameBlocksLayout->setSpacing(3);
     unitDisplayControl = new UnitDisplayStatusBarControl(platformStyle);
-    labelWalletEncryptionIcon = new QLabel();
-    labelWalletHDStatusIcon = new QLabel();
+    labelWalletEncryptionIcon = new GUIUtil::ThemedLabel(platformStyle);
+    labelWalletHDStatusIcon = new GUIUtil::ThemedLabel(platformStyle);
     labelProxyIcon = new GUIUtil::ClickableLabel();
     connectionsControl = new GUIUtil::ClickableLabel();
     labelBlocksIcon = new GUIUtil::ClickableLabel();
@@ -1266,7 +1266,7 @@ bool BitcoinGUI::handlePaymentRequest(const SendCoinsRecipient& recipient)
 
 void BitcoinGUI::setHDStatus(bool privkeyDisabled, int hdEnabled)
 {
-    labelWalletHDStatusIcon->setPixmap(platformStyle->SingleColorIcon(privkeyDisabled ? ":/icons/eye" : hdEnabled ? ":/icons/hd_enabled" : ":/icons/hd_disabled").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE));
+    labelWalletHDStatusIcon->setThemedPixmap(privkeyDisabled ? QStringLiteral(":/icons/eye") : hdEnabled ? QStringLiteral(":/icons/hd_enabled") : QStringLiteral(":/icons/hd_disabled"), STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE);
     labelWalletHDStatusIcon->setToolTip(privkeyDisabled ? tr("Private key <b>disabled</b>") : hdEnabled ? tr("HD key generation is <b>enabled</b>") : tr("HD key generation is <b>disabled</b>"));
     labelWalletHDStatusIcon->show();
     // eventually disable the QLabel to set its opacity to 50%
@@ -1285,7 +1285,7 @@ void BitcoinGUI::setEncryptionStatus(int status)
         break;
     case WalletModel::Unlocked:
         labelWalletEncryptionIcon->show();
-        labelWalletEncryptionIcon->setPixmap(platformStyle->SingleColorIcon(":/icons/lock_open").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE));
+        labelWalletEncryptionIcon->setThemedPixmap(QStringLiteral(":/icons/lock_open"), STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE);
         labelWalletEncryptionIcon->setToolTip(tr("Wallet is <b>encrypted</b> and currently <b>unlocked</b>"));
         encryptWalletAction->setChecked(true);
         changePassphraseAction->setEnabled(true);
@@ -1293,7 +1293,7 @@ void BitcoinGUI::setEncryptionStatus(int status)
         break;
     case WalletModel::Locked:
         labelWalletEncryptionIcon->show();
-        labelWalletEncryptionIcon->setPixmap(platformStyle->SingleColorIcon(":/icons/lock_closed").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE));
+        labelWalletEncryptionIcon->setThemedPixmap(QStringLiteral(":/icons/lock_closed"), STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE);
         labelWalletEncryptionIcon->setToolTip(tr("Wallet is <b>encrypted</b> and currently <b>locked</b>"));
         encryptWalletAction->setChecked(true);
         changePassphraseAction->setEnabled(true);
diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h
index 147f19e68df..d1cfa547bd6 100644
--- a/src/qt/bitcoingui.h
+++ b/src/qt/bitcoingui.h
@@ -9,6 +9,7 @@
 #include <config/bitcoin-config.h>
 #endif
 
+#include <qt/guiutil.h>
 #include <qt/optionsdialog.h>
 
 #include <amount.h>
@@ -121,8 +122,8 @@ class BitcoinGUI : public QMainWindow
     WalletFrame* walletFrame = nullptr;
 
     UnitDisplayStatusBarControl* unitDisplayControl = nullptr;
-    QLabel* labelWalletEncryptionIcon = nullptr;
-    QLabel* labelWalletHDStatusIcon = nullptr;
+    GUIUtil::ThemedLabel* labelWalletEncryptionIcon = nullptr;
+    GUIUtil::ThemedLabel* labelWalletHDStatusIcon = nullptr;
     GUIUtil::ClickableLabel* labelProxyIcon = nullptr;
     GUIUtil::ClickableLabel* connectionsControl = nullptr;
     GUIUtil::ClickableLabel* labelBlocksIcon = nullptr;

From 6b2ce65392dc98250e84941370e975048b8afc54 Mon Sep 17 00:00:00 2001
From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com>
Date: Thu, 8 Apr 2021 16:14:12 +0300
Subject: [PATCH 08/12] qt: Replace base class of ClickableLabel with
 ThemedLabel

This change fixes the GUI when changing appearance on macOS.
---
 src/qt/bitcoingui.cpp | 18 +++++++++---------
 src/qt/guiutil.cpp    |  5 +++++
 src/qt/guiutil.h      |  5 ++++-
 3 files changed, 18 insertions(+), 10 deletions(-)

diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp
index 5c3f16aab09..ff5d38fb0aa 100644
--- a/src/qt/bitcoingui.cpp
+++ b/src/qt/bitcoingui.cpp
@@ -152,9 +152,9 @@ BitcoinGUI::BitcoinGUI(interfaces::Node& node, const PlatformStyle *_platformSty
     unitDisplayControl = new UnitDisplayStatusBarControl(platformStyle);
     labelWalletEncryptionIcon = new GUIUtil::ThemedLabel(platformStyle);
     labelWalletHDStatusIcon = new GUIUtil::ThemedLabel(platformStyle);
-    labelProxyIcon = new GUIUtil::ClickableLabel();
-    connectionsControl = new GUIUtil::ClickableLabel();
-    labelBlocksIcon = new GUIUtil::ClickableLabel();
+    labelProxyIcon = new GUIUtil::ClickableLabel(platformStyle);
+    connectionsControl = new GUIUtil::ClickableLabel(platformStyle);
+    labelBlocksIcon = new GUIUtil::ClickableLabel(platformStyle);
     if(enableWallet)
     {
         frameBlocksLayout->addStretch();
@@ -925,7 +925,7 @@ void BitcoinGUI::updateNetworkState()
     tooltip = QString("<nobr>") + tooltip + QString("</nobr>");
     connectionsControl->setToolTip(tooltip);
 
-    connectionsControl->setPixmap(platformStyle->SingleColorIcon(icon).pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE));
+    connectionsControl->setThemedPixmap(icon, STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE);
 }
 
 void BitcoinGUI::setNumConnections(int count)
@@ -1021,7 +1021,7 @@ void BitcoinGUI::setNumBlocks(int count, const QDateTime& blockDate, double nVer
     // Set icon state: spinning if catching up, tick otherwise
     if (secs < MAX_BLOCK_TIME_GAP) {
         tooltip = tr("Up to date") + QString(".<br>") + tooltip;
-        labelBlocksIcon->setPixmap(platformStyle->SingleColorIcon(":/icons/synced").pixmap(STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE));
+        labelBlocksIcon->setThemedPixmap(QStringLiteral(":/icons/synced"), STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE);
 
 #ifdef ENABLE_WALLET
         if(walletFrame)
@@ -1047,9 +1047,9 @@ void BitcoinGUI::setNumBlocks(int count, const QDateTime& blockDate, double nVer
         tooltip = tr("Catching up...") + QString("<br>") + tooltip;
         if(count != prevBlocks)
         {
-            labelBlocksIcon->setPixmap(platformStyle->SingleColorIcon(QString(
-                ":/animation/spinner-%1").arg(spinnerFrame, 3, 10, QChar('0')))
-                .pixmap(STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE));
+            labelBlocksIcon->setThemedPixmap(
+                QString(":/animation/spinner-%1").arg(spinnerFrame, 3, 10, QChar('0')),
+                STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE);
             spinnerFrame = (spinnerFrame + 1) % SPINNER_FRAMES;
         }
         prevBlocks = count;
@@ -1325,7 +1325,7 @@ void BitcoinGUI::updateProxyIcon()
     if (proxy_enabled) {
         if (!GUIUtil::HasPixmap(labelProxyIcon)) {
             QString ip_port_q = QString::fromStdString(ip_port);
-            labelProxyIcon->setPixmap(platformStyle->SingleColorIcon(":/icons/proxy").pixmap(STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE));
+            labelProxyIcon->setThemedPixmap((":/icons/proxy"), STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE);
             labelProxyIcon->setToolTip(tr("Proxy is <b>enabled</b>: %1").arg(ip_port_q));
         } else {
             labelProxyIcon->show();
diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp
index 3c4f3df89d0..b738d13840c 100644
--- a/src/qt/guiutil.cpp
+++ b/src/qt/guiutil.cpp
@@ -817,6 +817,11 @@ void ThemedLabel::updateThemedPixmap()
     setPixmap(m_platform_style->SingleColorIcon(m_image_filename).pixmap(m_pixmap_width, m_pixmap_height));
 }
 
+ClickableLabel::ClickableLabel(const PlatformStyle* platform_style, QWidget* parent)
+    : ThemedLabel{platform_style, parent}
+{
+}
+
 void ClickableLabel::mouseReleaseEvent(QMouseEvent *event)
 {
     Q_EMIT clicked(event->pos());
diff --git a/src/qt/guiutil.h b/src/qt/guiutil.h
index 31e7aa73355..d3d0ba64cad 100644
--- a/src/qt/guiutil.h
+++ b/src/qt/guiutil.h
@@ -241,10 +241,13 @@ namespace GUIUtil
         void updateThemedPixmap();
     };
 
-    class ClickableLabel : public QLabel
+    class ClickableLabel : public ThemedLabel
     {
         Q_OBJECT
 
+    public:
+        explicit ClickableLabel(const PlatformStyle* platform_style, QWidget* parent = nullptr);
+
     Q_SIGNALS:
         /** Emitted when the label is clicked. The relative mouse coordinates of the click are
          * passed to the signal.

From d05f1b278d9846de5142a4ac3f53c84145330dd1 Mon Sep 17 00:00:00 2001
From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com>
Date: Thu, 8 Apr 2021 19:56:16 +0300
Subject: [PATCH 09/12] qt: Make UnitDisplayStatusBarControl aware of runtime
 palette change

This change fixes the GUI when changing appearance on macOS.
---
 src/qt/bitcoingui.cpp | 21 +++++++++++++++++----
 src/qt/bitcoingui.h   |  2 ++
 2 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp
index ff5d38fb0aa..ae4db9fa806 100644
--- a/src/qt/bitcoingui.cpp
+++ b/src/qt/bitcoingui.cpp
@@ -1450,9 +1450,10 @@ bool BitcoinGUI::isPrivacyModeActivated() const
     return m_mask_values_action->isChecked();
 }
 
-UnitDisplayStatusBarControl::UnitDisplayStatusBarControl(const PlatformStyle *platformStyle) :
-    optionsModel(nullptr),
-    menu(nullptr)
+UnitDisplayStatusBarControl::UnitDisplayStatusBarControl(const PlatformStyle *platformStyle)
+    : optionsModel(nullptr),
+      menu(nullptr),
+      m_platform_style{platformStyle}
 {
     createContextMenu();
     setToolTip(tr("Unit to show amounts in. Click to select another unit."));
@@ -1465,7 +1466,7 @@ UnitDisplayStatusBarControl::UnitDisplayStatusBarControl(const PlatformStyle *pl
     }
     setMinimumSize(max_width, 0);
     setAlignment(Qt::AlignRight | Qt::AlignVCenter);
-    setStyleSheet(QString("QLabel { color : %1 }").arg(platformStyle->SingleColor().name()));
+    setStyleSheet(QString("QLabel { color : %1 }").arg(m_platform_style->SingleColor().name()));
 }
 
 /** So that it responds to button clicks */
@@ -1474,6 +1475,18 @@ void UnitDisplayStatusBarControl::mousePressEvent(QMouseEvent *event)
     onDisplayUnitsClicked(event->pos());
 }
 
+void UnitDisplayStatusBarControl::changeEvent(QEvent* e)
+{
+#ifdef Q_OS_MACOS
+    if (e->type() == QEvent::PaletteChange) {
+        QString style = QString("QLabel { color : %1 }").arg(m_platform_style->SingleColor().name());
+        if (style != styleSheet()) {
+            setStyleSheet(style);
+        }
+    }
+#endif
+}
+
 /** Creates context menu, its actions, and wires up all the relevant signals for mouse events. */
 void UnitDisplayStatusBarControl::createContextMenu()
 {
diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h
index d1cfa547bd6..65c5331d32f 100644
--- a/src/qt/bitcoingui.h
+++ b/src/qt/bitcoingui.h
@@ -334,10 +334,12 @@ class UnitDisplayStatusBarControl : public QLabel
 protected:
     /** So that it responds to left-button clicks */
     void mousePressEvent(QMouseEvent *event) override;
+    void changeEvent(QEvent* e) override;
 
 private:
     OptionsModel *optionsModel;
     QMenu* menu;
+    const PlatformStyle* m_platform_style;
 
     /** Shows context menu with Display Unit options by the mouse coordinates */
     void onDisplayUnitsClicked(const QPoint& point);

From 97a6b5e06a532a4ee029c8ba59c3438369f8b049 Mon Sep 17 00:00:00 2001
From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com>
Date: Thu, 8 Apr 2021 20:42:03 +0300
Subject: [PATCH 10/12] qt: Make OverviewPage aware of runtime palette change

This change fixes the GUI when changing appearance on macOS.
---
 src/qt/overviewpage.cpp | 15 ++++++++++++++-
 src/qt/overviewpage.h   |  5 +++++
 2 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/src/qt/overviewpage.cpp b/src/qt/overviewpage.cpp
index 7f12b1d2b5c..27783bdf87b 100644
--- a/src/qt/overviewpage.cpp
+++ b/src/qt/overviewpage.cpp
@@ -78,6 +78,7 @@ class TxViewDelegate : public QAbstractItemDelegate
         {
             QIcon iconWatchonly = qvariant_cast<QIcon>(index.data(TransactionTableModel::WatchonlyDecorationRole));
             QRect watchonlyRect(boundingRect.right() + 5, mainRect.top()+ypad+halfheight, 16, halfheight);
+            iconWatchonly = platformStyle->TextColorIcon(iconWatchonly);
             iconWatchonly.paint(painter, watchonlyRect);
             address_rect_min_width += 5 + watchonlyRect.width();
         }
@@ -143,6 +144,7 @@ OverviewPage::OverviewPage(const PlatformStyle *platformStyle, QWidget *parent)
     ui(new Ui::OverviewPage),
     clientModel(nullptr),
     walletModel(nullptr),
+    m_platform_style{platformStyle},
     txdelegate(new TxViewDelegate(platformStyle, this))
 {
     ui->setupUi(this);
@@ -150,7 +152,7 @@ OverviewPage::OverviewPage(const PlatformStyle *platformStyle, QWidget *parent)
     m_balances.balance = -1;
 
     // use a SingleColorIcon for the "out of sync warning" icon
-    QIcon icon = platformStyle->SingleColorIcon(":/icons/warning");
+    QIcon icon = m_platform_style->SingleColorIcon(QStringLiteral(":/icons/warning"));
     ui->labelTransactionsStatus->setIcon(icon);
     ui->labelWalletStatus->setIcon(icon);
 
@@ -298,6 +300,17 @@ void OverviewPage::setWalletModel(WalletModel *model)
     updateDisplayUnit();
 }
 
+void OverviewPage::changeEvent(QEvent* e)
+{
+#ifdef Q_OS_MACOS
+    if (e->type() == QEvent::PaletteChange) {
+        QIcon icon = m_platform_style->SingleColorIcon(QStringLiteral(":/icons/warning"));
+        ui->labelTransactionsStatus->setIcon(icon);
+        ui->labelWalletStatus->setIcon(icon);
+    }
+#endif
+}
+
 void OverviewPage::updateDisplayUnit()
 {
     if(walletModel && walletModel->getOptionsModel())
diff --git a/src/qt/overviewpage.h b/src/qt/overviewpage.h
index 5158c816783..755a107a000 100644
--- a/src/qt/overviewpage.h
+++ b/src/qt/overviewpage.h
@@ -45,6 +45,9 @@ public Q_SLOTS:
     void transactionClicked(const QModelIndex &index);
     void outOfSyncWarningClicked();
 
+protected:
+    void changeEvent(QEvent* e) override;
+
 private:
     Ui::OverviewPage *ui;
     ClientModel *clientModel;
@@ -52,6 +55,8 @@ public Q_SLOTS:
     interfaces::WalletBalances m_balances;
     bool m_privacy{false};
 
+    const PlatformStyle* m_platform_style;
+
     TxViewDelegate *txdelegate;
     std::unique_ptr<TransactionFilterProxy> filter;
 

From 2b622d4aced1848393989ee906b1f9d2436f1c1a Mon Sep 17 00:00:00 2001
From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com>
Date: Thu, 8 Apr 2021 21:36:11 +0300
Subject: [PATCH 11/12] qt: Make CoinControlDialog aware of runtime palette
 change

This change fixes the GUI when changing appearance on macOS.
---
 src/qt/coincontroldialog.cpp | 9 +++++++++
 src/qt/coincontroldialog.h   | 3 +++
 2 files changed, 12 insertions(+)

diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp
index daea2f9cab9..8ae06481410 100644
--- a/src/qt/coincontroldialog.cpp
+++ b/src/qt/coincontroldialog.cpp
@@ -562,6 +562,15 @@ void CoinControlDialog::updateLabels(CCoinControl& m_coin_control, WalletModel *
         label->setVisible(nChange < 0);
 }
 
+void CoinControlDialog::changeEvent(QEvent* e)
+{
+#ifdef Q_OS_MACOS
+    if (e->type() == QEvent::PaletteChange) {
+        updateView();
+    }
+#endif
+}
+
 void CoinControlDialog::updateView()
 {
     if (!model || !model->getOptionsModel() || !model->getAddressTableModel())
diff --git a/src/qt/coincontroldialog.h b/src/qt/coincontroldialog.h
index 6ceb3de61d1..3a03341c9e1 100644
--- a/src/qt/coincontroldialog.h
+++ b/src/qt/coincontroldialog.h
@@ -51,6 +51,9 @@ class CoinControlDialog : public QDialog
     static QList<CAmount> payAmounts;
     static bool fSubtractFeeFromAmount;
 
+protected:
+    void changeEvent(QEvent* e) override;
+
 private:
     Ui::CoinControlDialog *ui;
     CCoinControl& m_coin_control;

From c231254a65d390a3350fcef456d57e4a6eca0506 Mon Sep 17 00:00:00 2001
From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com>
Date: Fri, 9 Apr 2021 08:28:03 +0300
Subject: [PATCH 12/12] qt: Make TransactionView aware of runtime palette
 change

This change fixes the GUI when changing appearance on macOS.
---
 src/qt/transactionview.cpp | 18 ++++++++++++++++--
 src/qt/transactionview.h   |  5 +++++
 2 files changed, 21 insertions(+), 2 deletions(-)

diff --git a/src/qt/transactionview.cpp b/src/qt/transactionview.cpp
index 890d1a1740f..6c8819b5493 100644
--- a/src/qt/transactionview.cpp
+++ b/src/qt/transactionview.cpp
@@ -37,8 +37,8 @@
 #include <QUrl>
 #include <QVBoxLayout>
 
-TransactionView::TransactionView(const PlatformStyle *platformStyle, QWidget *parent) :
-    QWidget(parent)
+TransactionView::TransactionView(const PlatformStyle *platformStyle, QWidget *parent)
+    : QWidget(parent), m_platform_style{platformStyle}
 {
     // Build filter row
     setContentsMargins(0,0,0,0);
@@ -243,6 +243,20 @@ void TransactionView::setModel(WalletModel *_model)
     }
 }
 
+void TransactionView::changeEvent(QEvent* e)
+{
+#ifdef Q_OS_MACOS
+    if (e->type() == QEvent::PaletteChange) {
+        watchOnlyWidget->setItemIcon(
+            TransactionFilterProxy::WatchOnlyFilter_Yes,
+            m_platform_style->SingleColorIcon(QStringLiteral(":/icons/eye_plus")));
+        watchOnlyWidget->setItemIcon(
+            TransactionFilterProxy::WatchOnlyFilter_No,
+            m_platform_style->SingleColorIcon(QStringLiteral(":/icons/eye_minus")));
+    }
+#endif
+}
+
 void TransactionView::chooseDate(int idx)
 {
     if (!transactionProxyModel) return;
diff --git a/src/qt/transactionview.h b/src/qt/transactionview.h
index 66350bdc02e..3e2321d91bc 100644
--- a/src/qt/transactionview.h
+++ b/src/qt/transactionview.h
@@ -60,6 +60,9 @@ class TransactionView : public QWidget
         MINIMUM_COLUMN_WIDTH = 23
     };
 
+protected:
+    void changeEvent(QEvent* e) override;
+
 private:
     WalletModel *model{nullptr};
     TransactionFilterProxy *transactionProxyModel{nullptr};
@@ -85,6 +88,8 @@ class TransactionView : public QWidget
 
     bool eventFilter(QObject *obj, QEvent *event) override;
 
+    const PlatformStyle* m_platform_style;
+
 private Q_SLOTS:
     void contextualMenu(const QPoint &);
     void dateRangeChanged();
