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