Skip to content

Commit 032ca47

Browse files
committed
Add WindowProcDelegateManager for tray icon events
Introduces WindowProcDelegateManager to manage window procedure delegates in Windows platform code. TrayIcon now registers and unregisters its window procedure delegate for handling tray icon events, improving encapsulation and event management.
1 parent 9a62b35 commit 032ca47

File tree

4 files changed

+95
-3
lines changed

4 files changed

+95
-3
lines changed

src/CMakeLists.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,17 +23,17 @@ file(GLOB CAPI_SOURCES "capi/*.cpp" "capi/*.c")
2323

2424
# Platform-specific source files
2525
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
26-
file(GLOB PLATFORM_SOURCES "platform/linux/*_linux.cpp")
26+
file(GLOB PLATFORM_SOURCES "platform/linux/*.cpp")
2727
# Find packages for Linux
2828
find_package(PkgConfig REQUIRED)
2929
pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0)
3030
pkg_check_modules(X11 REQUIRED IMPORTED_TARGET x11)
3131
pkg_check_modules(XI REQUIRED IMPORTED_TARGET xi)
3232
pkg_check_modules(AYATANA_APPINDICATOR REQUIRED IMPORTED_TARGET ayatana-appindicator3-0.1)
3333
elseif(APPLE)
34-
file(GLOB PLATFORM_SOURCES "platform/macos/*_macos.mm")
34+
file(GLOB PLATFORM_SOURCES "platform/macos/*.mm")
3535
elseif(WIN32)
36-
file(GLOB PLATFORM_SOURCES "platform/windows/*_windows.cpp")
36+
file(GLOB PLATFORM_SOURCES "platform/windows/*.cpp")
3737
else()
3838
set(PLATFORM_SOURCES "")
3939
endif()

src/platform/windows/tray_icon_windows.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
// clang-format off
12
#include <windows.h>
23
#include <shellapi.h>
4+
// clang-format on
35
#include <memory>
46
#include <string>
57

@@ -10,6 +12,7 @@
1012
#include "../../tray_icon.h"
1113
#include "../../tray_icon_event.h"
1214
#include "string_utils_windows.h"
15+
#include "window_proc_delegate_manager.h"
1316

1417
namespace nativeapi {
1518

@@ -36,8 +39,14 @@ class TrayIcon::Impl {
3639
nid_.uID = icon_id_;
3740
nid_.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
3841
nid_.uCallbackMessage = WM_USER + 1; // Custom message for tray icon events
42+
43+
window_proc_id_ = WindowProcDelegateManager::GetInstance().RegisterDelegate(
44+
[this](HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) {
45+
return HandleWindowProc(hwnd, message, wparam, lparam);
46+
});
3947
}
4048

49+
4150
// Windows-specific method to set internal data
4251
void SetWindowsData(HWND hwnd, UINT icon_id) {
4352
hwnd_ = hwnd;
@@ -91,6 +100,7 @@ class TrayIcon::Impl {
91100
}
92101

93102
~Impl() {
103+
WindowProcDelegateManager::GetInstance().UnregisterDelegate(window_proc_id_);
94104
if (hwnd_) {
95105
Shell_NotifyIconW(NIM_DELETE, &nid_);
96106
}
@@ -99,6 +109,16 @@ class TrayIcon::Impl {
99109
}
100110
}
101111

112+
// Handle window procedure delegate
113+
std::optional<LRESULT> HandleWindowProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) {
114+
if (message == WM_USER + 1 && wparam == icon_id_) {
115+
// This is handled by HandleWindowsMessage, but we need to return a value
116+
return 0;
117+
}
118+
return std::nullopt; // Let default window procedure handle it
119+
}
120+
121+
int window_proc_id_;
102122
HWND hwnd_;
103123
UINT icon_id_;
104124
NOTIFYICONDATAW nid_;
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#include "window_proc_delegate_manager.h"
2+
3+
namespace nativeapi {
4+
5+
WindowProcDelegateManager& WindowProcDelegateManager::GetInstance() {
6+
static WindowProcDelegateManager instance;
7+
return instance;
8+
}
9+
10+
int WindowProcDelegateManager::RegisterDelegate(WindowProcDelegate delegate) {
11+
if (!delegate) {
12+
return -1;
13+
}
14+
15+
std::lock_guard<std::mutex> lock(mutex_);
16+
17+
int id = next_id_++;
18+
delegates_[id] = std::move(delegate);
19+
return id;
20+
}
21+
22+
bool WindowProcDelegateManager::UnregisterDelegate(int id) {
23+
if (id < 0) {
24+
return false;
25+
}
26+
27+
std::lock_guard<std::mutex> lock(mutex_);
28+
29+
auto it = delegates_.find(id);
30+
if (it != delegates_.end()) {
31+
delegates_.erase(it);
32+
return true;
33+
}
34+
35+
return false;
36+
}
37+
38+
} // namespace nativeapi
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#pragma once
2+
3+
#include <windows.h>
4+
#include <functional>
5+
#include <mutex>
6+
#include <optional>
7+
#include <unordered_map>
8+
9+
namespace nativeapi {
10+
11+
using WindowProcDelegate =
12+
std::function<std::optional<LRESULT>(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)>;
13+
14+
class WindowProcDelegateManager {
15+
public:
16+
// Get the singleton instance
17+
static WindowProcDelegateManager& GetInstance();
18+
19+
// Register a delegate
20+
// Returns a unique ID if registration was successful, -1 if failed
21+
int RegisterDelegate(WindowProcDelegate delegate);
22+
23+
// Unregister the delegate by ID
24+
// Returns true if a delegate was found and removed, false if no delegate was
25+
// found
26+
bool UnregisterDelegate(int id);
27+
28+
private:
29+
mutable std::mutex mutex_;
30+
std::unordered_map<int, WindowProcDelegate> delegates_;
31+
int next_id_ = 1;
32+
};
33+
34+
} // namespace nativeapi

0 commit comments

Comments
 (0)