Skip to content

Commit f2fa286

Browse files
committed
feat(tray): add trayIcon field for dynamic icon updates
Added trayIcon field to PluginOutput (crossbar_core) allowing plugins to dynamically specify Freedesktop icon names (e.g., battery-level-50-symbolic). Changes: - Added trayIcon?: String to PluginOutput constructor, copyWith, toJson - Propagated trayIcon from TrayService → ProcessSpawnBackend → daemon - Fixed duplicate menu items (Refresh/Show/Quit appeared 2x) - Removed standard actions from daemon since TrayService's _buildPluginMenu already adds them Plugins can now change tray icons based on state: - battery plugin: battery-level-10-symbolic → battery-level-100-symbolic - If trayIcon is null, falls back to pluginId-based mapping
1 parent 878469a commit f2fa286

File tree

3 files changed

+15
-16
lines changed

3 files changed

+15
-16
lines changed

bin/crossbar_tray_daemon.dart

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -125,20 +125,8 @@ Future<void> _processMessage(Map<String, dynamic> data) async {
125125
}
126126
}
127127

128-
// Add standard actions
129-
menuItems.add(DBusMenuItem.separator());
130-
menuItems.add(DBusMenuItem(
131-
label: 'Show Crossbar',
132-
onClicked: () async {
133-
stdout.writeln(jsonEncode({'action': 'show'}));
134-
},
135-
));
136-
menuItems.add(DBusMenuItem(
137-
label: 'Quit',
138-
onClicked: () async {
139-
stdout.writeln(jsonEncode({'action': 'quit'}));
140-
},
141-
));
128+
// Note: Standard actions (Refresh, Show, Quit) are added by TrayService's
129+
// _buildPluginMenu, so we don't add them here to avoid duplicates.
142130

143131
final menu = DBusMenuItem(children: menuItems);
144132

lib/services/tray_service.dart

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -315,14 +315,17 @@ class TrayService with TrayListener {
315315

316316
final existingIconId = _pluginIconIds[pluginId];
317317
final title = '${output.icon} ${output.text ?? ''}';
318+
// Use plugin's trayIcon if provided, otherwise null (daemon will use mapping)
319+
final iconName = output.trayIcon;
318320

319-
LoggerService().info('TrayService._updateSeparateIcon: pluginId=$pluginId, existingIconId=$existingIconId, totalIcons=${_pluginIconIds.length}');
321+
LoggerService().info('TrayService._updateSeparateIcon: pluginId=$pluginId, existingIconId=$existingIconId, trayIcon=$iconName');
320322

321323
if (existingIconId != null) {
322324
// Update existing icon
323325
LoggerService().info('TrayService._updateSeparateIcon: updating existing icon $existingIconId');
324326
await _backend!.updateIcon(
325327
iconId: existingIconId,
328+
iconPath: iconName,
326329
title: title,
327330
tooltip: output.text ?? pluginId,
328331
menu: _buildPluginMenu(pluginId, output),
@@ -332,7 +335,7 @@ class TrayService with TrayListener {
332335
LoggerService().info('TrayService._updateSeparateIcon: creating new icon for $pluginId');
333336
final iconId = await _backend!.createIcon(
334337
pluginId: pluginId,
335-
iconPath: _iconPath ?? 'applications-utilities',
338+
iconPath: iconName ?? 'applications-utilities',
336339
tooltip: title,
337340
);
338341

@@ -343,6 +346,7 @@ class TrayService with TrayListener {
343346
// Update with full menu immediately
344347
await _backend!.updateIcon(
345348
iconId: iconId,
349+
iconPath: iconName,
346350
title: title,
347351
menu: _buildPluginMenu(pluginId, output),
348352
);

packages/crossbar_core/lib/src/models/plugin_output.dart

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ class PluginOutput {
66
this.text,
77
this.color,
88
this.trayTooltip,
9+
this.trayIcon,
910
this.menu = const [],
1011
this.hasError = false,
1112
this.errorMessage,
@@ -33,6 +34,9 @@ class PluginOutput {
3334
final String? text;
3435
final int? color;
3536
final String? trayTooltip;
37+
/// Freedesktop icon name for tray (e.g., 'battery-level-50-symbolic').
38+
/// If null, falls back to icon name mapping based on pluginId.
39+
final String? trayIcon;
3640
final List<MenuItem> menu;
3741
final bool hasError;
3842
final String? errorMessage;
@@ -43,6 +47,7 @@ class PluginOutput {
4347
String? text,
4448
int? color,
4549
String? trayTooltip,
50+
String? trayIcon,
4651
List<MenuItem>? menu,
4752
bool? hasError,
4853
String? errorMessage,
@@ -53,6 +58,7 @@ class PluginOutput {
5358
text: text ?? this.text,
5459
color: color ?? this.color,
5560
trayTooltip: trayTooltip ?? this.trayTooltip,
61+
trayIcon: trayIcon ?? this.trayIcon,
5662
menu: menu ?? this.menu,
5763
hasError: hasError ?? this.hasError,
5864
errorMessage: errorMessage ?? this.errorMessage,
@@ -66,6 +72,7 @@ class PluginOutput {
6672
'text': text,
6773
'color': color,
6874
'trayTooltip': trayTooltip,
75+
'trayIcon': trayIcon,
6976
'menu': menu.map((m) => m.toJson()).toList(),
7077
'hasError': hasError,
7178
'errorMessage': errorMessage,

0 commit comments

Comments
 (0)