-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathtray_manager_linux.cpp
More file actions
126 lines (105 loc) · 2.9 KB
/
tray_manager_linux.cpp
File metadata and controls
126 lines (105 loc) · 2.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#include <memory>
#include <mutex>
#include "../../tray_icon.h"
#include "../../tray_manager.h"
// Import headers
#ifdef __has_include
#if __has_include(<gtk/gtk.h>)
#include <gtk/gtk.h>
#define HAS_GTK 1
#else
#define HAS_GTK 0
#endif
#else
// Fallback for older compilers
#define HAS_GTK 0
#endif
#ifdef __has_include
#if __has_include(<libayatana-appindicator/app-indicator.h>)
#include <libayatana-appindicator/app-indicator.h>
#define HAS_AYATANA_APPINDICATOR 1
#else
#define HAS_AYATANA_APPINDICATOR 0
#endif
#else
// Fallback for older compilers
#define HAS_AYATANA_APPINDICATOR 0
#endif
namespace nativeapi {
class TrayManager::Impl {
public:
Impl() {}
~Impl() {}
};
TrayManager::TrayManager() : next_tray_id_(1), pimpl_(std::make_unique<Impl>()) {}
TrayManager::~TrayManager() {
std::lock_guard<std::mutex> lock(mutex_);
// Clean up all managed tray icons
for (auto& pair : trays_) {
auto tray = pair.second;
if (tray) {
// The TrayIcon destructor will handle cleanup of the AppIndicator
}
}
trays_.clear();
}
bool TrayManager::IsSupported() {
#if HAS_GTK && HAS_AYATANA_APPINDICATOR
// Check if GTK is initialized and AppIndicator is available
return gtk_init_check(nullptr, nullptr);
#else
// If GTK or AppIndicator is not available, assume no system tray support
return false;
#endif
}
std::shared_ptr<TrayIcon> TrayManager::Create() {
std::lock_guard<std::mutex> lock(mutex_);
#if HAS_GTK && HAS_AYATANA_APPINDICATOR
// Create a unique ID for this tray icon
std::string indicator_id = "nativeapi-tray-" + std::to_string(next_tray_id_);
// Create a new tray using AppIndicator
AppIndicator* app_indicator = app_indicator_new(
indicator_id.c_str(),
"application-default-icon", // Default icon name
APP_INDICATOR_CATEGORY_APPLICATION_STATUS
);
if (!app_indicator) {
return nullptr;
}
auto tray = std::make_shared<TrayIcon>((void*)app_indicator);
tray->id = next_tray_id_++;
trays_[tray->id] = tray;
return tray;
#else
// AppIndicator not available, return nullptr
return nullptr;
#endif
}
std::shared_ptr<TrayIcon> TrayManager::Get(TrayIconID id) {
std::lock_guard<std::mutex> lock(mutex_);
auto it = trays_.find(id);
if (it != trays_.end()) {
return it->second;
}
return nullptr;
}
std::vector<std::shared_ptr<TrayIcon>> TrayManager::GetAll() {
std::lock_guard<std::mutex> lock(mutex_);
std::vector<std::shared_ptr<TrayIcon>> trays;
for (const auto& pair : trays_) {
trays.push_back(pair.second);
}
return trays;
}
bool TrayManager::Destroy(TrayIconID id) {
std::lock_guard<std::mutex> lock(mutex_);
auto it = trays_.find(id);
if (it != trays_.end()) {
// Remove the tray icon from our container
// The shared_ptr will automatically clean up when the last reference is released
trays_.erase(it);
return true;
}
return false;
}
} // namespace nativeapi