1 #ifdef HAVE_CONFIG_H
2 # include "elementary_config.h"
3 #endif
4
5 #include <Elementary.h>
6
7 #include "elm_priv.h"
8 #include "elm_systray_eo.h"
9 #include "elm_systray_watcher.h"
10
11 EAPI int ELM_EVENT_SYSTRAY_READY = 0;
12
13 typedef struct _Elm_Systray_Private_Data
14 {
15 Elm_Systray_Category cat;
16 Elm_Systray_Status status;
17
18 const char *att_icon_name;
19 const char *icon_name;
20 const char *icon_theme_path;
21 const char *id;
22 const char *title;
23 const char *menu;
24 const Eo *menu_obj;
25 } Elm_Systray_Private_Data;
26
27 static Elm_Systray_Private_Data _item = {
28 .cat = ELM_SYSTRAY_CATEGORY_APP_STATUS,
29 .status = ELM_SYSTRAY_STATUS_ACTIVE,
30 .att_icon_name = NULL,
31 .icon_name = NULL,
32 .icon_theme_path = NULL,
33 .id = NULL,
34 .title = NULL,
35 .menu = NULL,
36 .menu_obj = NULL
37 };
38
39 #define OBJ_PATH "/org/ayatana/NotificationItem/StatusNotifierItem"
40 #define INTERFACE "org.kde.StatusNotifierItem"
41
42 static Eina_Bool _elm_need_systray = EINA_FALSE;
43
44 static Eldbus_Connection *_conn = NULL;
45 static Eldbus_Service_Interface *_iface = NULL;
46
47 static const char *_Elm_Systray_Cat_Str[] = {
48 [ELM_SYSTRAY_CATEGORY_APP_STATUS] = "ApplicationStatus",
49 [ELM_SYSTRAY_CATEGORY_COMMUNICATIONS] = "Communications",
50 [ELM_SYSTRAY_CATEGORY_SYS_SERVICES] = "SystemServices",
51 [ELM_SYSTRAY_CATEGORY_HARDWARE] = "Hardware",
52 [ELM_SYSTRAY_CATEGORY_OTHER] = "Other"
53 };
54
55 static const char *_Elm_Systray_Status_Str[] = {
56 [ELM_SYSTRAY_STATUS_ACTIVE] = "Active",
57 [ELM_SYSTRAY_STATUS_PASSIVE] = "Passive",
58 [ELM_SYSTRAY_STATUS_ATTENTION] = "NeedsAttention"
59 };
60
61 // =============================================================================
62 // org.kde.StatusNotifierItem Service
63 // =============================================================================
64 // =============================================================================
65 // Methods
66 // =============================================================================
67 static Eldbus_Message *
_empty_method(const Eldbus_Service_Interface * iface EINA_UNUSED,const Eldbus_Message * msg)68 _empty_method(const Eldbus_Service_Interface *iface EINA_UNUSED,
69 const Eldbus_Message *msg)
70 {
71 return eldbus_message_method_return_new(msg);
72 }
73
74 static const Eldbus_Method methods[] = {
75 {
76 "Scroll",
77 ELDBUS_ARGS({"i", "delta"}, {"s", "orientation"}),
78 NULL,
79 _empty_method,
80 0
81 },
82 {
83 "SecondaryActivate",
84 ELDBUS_ARGS({"i", "x"}, {"i", "y"}),
85 NULL,
86 _empty_method,
87 0
88 },
89 {
90 "XAyatanaSecondaryActivate",
91 ELDBUS_ARGS({"u", "timestamp"}),
92 NULL,
93 _empty_method,
94 0
95 },
96 { NULL, NULL, NULL, NULL, 0 }
97 };
98
99 // =============================================================================
100 // Signals
101 // =============================================================================
102 typedef enum _Elm_Systray_Service_Signals
103 {
104 ELM_SYSTRAY_SIGNAL_NEWATTENTIONICON,
105 ELM_SYSTRAY_SIGNAL_NEWICON,
106 ELM_SYSTRAY_SIGNAL_NEWICONTHEMEPATH,
107 ELM_SYSTRAY_SIGNAL_NEWSTATUS,
108 ELM_SYSTRAY_SIGNAL_NEWTITLE,
109 ELM_SYSTRAY_SIGNAL_XAYATANANEWLABEL
110 } Elm_Systray_Service_Signals;
111
112 #define _elm_systray_signal_emit(sig, ...) \
113 eldbus_service_signal_emit(_iface, sig, __VA_ARGS__)
114
115 static const Eldbus_Signal signals[] = {
116 [ELM_SYSTRAY_SIGNAL_NEWATTENTIONICON] = {
117 "NewAttentionIcon", NULL, 0
118 },
119 [ELM_SYSTRAY_SIGNAL_NEWICON] = {
120 "NewIcon", NULL, 0
121 },
122 [ELM_SYSTRAY_SIGNAL_NEWICONTHEMEPATH] = {
123 "NewIconThemePath", ELDBUS_ARGS({"s", "icon_theme_path"}), 0
124 },
125 [ELM_SYSTRAY_SIGNAL_NEWSTATUS] = {
126 "NewStatus", ELDBUS_ARGS({"s", "status"}), 0
127 },
128 [ELM_SYSTRAY_SIGNAL_NEWTITLE] = {
129 "NewTitle", NULL, 0
130 },
131 [ELM_SYSTRAY_SIGNAL_XAYATANANEWLABEL] = {
132 "XAyatanaNewLabel", ELDBUS_ARGS({"s", "label"}, {"s", "guide"}), 0
133 },
134 { NULL, NULL, 0 }
135 };
136
137 // =============================================================================
138 // Properties
139 // =============================================================================
140 static Eina_Bool
_prop_str_empty_get(const Eldbus_Service_Interface * iface EINA_UNUSED,const char * propname EINA_UNUSED,Eldbus_Message_Iter * iter,const Eldbus_Message * request_msg EINA_UNUSED,Eldbus_Message ** error EINA_UNUSED)141 _prop_str_empty_get(const Eldbus_Service_Interface *iface EINA_UNUSED,
142 const char *propname EINA_UNUSED,
143 Eldbus_Message_Iter *iter,
144 const Eldbus_Message *request_msg EINA_UNUSED,
145 Eldbus_Message **error EINA_UNUSED)
146 {
147 eldbus_message_iter_basic_append(iter, 's', "");
148
149 return EINA_TRUE;
150 }
151
152 static Eina_Bool
_prop_attention_icon_name_get(const Eldbus_Service_Interface * iface EINA_UNUSED,const char * propname EINA_UNUSED,Eldbus_Message_Iter * iter,const Eldbus_Message * request_msg EINA_UNUSED,Eldbus_Message ** error EINA_UNUSED)153 _prop_attention_icon_name_get(const Eldbus_Service_Interface *iface EINA_UNUSED,
154 const char *propname EINA_UNUSED,
155 Eldbus_Message_Iter *iter,
156 const Eldbus_Message *request_msg EINA_UNUSED,
157 Eldbus_Message **error EINA_UNUSED)
158 {
159 const char *s = _item.att_icon_name ? _item.att_icon_name : "";
160
161 eldbus_message_iter_basic_append(iter, 's', s);
162
163 return EINA_TRUE;
164 }
165
166 static Eina_Bool
_prop_category_get(const Eldbus_Service_Interface * iface EINA_UNUSED,const char * propname EINA_UNUSED,Eldbus_Message_Iter * iter,const Eldbus_Message * request_msg EINA_UNUSED,Eldbus_Message ** error EINA_UNUSED)167 _prop_category_get(const Eldbus_Service_Interface *iface EINA_UNUSED,
168 const char *propname EINA_UNUSED,
169 Eldbus_Message_Iter *iter,
170 const Eldbus_Message *request_msg EINA_UNUSED,
171 Eldbus_Message **error EINA_UNUSED)
172 {
173 eldbus_message_iter_basic_append(iter, 's', _Elm_Systray_Cat_Str[_item.cat]);
174
175 return EINA_TRUE;
176 }
177
178 static Eina_Bool
_prop_icon_name_get(const Eldbus_Service_Interface * iface EINA_UNUSED,const char * propname EINA_UNUSED,Eldbus_Message_Iter * iter,const Eldbus_Message * request_msg EINA_UNUSED,Eldbus_Message ** error EINA_UNUSED)179 _prop_icon_name_get(const Eldbus_Service_Interface *iface EINA_UNUSED,
180 const char *propname EINA_UNUSED,
181 Eldbus_Message_Iter *iter,
182 const Eldbus_Message *request_msg EINA_UNUSED,
183 Eldbus_Message **error EINA_UNUSED)
184 {
185 const char *s = _item.icon_name ? _item.icon_name : "";
186
187 eldbus_message_iter_basic_append(iter, 's', s);
188
189 return EINA_TRUE;
190 }
191
192 static Eina_Bool
_prop_icon_theme_path_get(const Eldbus_Service_Interface * iface EINA_UNUSED,const char * propname EINA_UNUSED,Eldbus_Message_Iter * iter,const Eldbus_Message * request_msg EINA_UNUSED,Eldbus_Message ** error EINA_UNUSED)193 _prop_icon_theme_path_get(const Eldbus_Service_Interface *iface EINA_UNUSED,
194 const char *propname EINA_UNUSED,
195 Eldbus_Message_Iter *iter,
196 const Eldbus_Message *request_msg EINA_UNUSED,
197 Eldbus_Message **error EINA_UNUSED)
198 {
199 const char *s = _item.icon_theme_path ? _item.icon_theme_path : "";
200
201 eldbus_message_iter_basic_append(iter, 's', s);
202
203 return EINA_TRUE;
204 }
205
206 static Eina_Bool
_prop_id_get(const Eldbus_Service_Interface * iface EINA_UNUSED,const char * propname EINA_UNUSED,Eldbus_Message_Iter * iter,const Eldbus_Message * request_msg EINA_UNUSED,Eldbus_Message ** error EINA_UNUSED)207 _prop_id_get(const Eldbus_Service_Interface *iface EINA_UNUSED,
208 const char *propname EINA_UNUSED,
209 Eldbus_Message_Iter *iter,
210 const Eldbus_Message *request_msg EINA_UNUSED,
211 Eldbus_Message **error EINA_UNUSED)
212 {
213 const char *s = _item.id ? _item.id : "";
214
215 eldbus_message_iter_basic_append(iter, 's', s);
216
217 return EINA_TRUE;
218 }
219
220 static Eina_Bool
_prop_menu_get(const Eldbus_Service_Interface * iface EINA_UNUSED,const char * propname EINA_UNUSED,Eldbus_Message_Iter * iter,const Eldbus_Message * request_msg EINA_UNUSED,Eldbus_Message ** error EINA_UNUSED)221 _prop_menu_get(const Eldbus_Service_Interface *iface EINA_UNUSED,
222 const char *propname EINA_UNUSED,
223 Eldbus_Message_Iter *iter,
224 const Eldbus_Message *request_msg EINA_UNUSED,
225 Eldbus_Message **error EINA_UNUSED)
226 {
227 const char *s = _item.menu ? _item.menu : "/";
228
229 eldbus_message_iter_basic_append(iter, 'o', s);
230
231 return EINA_TRUE;
232 }
233
234 static Eina_Bool
_prop_status_get(const Eldbus_Service_Interface * iface EINA_UNUSED,const char * propname EINA_UNUSED,Eldbus_Message_Iter * iter,const Eldbus_Message * request_msg EINA_UNUSED,Eldbus_Message ** error EINA_UNUSED)235 _prop_status_get(const Eldbus_Service_Interface *iface EINA_UNUSED,
236 const char *propname EINA_UNUSED,
237 Eldbus_Message_Iter *iter,
238 const Eldbus_Message *request_msg EINA_UNUSED,
239 Eldbus_Message **error EINA_UNUSED)
240 {
241 eldbus_message_iter_basic_append(iter, 's',
242 _Elm_Systray_Status_Str[_item.status]);
243
244 return EINA_TRUE;
245 }
246
247 static Eina_Bool
_prop_title_get(const Eldbus_Service_Interface * iface EINA_UNUSED,const char * propname EINA_UNUSED,Eldbus_Message_Iter * iter,const Eldbus_Message * request_msg EINA_UNUSED,Eldbus_Message ** error EINA_UNUSED)248 _prop_title_get(const Eldbus_Service_Interface *iface EINA_UNUSED,
249 const char *propname EINA_UNUSED,
250 Eldbus_Message_Iter *iter,
251 const Eldbus_Message *request_msg EINA_UNUSED,
252 Eldbus_Message **error EINA_UNUSED)
253 {
254 const char *s = _item.title ? _item.title : "";
255
256 eldbus_message_iter_basic_append(iter, 's', s);
257
258 return EINA_TRUE;
259 }
260
261 static Eina_Bool
_prop_xayatana_orderindex_get(const Eldbus_Service_Interface * iface EINA_UNUSED,const char * propname EINA_UNUSED,Eldbus_Message_Iter * iter,const Eldbus_Message * request_msg EINA_UNUSED,Eldbus_Message ** error EINA_UNUSED)262 _prop_xayatana_orderindex_get(const Eldbus_Service_Interface *iface EINA_UNUSED,
263 const char *propname EINA_UNUSED,
264 Eldbus_Message_Iter *iter,
265 const Eldbus_Message *request_msg EINA_UNUSED,
266 Eldbus_Message **error EINA_UNUSED)
267 {
268 eldbus_message_iter_basic_append(iter, 'u', 0);
269
270 return EINA_TRUE;
271 }
272
273 static const Eldbus_Property properties[] = {
274 { "AttentionAcessibleDesc", "s", _prop_str_empty_get, NULL, 0 },
275 { "AttentionIconName", "s", _prop_attention_icon_name_get, NULL, 0 },
276 { "Category", "s", _prop_category_get, NULL, 0 },
277 { "IconAcessibleDesc", "s", _prop_str_empty_get, NULL, 0 },
278 { "IconName", "s", _prop_icon_name_get, NULL, 0 },
279 { "IconThemePath", "s", _prop_icon_theme_path_get, NULL, 0 },
280 { "Id", "s", _prop_id_get, NULL, 0 },
281 { "Menu", "o", _prop_menu_get, NULL, 0 },
282 { "Status", "s", _prop_status_get, NULL, 0 },
283 { "Title", "s", _prop_title_get, NULL, 0 },
284 { "XAyatanaLabelGuide", "s", _prop_str_empty_get, NULL, 0 },
285 { "XAyatanaLabel", "s", _prop_str_empty_get, NULL, 0 },
286 { "XAyatanaOrderingIndex", "u", _prop_xayatana_orderindex_get, NULL, 0 },
287 { NULL, NULL, NULL, NULL, 0 }
288 };
289
290 static const Eldbus_Service_Interface_Desc _iface_desc = {
291 INTERFACE, methods, signals, properties, NULL, NULL
292 };
293 // =============================================================================
294
295 static void
_menu_died(void * data EINA_UNUSED,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info EINA_UNUSED)296 _menu_died(void *data EINA_UNUSED,
297 Evas *e EINA_UNUSED,
298 Evas_Object *obj EINA_UNUSED,
299 void *event_info EINA_UNUSED)
300 {
301 _item.menu_obj = NULL;
302
303 eina_stringshare_replace(&(_item.menu), NULL);
304
305 eldbus_service_property_changed(_iface, "Menu");
306 }
307
308 EOLIAN static void
_elm_systray_category_set(Eo * obj EINA_UNUSED,void * priv EINA_UNUSED,Elm_Systray_Category cat)309 _elm_systray_category_set(Eo *obj EINA_UNUSED, void *priv EINA_UNUSED, Elm_Systray_Category cat)
310 {
311 if (_item.cat == cat) return;
312
313 _item.cat = cat;
314 eldbus_service_property_changed(_iface, "Category");
315 }
316
317 EOLIAN static Elm_Systray_Category
_elm_systray_category_get(const Eo * obj EINA_UNUSED,void * priv EINA_UNUSED)318 _elm_systray_category_get(const Eo *obj EINA_UNUSED, void *priv EINA_UNUSED)
319 {
320 return _item.cat;
321 }
322
323 EOLIAN static void
_elm_systray_status_set(Eo * obj EINA_UNUSED,void * priv EINA_UNUSED,Elm_Systray_Status st)324 _elm_systray_status_set(Eo *obj EINA_UNUSED, void *priv EINA_UNUSED, Elm_Systray_Status st)
325 {
326 if (_item.status == st) return;
327
328 _item.status = st;
329 eldbus_service_property_changed(_iface, "Status");
330 _elm_systray_signal_emit(ELM_SYSTRAY_SIGNAL_NEWSTATUS,
331 _Elm_Systray_Status_Str[_item.status]);
332 }
333
334 EOLIAN static Elm_Systray_Status
_elm_systray_status_get(const Eo * obj EINA_UNUSED,void * priv EINA_UNUSED)335 _elm_systray_status_get(const Eo *obj EINA_UNUSED, void *priv EINA_UNUSED)
336 {
337 return _item.status;
338 }
339
340 EOLIAN static void
_elm_systray_att_icon_name_set(Eo * obj EINA_UNUSED,void * priv EINA_UNUSED,const char * att_icon_name)341 _elm_systray_att_icon_name_set(Eo *obj EINA_UNUSED, void *priv EINA_UNUSED, const char *att_icon_name)
342 {
343 if (!eina_stringshare_replace(&(_item.att_icon_name), att_icon_name)) return;
344
345 eldbus_service_property_changed(_iface, "AttentionIconName");
346 _elm_systray_signal_emit(ELM_SYSTRAY_SIGNAL_NEWATTENTIONICON, NULL);
347 }
348
349 EOLIAN static const char*
_elm_systray_att_icon_name_get(const Eo * obj EINA_UNUSED,void * priv EINA_UNUSED)350 _elm_systray_att_icon_name_get(const Eo *obj EINA_UNUSED, void *priv EINA_UNUSED)
351 {
352 return _item.att_icon_name;
353 }
354
355 EOLIAN static void
_elm_systray_icon_name_set(Eo * obj EINA_UNUSED,void * priv EINA_UNUSED,const char * icon_name)356 _elm_systray_icon_name_set(Eo *obj EINA_UNUSED, void *priv EINA_UNUSED, const char *icon_name)
357 {
358 if (!eina_stringshare_replace(&(_item.icon_name), icon_name)) return;
359
360 eldbus_service_property_changed(_iface, "IconName");
361 _elm_systray_signal_emit(ELM_SYSTRAY_SIGNAL_NEWICON, NULL);
362 }
363
364 EOLIAN static const char*
_elm_systray_icon_name_get(const Eo * obj EINA_UNUSED,void * priv EINA_UNUSED)365 _elm_systray_icon_name_get(const Eo *obj EINA_UNUSED, void *priv EINA_UNUSED)
366 {
367 return _item.icon_name;
368 }
369
370 EOLIAN static void
_elm_systray_icon_theme_path_set(Eo * obj EINA_UNUSED,void * priv EINA_UNUSED,const char * icon_theme_path)371 _elm_systray_icon_theme_path_set(Eo *obj EINA_UNUSED, void *priv EINA_UNUSED, const char *icon_theme_path)
372 {
373 if (!eina_stringshare_replace(&(_item.icon_theme_path), icon_theme_path))
374 return;
375
376 eldbus_service_property_changed(_iface, "IconThemePath");
377 _elm_systray_signal_emit(ELM_SYSTRAY_SIGNAL_NEWICONTHEMEPATH,
378 _item.icon_theme_path);
379 }
380
381 EOLIAN static const char*
_elm_systray_icon_theme_path_get(const Eo * obj EINA_UNUSED,void * priv EINA_UNUSED)382 _elm_systray_icon_theme_path_get(const Eo *obj EINA_UNUSED, void *priv EINA_UNUSED)
383 {
384 return _item.icon_theme_path;
385 }
386
387 EOLIAN static void
_elm_systray_id_set(Eo * obj EINA_UNUSED,void * priv EINA_UNUSED,const char * id)388 _elm_systray_id_set(Eo *obj EINA_UNUSED, void *priv EINA_UNUSED, const char *id)
389 {
390 if (!eina_stringshare_replace(&(_item.id), id)) return;
391
392 eldbus_service_property_changed(_iface, "Id");
393 }
394
395 EOLIAN static const char*
_elm_systray_id_get(const Eo * obj EINA_UNUSED,void * priv EINA_UNUSED)396 _elm_systray_id_get(const Eo *obj EINA_UNUSED, void *priv EINA_UNUSED)
397 {
398 return _item.id;
399 }
400
401 EOLIAN static void
_elm_systray_title_set(Eo * obj EINA_UNUSED,void * priv EINA_UNUSED,const char * title)402 _elm_systray_title_set(Eo *obj EINA_UNUSED, void *priv EINA_UNUSED, const char *title)
403 {
404 if (!eina_stringshare_replace(&(_item.title), title)) return;
405
406 eldbus_service_property_changed(_iface, "Title");
407 _elm_systray_signal_emit(ELM_SYSTRAY_SIGNAL_NEWTITLE, NULL);
408 }
409
410 EOLIAN static const char*
_elm_systray_title_get(const Eo * obj EINA_UNUSED,void * priv EINA_UNUSED)411 _elm_systray_title_get(const Eo *obj EINA_UNUSED, void *priv EINA_UNUSED)
412 {
413 return _item.title;
414 }
415
416 EOLIAN static void
_elm_systray_menu_set(Eo * obj EINA_UNUSED,void * priv EINA_UNUSED,const Eo * menu_obj)417 _elm_systray_menu_set(Eo *obj EINA_UNUSED, void *priv EINA_UNUSED, const Eo *menu_obj)
418 {
419 const char *menu = NULL;
420
421 if (_item.menu_obj == menu_obj) return;
422
423 if (menu_obj)
424 {
425 menu = _elm_dbus_menu_register((Eo *) menu_obj);
426 evas_object_event_callback_add((Evas_Object *) menu_obj,
427 EVAS_CALLBACK_DEL, _menu_died, NULL);
428 }
429
430 eina_stringshare_replace(&(_item.menu), menu);
431
432 if (_item.menu_obj)
433 evas_object_event_callback_del_full((Evas_Object *) _item.menu_obj,
434 EVAS_CALLBACK_DEL, _menu_died, NULL);
435
436 _item.menu_obj = menu_obj;
437
438 eldbus_service_property_changed(_iface, "Menu");
439 }
440
441 EOLIAN static const Eo*
_elm_systray_menu_get(const Eo * obj EINA_UNUSED,void * priv EINA_UNUSED)442 _elm_systray_menu_get(const Eo *obj EINA_UNUSED, void *priv EINA_UNUSED)
443 {
444 return _item.menu_obj;
445 }
446
447 EOLIAN static Eina_Bool
_elm_systray_register(Eo * obj EINA_UNUSED,void * priv EINA_UNUSED)448 _elm_systray_register(Eo *obj EINA_UNUSED, void *priv EINA_UNUSED)
449 {
450 if (!_elm_need_systray) return EINA_FALSE;
451
452 return _elm_systray_watcher_status_notifier_item_register(OBJ_PATH);
453 }
454
455 EAPI Eina_Bool
elm_need_systray(void)456 elm_need_systray(void)
457 {
458 if (_elm_need_systray) return EINA_TRUE;
459
460 if (!elm_need_eldbus()) return EINA_FALSE;
461
462 ELM_EVENT_SYSTRAY_READY = ecore_event_type_new();
463
464 if (!_elm_systray_watcher_init()) return EINA_FALSE;
465
466 _conn = eldbus_connection_get(ELDBUS_CONNECTION_TYPE_SESSION);
467 if (!_conn) goto err;
468
469 _iface = eldbus_service_interface_register(_conn, OBJ_PATH, &_iface_desc);
470 if (!_iface) goto err;
471
472 _elm_need_systray = EINA_TRUE;
473 return EINA_TRUE;
474
475 err:
476 if (_conn)
477 {
478 eldbus_connection_unref(_conn);
479 _conn = NULL;
480 }
481
482 _elm_systray_watcher_shutdown();
483 return EINA_FALSE;
484 }
485
486 void
_elm_unneed_systray(void)487 _elm_unneed_systray(void)
488 {
489 if (!_elm_need_systray) return;
490
491 ecore_event_type_flush(ELM_EVENT_SYSTRAY_READY);
492
493 _elm_need_systray = EINA_FALSE;
494
495 eldbus_service_interface_unregister(_iface);
496
497 eldbus_connection_unref(_conn);
498
499 _elm_systray_watcher_shutdown();
500
501 eina_stringshare_del(_item.att_icon_name);
502 eina_stringshare_del(_item.icon_name);
503 eina_stringshare_del(_item.icon_theme_path);
504 eina_stringshare_del(_item.id);
505 eina_stringshare_del(_item.title);
506 eina_stringshare_del(_item.menu);
507
508 if (_item.menu_obj)
509 {
510 evas_object_event_callback_del_full((Evas_Object *) _item.menu_obj,
511 EVAS_CALLBACK_DEL, _menu_died,
512 NULL);
513 _item.menu_obj = NULL;
514 }
515 }
516
517 EAPI Elm_Systray*
elm_systray_add(Evas_Object * win)518 elm_systray_add(Evas_Object *win)
519 {
520 return efl_add(ELM_SYSTRAY_CLASS, win);
521 }
522
523
524 #include "elm_systray_eo.c"
525