Skip to content

Commit 5407028

Browse files
committed
qt: Port Windows taskbar progress to native Windows API
1 parent 7b009f5 commit 5407028

File tree

5 files changed

+182
-15
lines changed

5 files changed

+182
-15
lines changed

src/qt/CMakeLists.txt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -364,10 +364,14 @@ if(WITH_DBUS)
364364
target_link_libraries(bitcoinqt PRIVATE "Qt${WITH_QT_VERSION}::DBus")
365365
endif()
366366
if(WITH_TASKBAR_PROGRESS)
367+
target_sources(bitcoinqt
368+
PRIVATE
369+
$<$<PLATFORM_ID:Windows>:wintaskbarprogress.cpp>
370+
$<$<PLATFORM_ID:Windows>:wintaskbarprogress.h>
371+
)
367372
target_link_libraries(bitcoinqt
368373
PRIVATE
369-
"Qt${WITH_QT_VERSION}::WinExtras"
370-
$<$<PLATFORM_ID:Windows>:dwmapi>
374+
$<$<PLATFORM_ID:Windows>:ole32>
371375
)
372376
endif()
373377

src/qt/bitcoingui.cpp

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,7 @@
3535
#include <qt/macdockiconhandler.h>
3636
#endif
3737
#ifdef BITCOIN_QT_WIN_TASKBAR
38-
#include <QWinTaskbarButton>
39-
#include <QWinTaskbarProgress>
38+
#include <qt/wintaskbarprogress.h>
4039
#endif
4140

