Skip to content

Commit 63289e2

Browse files
committed
Refactor tray icon API for visibility and optional text
Replaces Show/Hide methods with SetVisible for tray icon visibility across all platforms. Title and tooltip setters/getters now use std::optional to allow clearing values. Updates C/C++ API, documentation, and example usage to reflect these changes for improved consistency and flexibility.
1 parent ad37ad9 commit 63289e2

File tree

11 files changed

+128
-120
lines changed

11 files changed

+128
-120
lines changed

examples/tray_icon_c_example/main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ int main() {
188188
on_tray_double_clicked, NULL);
189189

190190
// Show the tray icon
191-
if (native_tray_icon_show(tray_icon)) {
191+
if (native_tray_icon_set_visible(tray_icon, true)) {
192192
printf("Tray icon is now visible\n");
193193
} else {
194194
printf("Warning: Failed to show tray icon\n");

examples/tray_icon_example/main.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ int main() {
120120
trayIcon->SetContextMenu(context_menu);
121121

122122
// Show the tray icon
123-
if (trayIcon->Show()) {
123+
if (trayIcon->SetVisible(true)) {
124124
std::cout << "Tray icon is now visible!" << std::endl;
125125
} else {
126126
std::cerr << "Failed to show tray icon!" << std::endl;
@@ -170,7 +170,7 @@ int main() {
170170
}
171171

172172
// Hide the tray icon before exiting
173-
trayIcon->Hide();
173+
trayIcon->SetVisible(false);
174174
std::cout << "Exiting TrayIcon Example..." << std::endl;
175175

176176
// Cleanup

examples/window_c_example/main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,7 @@ int main() {
349349
native_tray_icon_add_listener(g_tray_icon, NATIVE_TRAY_ICON_EVENT_RIGHT_CLICKED, on_tray_icon_right_clicked, NULL);
350350
native_tray_icon_add_listener(g_tray_icon, NATIVE_TRAY_ICON_EVENT_DOUBLE_CLICKED, on_tray_icon_double_clicked, NULL);
351351

352-
native_tray_icon_show(g_tray_icon);
352+
native_tray_icon_set_visible(g_tray_icon, true);
353353
} else {
354354
fprintf(stderr, "Failed to create tray.\n");
355355
}

examples/window_example/main.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,8 @@ int main() {
8181
"XFg23zDhiRuqUXbBi1whJ9enqSQUWa7x3IcWHH0xDhLfUVYSpsWt6LMfZQwwX/"
8282
"wLVwWPG97osM9Wf7Df6GGOwnsP4BQFiPuOZ8wJUAAAAASUVORK5CYII=");
8383
std::cout << "Tray ID: " << tray_icon.id << std::endl;
84-
std::cout << "Tray Title: " << tray_icon.GetTitle() << std::endl;
85-
86-
tray_icon.Show();
84+
auto title = tray_icon.GetTitle();
85+
std::cout << "Tray Title: " << (title.has_value() ? title.value() : "(no title)") << std::endl;
8786

8887
// Create context menu
8988
auto context_menu = Menu::Create();

src/capi/tray_icon_c.cpp

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -85,12 +85,16 @@ void native_tray_icon_set_icon(native_tray_icon_t tray_icon, const char* icon) {
8585

8686
void native_tray_icon_set_title(native_tray_icon_t tray_icon,
8787
const char* title) {
88-
if (!tray_icon || !title)
88+
if (!tray_icon)
8989
return;
9090

9191
try {
9292
auto tray_icon_ptr = static_cast<TrayIcon*>(tray_icon);
93-
tray_icon_ptr->SetTitle(title);
93+
if (title) {
94+
tray_icon_ptr->SetTitle(std::string(title));
95+
} else {
96+
tray_icon_ptr->SetTitle(std::nullopt);
97+
}
9498
} catch (...) {
9599
// Ignore exceptions
96100
}
@@ -102,20 +106,29 @@ char* native_tray_icon_get_title(native_tray_icon_t tray_icon) {
102106

103107
try {
104108
auto tray_icon_ptr = static_cast<TrayIcon*>(tray_icon);
105-
return to_c_str(tray_icon_ptr->GetTitle());
109+
auto title = tray_icon_ptr->GetTitle();
110+
if (title.has_value()) {
111+
return to_c_str(title.value());
112+
} else {
113+
return nullptr;
114+
}
106115
} catch (...) {
107116
return nullptr;
108117
}
109118
}
110119

111120
void native_tray_icon_set_tooltip(native_tray_icon_t tray_icon,
112121
const char* tooltip) {
113-
if (!tray_icon || !tooltip)
122+
if (!tray_icon)
114123
return;
115124

116125
try {
117126
auto tray_icon_ptr = static_cast<TrayIcon*>(tray_icon);
118-
tray_icon_ptr->SetTooltip(tooltip);
127+
if (tooltip) {
128+
tray_icon_ptr->SetTooltip(std::string(tooltip));
129+
} else {
130+
tray_icon_ptr->SetTooltip(std::nullopt);
131+
}
119132
} catch (...) {
120133
// Ignore exceptions
121134
}
@@ -127,7 +140,12 @@ char* native_tray_icon_get_tooltip(native_tray_icon_t tray_icon) {
127140

128141
try {
129142
auto tray_icon_ptr = static_cast<TrayIcon*>(tray_icon);
130-
return to_c_str(tray_icon_ptr->GetTooltip());
143+
auto tooltip = tray_icon_ptr->GetTooltip();
144+
if (tooltip.has_value()) {
145+
return to_c_str(tooltip.value());
146+
} else {
147+
return nullptr;
148+
}
131149
} catch (...) {
132150
return nullptr;
133151
}
@@ -190,25 +208,13 @@ bool native_tray_icon_get_bounds(native_tray_icon_t tray_icon,
190208
}
191209
}
192210

193-
bool native_tray_icon_show(native_tray_icon_t tray_icon) {
194-
if (!tray_icon)
195-
return false;
196-
197-
try {
198-
auto tray_icon_ptr = static_cast<TrayIcon*>(tray_icon);
199-
return tray_icon_ptr->Show();
200-
} catch (...) {
201-
return false;
202-
}
203-
}
204-
205-
bool native_tray_icon_hide(native_tray_icon_t tray_icon) {
211+
bool native_tray_icon_set_visible(native_tray_icon_t tray_icon, bool visible) {
206212
if (!tray_icon)
207213
return false;
208214

209215
try {
210216
auto tray_icon_ptr = static_cast<TrayIcon*>(tray_icon);
211-
return tray_icon_ptr->Hide();
217+
return tray_icon_ptr->SetVisible(visible);
212218
} catch (...) {
213219
return false;
214220
}

src/capi/tray_icon_c.h

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -108,15 +108,15 @@ void native_tray_icon_set_icon(native_tray_icon_t tray_icon, const char* icon);
108108
/**
109109
* Set the title text for the tray icon
110110
* @param tray_icon The tray icon
111-
* @param title The title text to set
111+
* @param title The title text to set, or NULL to clear the title
112112
*/
113113
FFI_PLUGIN_EXPORT
114114
void native_tray_icon_set_title(native_tray_icon_t tray_icon, const char* title);
115115

116116
/**
117117
* Get the title text of the tray icon
118118
* @param tray_icon The tray icon
119-
* @return The title text, or NULL if error. Caller must free the returned
119+
* @return The title text, or NULL if no title is set or error. Caller must free the returned
120120
* string.
121121
*/
122122
FFI_PLUGIN_EXPORT
@@ -125,15 +125,15 @@ char* native_tray_icon_get_title(native_tray_icon_t tray_icon);
125125
/**
126126
* Set the tooltip text for the tray icon
127127
* @param tray_icon The tray icon
128-
* @param tooltip The tooltip text to set
128+
* @param tooltip The tooltip text to set, or NULL to clear the tooltip
129129
*/
130130
FFI_PLUGIN_EXPORT
131131
void native_tray_icon_set_tooltip(native_tray_icon_t tray_icon, const char* tooltip);
132132

133133
/**
134134
* Get the tooltip text of the tray icon
135135
* @param tray_icon The tray icon
136-
* @return The tooltip text, or NULL if error. Caller must free the returned
136+
* @return The tooltip text, or NULL if no tooltip is set or error. Caller must free the returned
137137
* string.
138138
*/
139139
FFI_PLUGIN_EXPORT
@@ -165,20 +165,13 @@ FFI_PLUGIN_EXPORT
165165
bool native_tray_icon_get_bounds(native_tray_icon_t tray_icon, native_rectangle_t* bounds);
166166

167167
/**
168-
* Show the tray icon in the system tray
168+
* Set the visibility of the tray icon in the system tray
169169
* @param tray_icon The tray icon
170-
* @return true if shown successfully, false otherwise
170+
* @param visible true to show the icon, false to hide it
171+
* @return true if visibility was changed successfully, false otherwise
171172
*/
172173
FFI_PLUGIN_EXPORT
173-
bool native_tray_icon_show(native_tray_icon_t tray_icon);
174-
175-
/**
176-
* Hide the tray icon from the system tray
177-
* @param tray_icon The tray icon
178-
* @return true if hidden successfully, false otherwise
179-
*/
180-
FFI_PLUGIN_EXPORT
181-
bool native_tray_icon_hide(native_tray_icon_t tray_icon);
174+
bool native_tray_icon_set_visible(native_tray_icon_t tray_icon, bool visible);
182175

183176
/**
184177
* Check if the tray icon is currently visible

src/platform/linux/tray_icon_linux.cpp

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -151,24 +151,21 @@ Rectangle TrayIcon::GetBounds() {
151151
return bounds;
152152
}
153153

154-
bool TrayIcon::Show() {
155-
if (pimpl_->app_indicator_) {
156-
app_indicator_set_status(pimpl_->app_indicator_,
157-
APP_INDICATOR_STATUS_ACTIVE);
158-
pimpl_->visible_ = true;
159-
return true;
154+
bool TrayIcon::SetVisible(bool visible) {
155+
if (!pimpl_->app_indicator_) {
156+
return false;
160157
}
161-
return false;
162-
}
163158

164-
bool TrayIcon::Hide() {
165-
if (pimpl_->app_indicator_) {
159+
if (visible) {
160+
app_indicator_set_status(pimpl_->app_indicator_,
161+
APP_INDICATOR_STATUS_ACTIVE);
162+
} else {
166163
app_indicator_set_status(pimpl_->app_indicator_,
167164
APP_INDICATOR_STATUS_PASSIVE);
168-
pimpl_->visible_ = false;
169-
return true;
170165
}
171-
return false;
166+
167+
pimpl_->visible_ = visible;
168+
return true;
172169
}
173170

174171
bool TrayIcon::IsVisible() {

src/platform/macos/tray_icon_macos.mm

Lines changed: 38 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,10 @@ @interface TrayIconMenuDelegate : NSObject <NSMenuDelegate>
2525
// Private implementation class
2626
class TrayIcon::Impl {
2727
public:
28-
Impl() : ns_status_item_(nil), delegate_(nil), menu_delegate_(nil), visible_(false) {}
28+
Impl() : ns_status_item_(nil), delegate_(nil), menu_delegate_(nil) {}
2929

3030
Impl(NSStatusItem* status_item)
31-
: ns_status_item_(status_item), delegate_(nil), menu_delegate_(nil), visible_(false) {
31+
: ns_status_item_(status_item), delegate_(nil), menu_delegate_(nil) {
3232
if (status_item) {
3333
// Create and set up delegate
3434
delegate_ = [[TrayIconDelegate alloc] init];
@@ -82,9 +82,6 @@ @interface TrayIconMenuDelegate : NSObject <NSMenuDelegate>
8282
TrayIconDelegate* delegate_;
8383
TrayIconMenuDelegate* menu_delegate_;
8484
std::shared_ptr<Menu> context_menu_;
85-
std::string title_;
86-
std::string tooltip_;
87-
bool visible_;
8885
};
8986

9087
TrayIcon::TrayIcon() : pimpl_(std::make_unique<Impl>()) {
@@ -164,30 +161,46 @@ @interface TrayIconMenuDelegate : NSObject <NSMenuDelegate>
164161
}
165162
}
166163

167-
void TrayIcon::SetTitle(std::string title) {
168-
pimpl_->title_ = title;
169-
164+
void TrayIcon::SetTitle(std::optional<std::string> title) {
170165
if (pimpl_->ns_status_item_ && pimpl_->ns_status_item_.button) {
171-
NSString* titleString = [NSString stringWithUTF8String:title.c_str()];
172-
[pimpl_->ns_status_item_.button setTitle:titleString];
166+
if (title.has_value()) {
167+
NSString* titleString = [NSString stringWithUTF8String:title.value().c_str()];
168+
[pimpl_->ns_status_item_.button setTitle:titleString];
169+
} else {
170+
[pimpl_->ns_status_item_.button setTitle:@""];
171+
}
173172
}
174173
}
175174

176-
std::string TrayIcon::GetTitle() {
177-
return pimpl_->title_;
175+
std::optional<std::string> TrayIcon::GetTitle() {
176+
if (pimpl_->ns_status_item_ && pimpl_->ns_status_item_.button) {
177+
NSString* titleString = [pimpl_->ns_status_item_.button title];
178+
if (titleString && [titleString length] > 0) {
179+
return std::string([titleString UTF8String]);
180+
}
181+
}
182+
return std::nullopt;
178183
}
179184

180-
void TrayIcon::SetTooltip(std::string tooltip) {
181-
pimpl_->tooltip_ = tooltip;
182-
185+
void TrayIcon::SetTooltip(std::optional<std::string> tooltip) {
183186
if (pimpl_->ns_status_item_ && pimpl_->ns_status_item_.button) {
184-
NSString* tooltipString = [NSString stringWithUTF8String:tooltip.c_str()];
185-
[pimpl_->ns_status_item_.button setToolTip:tooltipString];
187+
if (tooltip.has_value()) {
188+
NSString* tooltipString = [NSString stringWithUTF8String:tooltip.value().c_str()];
189+
[pimpl_->ns_status_item_.button setToolTip:tooltipString];
190+
} else {
191+
[pimpl_->ns_status_item_.button setToolTip:nil];
192+
}
186193
}
187194
}
188195

189-
std::string TrayIcon::GetTooltip() {
190-
return pimpl_->tooltip_;
196+
std::optional<std::string> TrayIcon::GetTooltip() {
197+
if (pimpl_->ns_status_item_ && pimpl_->ns_status_item_.button) {
198+
NSString* tooltipString = [pimpl_->ns_status_item_.button toolTip];
199+
if (tooltipString && [tooltipString length] > 0) {
200+
return std::string([tooltipString UTF8String]);
201+
}
202+
}
203+
return std::nullopt;
191204
}
192205

193206
void TrayIcon::SetContextMenu(std::shared_ptr<Menu> menu) {
@@ -224,29 +237,20 @@ @interface TrayIconMenuDelegate : NSObject <NSMenuDelegate>
224237
return bounds;
225238
}
226239

227-
bool TrayIcon::Show() {
228-
if (pimpl_->ns_status_item_) {
229-
[pimpl_->ns_status_item_ setVisible:YES];
230-
pimpl_->visible_ = true;
231-
return true;
240+
bool TrayIcon::SetVisible(bool visible) {
241+
if (!pimpl_->ns_status_item_) {
242+
return false;
232243
}
233-
return false;
234-
}
235244

236-
bool TrayIcon::Hide() {
237-
if (pimpl_->ns_status_item_) {
238-
[pimpl_->ns_status_item_ setVisible:NO];
239-
pimpl_->visible_ = false;
240-
return true;
241-
}
242-
return false;
245+
[pimpl_->ns_status_item_ setVisible:visible ? YES : NO];
246+
return true;
243247
}
244248

245249
bool TrayIcon::IsVisible() {
246250
if (pimpl_->ns_status_item_) {
247251
return [pimpl_->ns_status_item_ isVisible] == YES;
248252
}
249-
return pimpl_->visible_;
253+
return false;
250254
}
251255

252256
bool TrayIcon::OpenContextMenu(double x, double y) {

src/platform/macos/tray_manager_macos.mm

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
auto tray = pair.second;
2929
if (tray) {
3030
try {
31-
tray->Hide();
31+
tray->SetVisible(false);
3232
} catch (...) {
3333
// Ignore exceptions during cleanup
3434
}
@@ -62,6 +62,8 @@
6262
NSStatusBar* status_bar = [NSStatusBar systemStatusBar];
6363
NSStatusItem* status_item = [status_bar statusItemWithLength:NSVariableStatusItemLength];
6464

65+
std::cout << status_item.visible << std::endl;
66+
6567
auto tray = std::make_shared<TrayIcon>((__bridge void*)status_item);
6668
tray->id = next_tray_id_++;
6769
trays_[tray->id] = tray;

0 commit comments

Comments
 (0)