Skip to content

Commit 8b589a5

Browse files
committed
qt: add Windows taskbar progress for Qt6
1 parent 3d6a63e commit 8b589a5

File tree

4 files changed

+46
-62
lines changed

4 files changed

+46
-62
lines changed

src/qt/bitcoingui.cpp

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,9 @@ BitcoinGUI::BitcoinGUI(interfaces::Node& node, const PlatformStyle *_platformSty
232232
#endif
233233
#ifdef BITCOIN_QT_WIN_TASKBAR
234234
m_taskbar_progress = new WinTaskbarProgress();
235+
if (windowHandle()) {
236+
m_taskbar_progress->setWindow(windowHandle());
237+
}
235238
#endif
236239

237240
GUIUtil::handleCloseWindowShortcut(this);
@@ -1234,10 +1237,6 @@ void BitcoinGUI::setNumBlocks(int count, const QDateTime& blockDate, double nVer
12341237

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

1237-
#ifdef BITCOIN_QT_WIN_TASKBAR
1238-
m_taskbar_progress->setWindow(windowHandle());
1239-
#endif
1240-
12411240
// Set icon state: spinning if catching up, tick otherwise
12421241
if (secs < MAX_BLOCK_TIME_GAP) {
12431242
tooltip = tr("Up to date") + QString(".<br>") + tooltip;
@@ -1495,16 +1494,6 @@ bool BitcoinGUI::eventFilter(QObject *object, QEvent *event)
14951494
return QMainWindow::eventFilter(object, event);
14961495
}
14971496

1498-
#ifdef BITCOIN_QT_WIN_TASKBAR
1499-
bool BitcoinGUI::nativeEvent(const QByteArray &eventType, void *message, qintptr *result)
1500-
{
1501-
if (m_taskbar_progress) {
1502-
m_taskbar_progress->nativeEventFilter(message);
1503-
}
1504-
return QMainWindow::nativeEvent(eventType, message, result);
1505-
}
1506-
#endif
1507-
15081497
#ifdef ENABLE_WALLET
15091498
bool BitcoinGUI::handlePaymentRequest(const SendCoinsRecipient& recipient)
15101499
{

src/qt/bitcoingui.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -117,9 +117,6 @@ class BitcoinGUI : public QMainWindow
117117
void dragEnterEvent(QDragEnterEvent *event) override;
118118
void dropEvent(QDropEvent *event) override;
119119
bool eventFilter(QObject *object, QEvent *event) override;
120-
#ifdef BITCOIN_QT_WIN_TASKBAR
121-
bool nativeEvent(const QByteArray &eventType, void *message, qintptr *result) override;
122-
#endif
123120

124121
private:
125122
interfaces::Node& m_node;

src/qt/wintaskbarprogress.cpp

Lines changed: 42 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,6 @@
1313

1414
WinTaskbarProgress::WinTaskbarProgress()
1515
{
16-
// COM will be initialized by Qt or the application
17-
// Register for TaskbarButtonCreated message
18-
m_taskbarButtonCreatedMsg = RegisterWindowMessageW(L"TaskbarButtonCreated");
1916
}
2017

2118
WinTaskbarProgress::~WinTaskbarProgress()
@@ -25,26 +22,20 @@ WinTaskbarProgress::~WinTaskbarProgress()
2522

2623
void WinTaskbarProgress::setWindow(QWindow* window)
2724
{
28-
if (!window) {
29-
return;
30-
}
31-
32-
// Get the native window handle
33-
HWND newWinId = reinterpret_cast<HWND>(window->winId());
34-
35-
// Store window handle but DON'T initialize yet
36-
// We must wait for TaskbarButtonCreated message
37-
m_winId = newWinId;
25+
m_window = window;
3826
}
3927

4028
void WinTaskbarProgress::initializeTaskbar()
4129
{
42-
if (m_initialized || !m_winId) {
30+
if (m_initialized || !m_window) {
31+
return;
32+
}
33+
34+
HWND winId = reinterpret_cast<HWND>(m_window->winId());
35+
if (!winId) {
4336
return;
4437
}
4538

46-
// Create ITaskbarList3 instance
47-
// This should ONLY be called after TaskbarButtonCreated message
4839
HRESULT hr = CoCreateInstance(
4940
CLSID_TaskbarList,
5041
nullptr,
@@ -64,27 +55,15 @@ void WinTaskbarProgress::initializeTaskbar()
6455
}
6556
}
6657

67-
bool WinTaskbarProgress::nativeEventFilter(void* message)
68-
{
69-
MSG* msg = static_cast<MSG*>(message);
70-
71-
// Wait for TaskbarButtonCreated before using taskbar features
72-
if (msg->message == m_taskbarButtonCreatedMsg) {
73-
if (!m_initialized && m_winId) {
74-
initializeTaskbar();
75-
}
76-
return false;
77-
}
78-
79-
return false;
80-
}
81-
8258
void WinTaskbarProgress::releaseTaskbar()
8359
{
8460
if (m_taskbarList) {
8561
// Clear progress state before releasing
86-
if (m_winId) {
87-
m_taskbarList->SetProgressState(m_winId, TBPF_NOPROGRESS);
62+
if (m_window) {
63+
HWND winId = reinterpret_cast<HWND>(m_window->winId());
64+
if (winId) {
65+
m_taskbarList->SetProgressState(winId, TBPF_NOPROGRESS);
66+
}
8867
}
8968
m_taskbarList->Release();
9069
m_taskbarList = nullptr;
@@ -95,37 +74,60 @@ void WinTaskbarProgress::releaseTaskbar()
9574

9675
void WinTaskbarProgress::setValue(int value)
9776
{
98-
if (!m_initialized || !m_taskbarList || !m_winId) {
77+
// Lazy initialization on first use
78+
if (!m_initialized) {
79+
initializeTaskbar();
80+
}
81+
82+
if (!m_initialized || !m_taskbarList || !m_window) {
83+
return;
84+
}
85+
86+
HWND winId = reinterpret_cast<HWND>(m_window->winId());
87+
if (!winId) {
9988
return;
10089
}
10190

10291
// Clamp value to 0-100
10392
if (value < 0) value = 0;
10493
if (value > 100) value = 100;
10594

106-
// If not visible yet, make it visible first
95+
// Use indeterminate mode for very low progress (< 1%) to show activity
96+
// Otherwise progress of 0 is invisible on the taskbar
97+
if (value < 1) {
98+
m_taskbarList->SetProgressState(winId, TBPF_INDETERMINATE);
99+
m_visible = true;
100+
return;
101+
}
102+
103+
// Switch to normal mode if not already visible
107104
if (!m_visible) {
108-
m_taskbarList->SetProgressState(m_winId, TBPF_NORMAL);
105+
m_taskbarList->SetProgressState(winId, TBPF_NORMAL);
109106
m_visible = true;
110107
}
111108

112109
// Set progress value (current, maximum)
113-
m_taskbarList->SetProgressValue(m_winId, value, 100);
110+
m_taskbarList->SetProgressValue(winId, value, 100);
114111
}
115112

116113
void WinTaskbarProgress::setVisible(bool visible)
117114
{
118-
if (!m_initialized || !m_taskbarList || !m_winId) {
115+
if (!m_initialized || !m_taskbarList || !m_window) {
116+
return;
117+
}
118+
119+
HWND winId = reinterpret_cast<HWND>(m_window->winId());
120+
if (!winId) {
119121
return;
120122
}
121123

122124
if (visible && !m_visible) {
123125
// Show normal progress
124-
m_taskbarList->SetProgressState(m_winId, TBPF_NORMAL);
126+
m_taskbarList->SetProgressState(winId, TBPF_NORMAL);
125127
m_visible = true;
126128
} else if (!visible && m_visible) {
127129
// Hide progress
128-
m_taskbarList->SetProgressState(m_winId, TBPF_NOPROGRESS);
130+
m_taskbarList->SetProgressState(winId, TBPF_NOPROGRESS);
129131
m_visible = false;
130132
}
131133
}

src/qt/wintaskbarprogress.h

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,17 +37,13 @@ class WinTaskbarProgress
3737
void reset();
3838

3939
private:
40+
QWindow* m_window{nullptr};
4041
ITaskbarList3* m_taskbarList{nullptr};
41-
HWND m_winId{nullptr};
4242
bool m_initialized{false};
4343
bool m_visible{false};
44-
UINT m_taskbarButtonCreatedMsg{0};
4544

4645
void initializeTaskbar();
4746
void releaseTaskbar();
48-
bool nativeEventFilter(void* message);
49-
50-
friend class BitcoinGUI;
5147
};
5248

5349
#endif // WIN32

0 commit comments

Comments
 (0)