4241
#include <chain.h>
@@ -232,7 +231,8 @@ BitcoinGUI::BitcoinGUI(interfaces::Node& node, const PlatformStyle *_platformSty
232231
m_app_nap_inhibitor = new CAppNapInhibitor;
233232
#endif
234233
#ifdef BITCOIN_QT_WIN_TASKBAR
235-
m_taskbar_button = new QWinTaskbarButton(this);
234+
m_taskbar_progress = new WinTaskbarProgress(this);
235+
m_taskbar_progress->setWindow(windowHandle());
236236
#endif
237237

238238
GUIUtil::handleCloseWindowShortcut(this);
@@ -1235,11 +1235,6 @@ void BitcoinGUI::setNumBlocks(int count, const QDateTime& blockDate, double nVer
12351235

12361236
tooltip = tr("Processed %n block(s) of transaction history.", "", count);
12371237

1238-
#ifdef BITCOIN_QT_WIN_TASKBAR
1239-
m_taskbar_button->setWindow(windowHandle());
1240-
QWinTaskbarProgress* taskbar_progress = m_taskbar_button->progress();
1241-
#endif
1242-
12431238
// Set icon state: spinning if catching up, tick otherwise
12441239
if (secs < MAX_BLOCK_TIME_GAP) {
12451240
tooltip = tr("Up to date") + QString(".<br>") + tooltip;
@@ -1256,7 +1251,7 @@ void BitcoinGUI::setNumBlocks(int count, const QDateTime& blockDate, double nVer
12561251
progressBarLabel->setVisible(false);
12571252
progressBar->setVisible(false);
12581253
#ifdef BITCOIN_QT_WIN_TASKBAR
1259-
taskbar_progress->setVisible(false);
1254+
m_taskbar_progress->setVisible(false);
12601255
#endif
12611256
}
12621257
else
@@ -1273,8 +1268,8 @@ void BitcoinGUI::setNumBlocks(int count, const QDateTime& blockDate, double nVer
12731268
progressBar->setValue(nVerificationProgress * 1000000000.0 + 0.5);
12741269
progressBar->setVisible(true);
12751270
#ifdef BITCOIN_QT_WIN_TASKBAR
1276-
taskbar_progress->setValue(qRound(nVerificationProgress * 100.0));
1277-
taskbar_progress->setVisible(true);
1271+
m_taskbar_progress->setValue(qRound(nVerificationProgress * 100.0));
1272+
m_taskbar_progress->setVisible(true);
12781273
#endif
12791274

12801275
tooltip = tr("Catching up…") + QString("<br>") + tooltip;

src/qt/bitcoingui.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,10 @@ class QComboBox;
5555
class QDateTime;
5656
class QProgressBar;
5757
class QProgressDialog;
58-
class QWinTaskbarButton;
5958
QT_END_NAMESPACE
6059

60+
class WinTaskbarProgress;
61+
6162
namespace GUIUtil {
6263
class ClickableLabel;
6364
class ClickableProgressBar;
@@ -180,7 +181,7 @@ class BitcoinGUI : public QMainWindow
180181
RPCConsole* rpcConsole = nullptr;
181182
HelpMessageDialog* helpMessageDialog = nullptr;
182183
#ifdef BITCOIN_QT_WIN_TASKBAR
183-
QWinTaskbarButton* m_taskbar_button = nullptr;
184+
WinTaskbarProgress* m_taskbar_progress = nullptr;
184185
#endif
185186
ModalOverlay* modalOverlay = nullptr;
186187
MempoolStats* mempoolStats = nullptr;

src/qt/wintaskbarprogress.cpp

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
// Copyright (c) 2025 The Bitcoin Knots developers
2+
// Distributed under the MIT software license, see the accompanying
3+
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4+
5+
#include <qt/wintaskbarprogress.h>
6+
7+
#include <QWindow>
8+
9+
#include <cassert>
10+
#include <windows.h>
11+
#include <shobjidl.h>
12+
13+
WinTaskbarProgress::WinTaskbarProgress(QObject *parent)
14+
: QObject(parent)
15+
{
16+
}
17+
18+
WinTaskbarProgress::~WinTaskbarProgress()
19+
{
20+
releaseTaskbarButton();
21+
}
22+
23+
void WinTaskbarProgress::setWindow(QWindow* window)
24+
{
25+
assert(!m_taskbar_button);
26+
if (m_window == window) {
27+
return;
28+
}
29+
30+
m_window = window;
31+
initTaskbarButton();
32+
updateProgress();
33+
}
34+
35+
QWindow* WinTaskbarProgress::window() const
36+
{
37+
return m_window;
38+
}
39+
40+
void WinTaskbarProgress::setValue(int value)
41+
{
42+
if (m_value == value) {
43+
return;
44+
}
45+
46+
m_value = value;
47+
updateProgress();
48+
}
49+
50+
void WinTaskbarProgress::setVisible(bool visible)
51+
{
52+
if (m_visible == visible) {
53+
return;
54+
}
55+
56+
m_visible = visible;
57+
updateProgress();
58+
}
59+
60+
void WinTaskbarProgress::updateProgress()
61+
{
62+
if (!m_taskbar_button || !m_window) {
63+
return;
64+
}
65+
66+
if (m_visible) {
67+
// Set progress value
68+
m_taskbar_button->SetProgressValue((HWND)m_window->winId(), m_value, 100);
69+
// Set progress state to normal
70+
m_taskbar_button->SetProgressState((HWND)m_window->winId(), TBPF_NORMAL);
71+
} else {
72+
// Hide progress bar
73+
m_taskbar_button->SetProgressState((HWND)m_window->winId(), TBPF_NOPROGRESS);
74+
}
75+
}
76+
77+
void WinTaskbarProgress::initTaskbarButton()
78+
{
79+
if (m_taskbar_button || !m_window) {
80+
return;
81+
}
82+
83+
HRESULT hr = CoCreateInstance(CLSID_TaskbarList, nullptr, CLSCTX_INPROC_SERVER,
84+
IID_PPV_ARGS(&m_taskbar_button));
85+
86+
if (SUCCEEDED(hr)) {
87+
hr = m_taskbar_button->HrInit();
88+
if (!SUCCEEDED(hr)) {
89+
m_taskbar_button->Release();
90+
m_taskbar_button = nullptr;
91+
}
92+
}
93+
}
94+
95+
void WinTaskbarProgress::releaseTaskbarButton()
96+
{
97+
if (!m_taskbar_button) {
98+
return;
99+
}
100+
101+
if (m_window) {
102+
m_taskbar_button->SetProgressState((HWND)m_window->winId(), TBPF_NOPROGRESS);
103+
}
104+
m_taskbar_button->Release();
105+
m_taskbar_button = nullptr;
106+
}

src/qt/wintaskbarprogress.h

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// Copyright (c) 2025 The Bitcoin Knots developers
2+
// Distributed under the MIT software license, see the accompanying
3+
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4+
5+
#ifndef BITCOIN_QT_WINTASKBARPROGRESS_H
6+
#define BITCOIN_QT_WINTASKBARPROGRESS_H
7+
8+
#include <QObject>
9+
10+
class QWindow;
11+
struct ITaskbarList3;
12+
13+
/**
14+
* Manages Windows taskbar button progress indicator.
15+
* Provides a platform-independent wrapper around the native Windows API
16+
* for taskbar progress updates.
17+
*/
18+
class WinTaskbarProgress : public QObject
19+
{
20+
Q_OBJECT
21+
22+
public:
23+
explicit WinTaskbarProgress(QObject *parent = nullptr);
24+
~WinTaskbarProgress();
25+
26+
/**
27+
* Set the window handle for taskbar progress updates
28+
* @param[in] window The QWindow to update taskbar progress for
29+
*/
30+
void setWindow(QWindow* window);
31+
32+
/**
33+
* Get the current window handle
34+
* @return The current QWindow pointer, or nullptr if not set
35+
*/
36+
QWindow* window() const;
37+
38+
/**
39+
* Set the progress value
40+
* @param[in] value Progress value (0-100)
41+
*/
42+
void setValue(int value);
43+
44+
/**
45+
* Set progress visibility
46+
* @param[in] visible True to show progress, false to hide
47+
*/
48+
void setVisible(bool visible);
49+
50+
private:
51+
QWindow* m_window = nullptr;
52+
int m_value = 0;
53+
bool m_visible = false;
54+
ITaskbarList3* m_taskbar_button = nullptr;
55+
56+
void updateProgress();
57+
void initTaskbarButton();
58+
void releaseTaskbarButton();
59+
};
60+
61+
#endif // BITCOIN_QT_WINTASKBARPROGRESS_H

0 commit comments

Comments
 (0)