[elm] Add support to D-Bus systray icons

For now, it supports only one system tray icon per application.

Each instance of ELM_OBJ_SYSTRAY_CLASS is a handler for
the same system tray item. But the API is ready to support
multiple system tray items per application.

Also, since this is a new feature, it only provides an EObject API. So,
if the old style API is still required, please do it.

Patch by: Murilo Belluzzo <murilo.belluzzo@profusion.mobi>



SVN revision: 81747
This commit is contained in:
Murilo Belluzzo 2012-12-27 13:38:40 +00:00 committed by Lucas De Marchi
parent 58b2fc2cd2
commit abcc99fcd1
14 changed files with 1333 additions and 0 deletions

View File

@ -845,3 +845,7 @@
* Add elm_dbus_menu to support D-Bus external menus.
* Add main menu to elm_win, which can be exported via D-Bus
* Add configuration: ELM_EXTERNAL_MENU, to switch between internal and external menus
2012-12-20 Murilo Pinoti Belluzzo (mbelluzzo)
* Add elm_systray to set a Status Notifier Item in the System Tray (D-Bus).

View File

@ -25,6 +25,7 @@ Additions:
* Add elm_plug signals "image,deleted" (fixed typo) and "image,resized".
* Add elm_dbus_menu to support D-Bus external menus.
* Add configuration: ELM_EXTERNAL_MENU, to switch between internal and extenal menus
* Add elm_systray.[ch]: Add support to D-Bus systray icons.
Improvements:

View File

@ -124,6 +124,7 @@ test_slideshow.c \
test_spinner.c \
test_store.c \
test_sys_notify.c \
test_systray.c \
test_table.c \
test_thumb.c \
test_toolbar.c \

View File

@ -178,6 +178,7 @@ void test_bubble(void *data, Evas_Object *obj, void *event_info);
void test_segment_control(void *data, Evas_Object *obj, void *event_info);
void test_store(void *data, Evas_Object *obj, void *event_info);
void test_sys_notify(void *data, Evas_Object *obj, void *event_info);
void test_systray(void *data, Evas_Object *obj, void *event_info);
void test_win_inline(void *data, Evas_Object *obj, void *event_info);
void test_win_socket(void *data, Evas_Object *obj, void *event_info);
void test_win_plug(void *data, Evas_Object *obj, void *event_info);
@ -727,6 +728,7 @@ add_tests:
//------------------------------//
ADD_TEST(NULL, "System", "Notification", test_sys_notify);
ADD_TEST(NULL, "System", "Systray Item", test_systray);
//------------------------------//
ADD_TEST(NULL, "Micellaneous", "Copy And Paste", test_cnp);

View File

@ -0,0 +1,194 @@
#ifdef HAVE_CONFIG_H
# include "elementary_config.h"
#endif
#include <Elementary.h>
#ifndef ELM_LIB_QUICKLAUNCH
#define WIDTH 320
#define HEIGHT 160
static Evas_Object *ai = NULL;
static Evas_Object *i = NULL;
static Evas_Object *r = NULL;
static Eo *item = NULL;
static Eina_Bool
_ev_handler(void *data __UNUSED__,
int type __UNUSED__,
void *event __UNUSED__)
{
Eina_Bool ret;
printf("systray ready event\n");
eo_do(item, elm_obj_systray_register(&ret));
printf("Item Registration: ");
if (ret)
printf("OK!\n");
else
printf("Failed!\n");
return ECORE_CALLBACK_DONE;
}
static void
_bt_clicked(void *data __UNUSED__,
Evas_Object *obj __UNUSED__,
void *event_info __UNUSED__)
{
eo_do(item, elm_obj_systray_icon_name_set(elm_entry_entry_get(i)));
eo_do(item, elm_obj_systray_att_icon_name_set(elm_entry_entry_get(ai)));
}
static void
_r_clicked(void *data __UNUSED__,
Evas_Object *obj __UNUSED__,
void *event_info __UNUSED__)
{
eo_do(item, elm_obj_systray_status_set(elm_radio_value_get(r)));
}
static void
_menu_clicked(void *data,
Evas_Object *obj __UNUSED__,
void *event_info __UNUSED__)
{
printf("Menu Item Clicked: %s\n", (const char *) data);
}
void
test_systray(void *data __UNUSED__,
Evas_Object *obj __UNUSED__,
void *event_info __UNUSED__)
{
Evas_Object *win, *bx, *it;
Elm_Object_Item *it2;
int st = 1;
Eina_Bool init_ok = elm_need_systray();
ecore_event_handler_add(ELM_EVENT_SYSTRAY_READY,
_ev_handler, NULL);
win = elm_win_add(NULL, "Systray", ELM_WIN_BASIC);
elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED);
elm_win_title_set(win, "Systemtray - Status Notifier Item");
elm_win_autodel_set(win, EINA_TRUE);
it = elm_menu_add(win);
elm_menu_item_add(it, NULL, NULL, "root 1", _menu_clicked, "root 1");
it2 = elm_menu_item_add(it, NULL, NULL, "root 2", _menu_clicked, "root 2");
elm_menu_item_add(it, it2, NULL, "item 1", _menu_clicked, "item 1");
elm_menu_item_add(it, it2, NULL, "item 2", _menu_clicked, "item 2");
// Status Notifier Item Handler
item = eo_add(ELM_OBJ_SYSTRAY_CLASS, win);
eo_do(item, elm_obj_systray_icon_name_set("elementary"));
eo_do(item, elm_obj_systray_att_icon_name_set("elementary"));
eo_do(item, elm_obj_systray_menu_set(it));
it = elm_bg_add(win);
elm_win_resize_object_add(win, it);
evas_object_size_hint_min_set(it, WIDTH, HEIGHT);
evas_object_size_hint_max_set(it, WIDTH, HEIGHT);
evas_object_show(it);
bx = elm_box_add(win);
evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
elm_win_resize_object_add(win, bx);
evas_object_show(bx);
if (!init_ok)
{
it = elm_label_add(win);
evas_object_size_hint_align_set(it, 0, EVAS_HINT_FILL);
elm_object_text_set(it, "Systray initialization failed. "
"This test will do nothing.");
elm_box_pack_end(bx, it);
evas_object_show(it);
}
it = elm_label_add(win);
evas_object_size_hint_align_set(it, 0, EVAS_HINT_FILL);
elm_object_text_set(it, "Icon:");
elm_box_pack_end(bx, it);
evas_object_show(it);
i = elm_entry_add(win);
elm_entry_single_line_set(i, EINA_TRUE);
elm_entry_scrollable_set(i, EINA_TRUE);
elm_entry_entry_set(i, "elementary");
evas_object_size_hint_align_set(i, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_box_pack_end(bx, i);
evas_object_show(i);
it = elm_label_add(win);
evas_object_size_hint_align_set(it, 0, EVAS_HINT_FILL);
elm_object_text_set(it, "Attention Icon:");
elm_box_pack_end(bx, it);
evas_object_show(it);
ai = elm_entry_add(win);
elm_entry_single_line_set(ai, EINA_TRUE);
elm_entry_scrollable_set(ai, EINA_TRUE);
elm_entry_entry_set(ai, "elementary");
evas_object_size_hint_align_set(ai, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_box_pack_end(bx, ai);
evas_object_show(ai);
it = elm_button_add(win);
elm_object_text_set(it, "Update");
evas_object_smart_callback_add(it, "clicked", _bt_clicked, NULL);
elm_box_pack_end(bx, it);
evas_object_show(it);
it = elm_separator_add(win);
elm_separator_horizontal_set(it, EINA_TRUE);
elm_box_pack_end(bx, it);
evas_object_show(it);
it = elm_label_add(win);
evas_object_size_hint_align_set(it, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_object_text_set(it, "Status:");
elm_box_pack_end(bx, it);
evas_object_show(it);
it = elm_box_add(win);
elm_box_horizontal_set(it, EINA_TRUE);
elm_box_homogeneous_set(it, EINA_TRUE);
elm_box_pack_end(bx, it);
evas_object_show(it);
bx = it;
r = elm_radio_add(win);
evas_object_size_hint_align_set(r, EVAS_HINT_FILL, EVAS_HINT_FILL);
evas_object_smart_callback_add(r, "changed", _r_clicked, NULL);
elm_radio_value_pointer_set(r, &st);
elm_radio_state_value_set(r, 0);
elm_object_text_set(r, "Passive");
elm_box_pack_end(bx, r);
evas_object_show(r);
it = elm_radio_add(win);
evas_object_size_hint_align_set(it, EVAS_HINT_FILL, EVAS_HINT_FILL);
evas_object_smart_callback_add(it, "changed", _r_clicked, NULL);
elm_radio_state_value_set(it, 1);
elm_radio_group_add(it, r);
elm_object_text_set(it, "Active");
elm_box_pack_end(bx, it);
evas_object_show(it);
it = elm_radio_add(win);
evas_object_size_hint_align_set(it, EVAS_HINT_FILL, EVAS_HINT_FILL);
evas_object_smart_callback_add(it, "changed", _r_clicked, NULL);
elm_radio_state_value_set(it, 2);
elm_radio_group_add(it, r);
elm_object_text_set(it, "Needs Attention");
elm_box_pack_end(bx, it);
evas_object_show(it);
evas_object_resize(win, WIDTH, HEIGHT);
evas_object_show(win);
}
#endif

View File

@ -163,6 +163,7 @@ EAPI extern Elm_Version *elm_version;
#include <elm_prefs_data.h>
#include <elm_prefs.h>
#include <elm_systray.h>
#include <elm_sys_notify.h>
/* special widgets - types used elsewhere */

View File

@ -195,6 +195,8 @@ elm_slider.h \
elm_slideshow.h \
elm_spinner.h \
elm_store.h \
elm_systray.h \
elm_systray_watcher.h \
elm_sys_notify.h \
elm_table.h \
elm_theme.h \
@ -283,6 +285,8 @@ elm_slider.c \
elm_slideshow.c \
elm_spinner.c \
elm_store.c \
elm_systray.c \
elm_systray_watcher.c \
elm_sys_notify.c \
elm_table.c \
elm_theme.c \

View File

@ -649,6 +649,7 @@ elm_quicklaunch_shutdown(void)
_elm_exit_handler = NULL;
_elm_theme_shutdown();
_elm_unneed_systray();
_elm_unneed_sys_notify();
_elm_unneed_efreet();
_elm_unneed_e_dbus();

View File

@ -11,6 +11,20 @@
*/
EAPI Eina_Bool elm_need_efreet(void);
/**
* Request that your elementary application needs Elm_Systray
*
* This initializes the Elm_Systray when called and, if support exists,
* returns EINA_TRUE, otherwise returns EINA_FALSE. This must be called
* before any elm_systray calls.
*
* @return EINA_TRUE if support exists and initialization succeeded.
*
* @ingroup Elm_Systray
* @since 1.8
*/
EAPI Eina_Bool elm_need_systray(void);
/**
* Request that your elementary application needs Elm_Sys_Notify
*

View File

@ -328,6 +328,7 @@ void _elm_widget_top_win_focused_set(Evas_Object *obj,
Eina_Bool top_win_focused);
Eina_Bool _elm_widget_top_win_focused_get(const Evas_Object *obj);
void _elm_unneed_systray(void);
void _elm_unneed_sys_notify(void);
void _elm_unneed_ethumb(void);
void _elm_unneed_web(void);

View File

@ -0,0 +1,650 @@
#include "Elementary.h"
#include "elm_priv.h"
#include "Eo.h"
EAPI Eo_Op ELM_OBJ_SYSTRAY_BASE_ID = EO_NOOP;
#include "elm_systray_watcher.h"
EAPI int ELM_EVENT_SYSTRAY_READY = 0;
typedef struct _Elm_Systray_Private_Data
{
Elm_Systray_Category cat;
Elm_Systray_Status status;
const char *att_icon_name;
const char *icon_name;
const char *icon_theme_path;
const char *id;
const char *title;
const char *menu;
const Eo *menu_obj;
} Elm_Systray_Private_Data;
static Elm_Systray_Private_Data _item = {
.cat = ELM_SYSTRAY_CATEGORY_APP_STATUS,
.status = ELM_SYSTRAY_STATUS_ACTIVE,
.att_icon_name = NULL,
.icon_name = NULL,
.icon_theme_path = NULL,
.id = NULL,
.title = NULL,
.menu = NULL,
.menu_obj = NULL
};
#ifdef ELM_EDBUS2
#define OBJ_PATH "/org/ayatana/NotificationItem/StatusNotifierItem"
#define INTERFACE "org.kde.StatusNotifierItem"
static Eina_Bool _elm_need_systray = EINA_FALSE;
static EDBus_Connection *_conn = NULL;
static EDBus_Service_Interface *_iface = NULL;
static const char *_Elm_Systray_Cat_Str[] = {
[ELM_SYSTRAY_CATEGORY_APP_STATUS] = "ApplicationStatus",
[ELM_SYSTRAY_CATEGORY_COMMUNICATIONS] = "Communications",
[ELM_SYSTRAY_CATEGORY_SYS_SERVICES] = "SystemServices",
[ELM_SYSTRAY_CATEGORY_HARDWARE] = "Hardware",
[ELM_SYSTRAY_CATEGORY_OTHER] = "Other"
};
static const char *_Elm_Systray_Status_Str[] = {
[ELM_SYSTRAY_STATUS_ACTIVE] = "Active",
[ELM_SYSTRAY_STATUS_PASSIVE] = "Passive",
[ELM_SYSTRAY_STATUS_ATTENTION] = "NeedsAttention"
};
// =============================================================================
// org.kde.StatusNotifierItem Service
// =============================================================================
// =============================================================================
// Methods
// =============================================================================
static EDBus_Message *
_empty_method(const EDBus_Service_Interface *iface EINA_UNUSED,
const EDBus_Message *msg)
{
return edbus_message_method_return_new(msg);
}
static const EDBus_Method methods[] = {
{
"Scroll",
EDBUS_ARGS({"i", "delta"}, {"s", "orientation"}),
NULL,
_empty_method,
0
},
{
"SecondaryActivate",
EDBUS_ARGS({"i", "x"}, {"i", "y"}),
NULL,
_empty_method,
0
},
{
"XAyatanaSecondaryActivate",
EDBUS_ARGS({"u", "timestamp"}),
NULL,
_empty_method,
0
},
{ NULL, NULL, NULL, NULL, 0 }
};
// =============================================================================
// Signals
// =============================================================================
typedef enum _Elm_Systray_Service_Signals
{
ELM_SYSTRAY_SIGNAL_NEWATTENTIONICON,
ELM_SYSTRAY_SIGNAL_NEWICON,
ELM_SYSTRAY_SIGNAL_NEWICONTHEMEPATH,
ELM_SYSTRAY_SIGNAL_NEWSTATUS,
ELM_SYSTRAY_SIGNAL_NEWTITLE,
ELM_SYSTRAY_SIGNAL_XAYATANANEWLABEL
} Elm_Systray_Service_Signals;
#define _elm_systray_signal_emit(sig, ...) \
edbus_service_signal_emit(_iface, sig, __VA_ARGS__)
static const EDBus_Signal signals[] = {
[ELM_SYSTRAY_SIGNAL_NEWATTENTIONICON] = {
"NewAttentionIcon", NULL, 0
},
[ELM_SYSTRAY_SIGNAL_NEWICON] = {
"NewIcon", NULL, 0
},
[ELM_SYSTRAY_SIGNAL_NEWICONTHEMEPATH] = {
"NewIconThemePath", EDBUS_ARGS({"s", "icon_theme_path"}), 0
},
[ELM_SYSTRAY_SIGNAL_NEWSTATUS] = {
"NewStatus", EDBUS_ARGS({"s", "status"}), 0
},
[ELM_SYSTRAY_SIGNAL_NEWTITLE] = {
"NewTitle", NULL, 0
},
[ELM_SYSTRAY_SIGNAL_XAYATANANEWLABEL] = {
"XAyatanaNewLabel", EDBUS_ARGS({"s", "label"}, {"s", "guide"}), 0
},
{ NULL, NULL, 0 }
};
// =============================================================================
// Properties
// =============================================================================
static Eina_Bool
_prop_str_empty_get(const EDBus_Service_Interface *iface EINA_UNUSED,
const char *propname EINA_UNUSED,
EDBus_Message_Iter *iter,
const EDBus_Message *request_msg EINA_UNUSED,
EDBus_Message **error EINA_UNUSED)
{
edbus_message_iter_basic_append(iter, 's', "");
return EINA_TRUE;
}
static Eina_Bool
_prop_attention_icon_name_get(const EDBus_Service_Interface *iface EINA_UNUSED,
const char *propname EINA_UNUSED,
EDBus_Message_Iter *iter,
const EDBus_Message *request_msg EINA_UNUSED,
EDBus_Message **error EINA_UNUSED)
{
const char *s = _item.att_icon_name ? _item.att_icon_name : "";
edbus_message_iter_basic_append(iter, 's', s);
return EINA_TRUE;
}
static Eina_Bool
_prop_category_get(const EDBus_Service_Interface *iface EINA_UNUSED,
const char *propname EINA_UNUSED,
EDBus_Message_Iter *iter,
const EDBus_Message *request_msg EINA_UNUSED,
EDBus_Message **error EINA_UNUSED)
{
edbus_message_iter_basic_append(iter, 's', _Elm_Systray_Cat_Str[_item.cat]);
return EINA_TRUE;
}
static Eina_Bool
_prop_icon_name_get(const EDBus_Service_Interface *iface EINA_UNUSED,
const char *propname EINA_UNUSED,
EDBus_Message_Iter *iter,
const EDBus_Message *request_msg EINA_UNUSED,
EDBus_Message **error EINA_UNUSED)
{
const char *s = _item.icon_name ? _item.icon_name : "";
edbus_message_iter_basic_append(iter, 's', s);
return EINA_TRUE;
}
static Eina_Bool
_prop_icon_theme_path_get(const EDBus_Service_Interface *iface EINA_UNUSED,
const char *propname EINA_UNUSED,
EDBus_Message_Iter *iter,
const EDBus_Message *request_msg EINA_UNUSED,
EDBus_Message **error EINA_UNUSED)
{
const char *s = _item.icon_theme_path ? _item.icon_theme_path : "";
edbus_message_iter_basic_append(iter, 's', s);
return EINA_TRUE;
}
static Eina_Bool
_prop_id_get(const EDBus_Service_Interface *iface EINA_UNUSED,
const char *propname EINA_UNUSED,
EDBus_Message_Iter *iter,
const EDBus_Message *request_msg EINA_UNUSED,
EDBus_Message **error EINA_UNUSED)
{
const char *s = _item.id ? _item.id : "";
edbus_message_iter_basic_append(iter, 's', s);
return EINA_TRUE;
}
static Eina_Bool
_prop_menu_get(const EDBus_Service_Interface *iface EINA_UNUSED,
const char *propname EINA_UNUSED,
EDBus_Message_Iter *iter,
const EDBus_Message *request_msg EINA_UNUSED,
EDBus_Message **error EINA_UNUSED)
{
const char *s = _item.menu ? _item.menu : "/";
edbus_message_iter_basic_append(iter, 'o', s);
return EINA_TRUE;
}
static Eina_Bool
_prop_status_get(const EDBus_Service_Interface *iface EINA_UNUSED,
const char *propname EINA_UNUSED,
EDBus_Message_Iter *iter,
const EDBus_Message *request_msg EINA_UNUSED,
EDBus_Message **error EINA_UNUSED)
{
edbus_message_iter_basic_append(iter, 's',
_Elm_Systray_Status_Str[_item.status]);
return EINA_TRUE;
}
static Eina_Bool
_prop_title_get(const EDBus_Service_Interface *iface EINA_UNUSED,
const char *propname EINA_UNUSED,
EDBus_Message_Iter *iter,
const EDBus_Message *request_msg EINA_UNUSED,
EDBus_Message **error EINA_UNUSED)
{
const char *s = _item.title ? _item.title : "";
edbus_message_iter_basic_append(iter, 's', s);
return EINA_TRUE;
}
static Eina_Bool
_prop_xayatana_orderindex_get(const EDBus_Service_Interface *iface EINA_UNUSED,
const char *propname EINA_UNUSED,
EDBus_Message_Iter *iter,
const EDBus_Message *request_msg EINA_UNUSED,
EDBus_Message **error EINA_UNUSED)
{
edbus_message_iter_basic_append(iter, 'u', 0);
return EINA_TRUE;
}
static const EDBus_Property properties[] = {
{ "AttentionAcessibleDesc", "s", _prop_str_empty_get, NULL, 0 },
{ "AttentionIconName", "s", _prop_attention_icon_name_get, NULL, 0 },
{ "Category", "s", _prop_category_get, NULL, 0 },
{ "IconAcessibleDesc", "s", _prop_str_empty_get, NULL, 0 },
{ "IconName", "s", _prop_icon_name_get, NULL, 0 },
{ "IconThemePath", "s", _prop_icon_theme_path_get, NULL, 0 },
{ "Id", "s", _prop_id_get, NULL, 0 },
{ "Menu", "o", _prop_menu_get, NULL, 0 },
{ "Status", "s", _prop_status_get, NULL, 0 },
{ "Title", "s", _prop_title_get, NULL, 0 },
{ "XAyatanaLabelGuide", "s", _prop_str_empty_get, NULL, 0 },
{ "XAyatanaLabel", "s", _prop_str_empty_get, NULL, 0 },
{ "XAyatanaOrderingIndex", "u", _prop_xayatana_orderindex_get, NULL, 0 },
{ NULL, NULL, NULL, NULL, 0 }
};
static const EDBus_Service_Interface_Desc _iface_desc = {
INTERFACE, methods, signals, properties, NULL, NULL
};
#endif
// =============================================================================
static void
_menu_died(void *data EINA_UNUSED,
Evas *e EINA_UNUSED,
Evas_Object *obj EINA_UNUSED,
void *event_info EINA_UNUSED)
{
_item.menu_obj = NULL;
eina_stringshare_replace(&(_item.menu), NULL);
#ifdef ELM_EDBUS2
edbus_service_property_changed(_iface, "Menu");
#endif
}
static void
_category_set(Eo *obj EINA_UNUSED, void *priv EINA_UNUSED, va_list *args)
{
Elm_Systray_Category cat = va_arg(*args, Elm_Systray_Category);
if (_item.cat == cat) return;
_item.cat = cat;
#ifdef ELM_EDBUS2
edbus_service_property_changed(_iface, "Category");
#endif
}
static void
_category_get(Eo *obj EINA_UNUSED, void *priv EINA_UNUSED, va_list *args)
{
Elm_Systray_Category *ret = va_arg(*args, Elm_Systray_Category *);
*ret = _item.cat;
}
static void
_status_set(Eo *obj EINA_UNUSED, void *priv EINA_UNUSED, va_list *args)
{
Elm_Systray_Status st = va_arg(*args, Elm_Systray_Status);
if (_item.status == st) return;
_item.status = st;
#ifdef ELM_EDBUS2
edbus_service_property_changed(_iface, "Status");
_elm_systray_signal_emit(ELM_SYSTRAY_SIGNAL_NEWSTATUS,
_Elm_Systray_Status_Str[_item.status]);
#endif
}
static void
_status_get(Eo *obj EINA_UNUSED, void *priv EINA_UNUSED, va_list *args)
{
Elm_Systray_Status *ret = va_arg(*args, Elm_Systray_Status *);
*ret = _item.status;
}
static void
_att_icon_name_set(Eo *obj EINA_UNUSED, void *priv EINA_UNUSED, va_list *args)
{
const char *att_icon_name = va_arg(*args, const char *);
if (!eina_stringshare_replace(&(_item.att_icon_name), att_icon_name)) return;
#ifdef ELM_EDBUS2
edbus_service_property_changed(_iface, "AttentionIconName");
_elm_systray_signal_emit(ELM_SYSTRAY_SIGNAL_NEWATTENTIONICON, NULL);
#endif
}
static void
_att_icon_name_get(Eo *obj EINA_UNUSED, void *priv EINA_UNUSED, va_list *args)
{
const char **ret = va_arg(*args, const char **);
*ret = _item.att_icon_name;
}
static void
_icon_name_set(Eo *obj EINA_UNUSED, void *priv EINA_UNUSED, va_list *args)
{
const char *icon_name = va_arg(*args, const char *);
if (!eina_stringshare_replace(&(_item.icon_name), icon_name)) return;
#ifdef ELM_EDBUS2
edbus_service_property_changed(_iface, "IconName");
_elm_systray_signal_emit(ELM_SYSTRAY_SIGNAL_NEWICON, NULL);
#endif
}
static void
_icon_name_get(Eo *obj EINA_UNUSED, void *priv EINA_UNUSED, va_list *args)
{
const char **ret = va_arg(*args, const char **);
*ret = _item.icon_name;
}
static void
_icon_theme_path_set(Eo *obj EINA_UNUSED, void *priv EINA_UNUSED, va_list *args)
{
const char *icon_theme_path = va_arg(*args, const char *);
if (!eina_stringshare_replace(&(_item.icon_theme_path), icon_theme_path))
return;
#ifdef ELM_EDBUS2
edbus_service_property_changed(_iface, "IconThemePath");
_elm_systray_signal_emit(ELM_SYSTRAY_SIGNAL_NEWICONTHEMEPATH,
_item.icon_theme_path);
#endif
}
static void
_icon_theme_path_get(Eo *obj EINA_UNUSED, void *priv EINA_UNUSED, va_list *args)
{
const char **ret = va_arg(*args, const char **);
*ret = _item.icon_theme_path;
}
static void
_id_set(Eo *obj EINA_UNUSED, void *priv EINA_UNUSED, va_list *args)
{
const char *id = va_arg(*args, const char *);
if (!eina_stringshare_replace(&(_item.id), id)) return;
#ifdef ELM_EDBUS2
edbus_service_property_changed(_iface, "Id");
#endif
}
static void
_id_get(Eo *obj EINA_UNUSED, void *priv EINA_UNUSED, va_list *args)
{
const char **ret = va_arg(*args, const char **);
*ret = _item.id;
}
static void
_title_set(Eo *obj EINA_UNUSED, void *priv EINA_UNUSED, va_list *args)
{
const char *title = va_arg(*args, const char *);
if (!eina_stringshare_replace(&(_item.title), title)) return;
#ifdef ELM_EDBUS2
edbus_service_property_changed(_iface, "Title");
_elm_systray_signal_emit(ELM_SYSTRAY_SIGNAL_NEWTITLE, NULL);
#endif
}
static void
_title_get(Eo *obj EINA_UNUSED, void *priv EINA_UNUSED, va_list *args)
{
const char **ret = va_arg(*args, const char **);
*ret = _item.title;
}
static void
_menu_set(Eo *obj EINA_UNUSED, void *priv EINA_UNUSED, va_list *args)
{
const Eo *menu_obj = va_arg(*args, const Eo *);
const char *menu = NULL;
if (_item.menu_obj == menu_obj) return;
if (menu_obj)
{
menu = _elm_dbus_menu_register((Eo *) menu_obj);
evas_object_event_callback_add((Evas_Object *) menu_obj,
EVAS_CALLBACK_DEL, _menu_died, NULL);
}
eina_stringshare_replace(&(_item.menu), menu);
if (_item.menu_obj)
evas_object_event_callback_del_full((Evas_Object *) _item.menu_obj,
EVAS_CALLBACK_DEL, _menu_died, NULL);
_item.menu_obj = menu_obj;
#ifdef ELM_EDBUS2
edbus_service_property_changed(_iface, "Menu");
#endif
}
static void
_menu_get(Eo *obj EINA_UNUSED, void *priv EINA_UNUSED, va_list *args)
{
const Eo **ret = va_arg(*args, const Eo **);
*ret = _item.menu_obj;
}
static void
_register(Eo *obj EINA_UNUSED, void *priv EINA_UNUSED, va_list *args)
{
Eina_Bool *ret = va_arg(*args, Eina_Bool *);
#ifdef ELM_EDBUS2
if (!_elm_need_systray) goto err;
*ret = _elm_systray_watcher_status_notifier_item_register(OBJ_PATH);
return;
err:
#endif
*ret = EINA_FALSE;
}
EAPI Eina_Bool
elm_need_systray(void)
{
#ifdef ELM_EDBUS2
if (_elm_need_systray) return EINA_TRUE;
if (!elm_need_edbus()) return EINA_FALSE;
if (!ELM_EVENT_SYSTRAY_READY)
ELM_EVENT_SYSTRAY_READY = ecore_event_type_new();
if (!_elm_systray_watcher_init()) return EINA_FALSE;
_conn = edbus_connection_get(EDBUS_CONNECTION_TYPE_SESSION);
if (!_conn) goto err;
_iface = edbus_service_interface_register(_conn, OBJ_PATH, &_iface_desc);
if (!_iface) goto err;
_elm_need_systray = EINA_TRUE;
return EINA_TRUE;
err:
if (_conn)
{
edbus_connection_unref(_conn);
_conn = NULL;
}
_elm_systray_watcher_shutdown();
#endif
return EINA_FALSE;
}
void
_elm_unneed_systray(void)
{
#ifdef ELM_EDBUS2
if (!_elm_need_systray) return;
_elm_need_systray = EINA_FALSE;
edbus_service_interface_unregister(_iface);
edbus_connection_unref(_conn);
_elm_systray_watcher_shutdown();
eina_stringshare_del(_item.att_icon_name);
eina_stringshare_del(_item.icon_name);
eina_stringshare_del(_item.icon_theme_path);
eina_stringshare_del(_item.id);
eina_stringshare_del(_item.title);
eina_stringshare_del(_item.menu);
if (_item.menu_obj)
{
evas_object_event_callback_del_full((Evas_Object *) _item.menu_obj,
EVAS_CALLBACK_DEL, _menu_died,
NULL);
_item.menu_obj = NULL;
}
#endif
}
// =============================================================================
// EObject Stuff
// =============================================================================
static void
_class_constructor(Eo_Class *klass)
{
const Eo_Op_Func_Description func_desc[] = {
EO_OP_FUNC(ELM_OBJ_SYSTRAY_ID(ELM_OBJ_SYSTRAY_SUB_ID_CATEGORY_SET),
_category_set),
EO_OP_FUNC(ELM_OBJ_SYSTRAY_ID(ELM_OBJ_SYSTRAY_SUB_ID_CATEGORY_GET),
_category_get),
EO_OP_FUNC(ELM_OBJ_SYSTRAY_ID(ELM_OBJ_SYSTRAY_SUB_ID_STATUS_SET),
_status_set),
EO_OP_FUNC(ELM_OBJ_SYSTRAY_ID(ELM_OBJ_SYSTRAY_SUB_ID_STATUS_GET),
_status_get),
EO_OP_FUNC(ELM_OBJ_SYSTRAY_ID(ELM_OBJ_SYSTRAY_SUB_ID_ATT_ICON_NAME_SET),
_att_icon_name_set),
EO_OP_FUNC(ELM_OBJ_SYSTRAY_ID(ELM_OBJ_SYSTRAY_SUB_ID_ATT_ICON_NAME_GET),
_att_icon_name_get),
EO_OP_FUNC(ELM_OBJ_SYSTRAY_ID(ELM_OBJ_SYSTRAY_SUB_ID_ICON_NAME_SET),
_icon_name_set),
EO_OP_FUNC(ELM_OBJ_SYSTRAY_ID(ELM_OBJ_SYSTRAY_SUB_ID_ICON_NAME_GET),
_icon_name_get),
EO_OP_FUNC(ELM_OBJ_SYSTRAY_ID(ELM_OBJ_SYSTRAY_SUB_ID_ICON_THEME_PATH_SET),
_icon_theme_path_set),
EO_OP_FUNC(ELM_OBJ_SYSTRAY_ID(ELM_OBJ_SYSTRAY_SUB_ID_ICON_THEME_PATH_GET),
_icon_theme_path_get),
EO_OP_FUNC(ELM_OBJ_SYSTRAY_ID(ELM_OBJ_SYSTRAY_SUB_ID_ID_SET),
_id_set),
EO_OP_FUNC(ELM_OBJ_SYSTRAY_ID(ELM_OBJ_SYSTRAY_SUB_ID_ID_GET),
_id_get),
EO_OP_FUNC(ELM_OBJ_SYSTRAY_ID(ELM_OBJ_SYSTRAY_SUB_ID_TITLE_SET),
_title_set),
EO_OP_FUNC(ELM_OBJ_SYSTRAY_ID(ELM_OBJ_SYSTRAY_SUB_ID_TITLE_GET),
_title_get),
EO_OP_FUNC(ELM_OBJ_SYSTRAY_ID(ELM_OBJ_SYSTRAY_SUB_ID_MENU_SET),
_menu_set),
EO_OP_FUNC(ELM_OBJ_SYSTRAY_ID(ELM_OBJ_SYSTRAY_SUB_ID_MENU_GET),
_menu_get),
EO_OP_FUNC(ELM_OBJ_SYSTRAY_ID(ELM_OBJ_SYSTRAY_SUB_ID_REGISTER),
_register),
EO_OP_FUNC_SENTINEL
};
eo_class_funcs_set(klass, func_desc);
}
static const Eo_Op_Description op_desc[] = {
EO_OP_DESCRIPTION(ELM_OBJ_SYSTRAY_SUB_ID_CATEGORY_SET, ""),
EO_OP_DESCRIPTION(ELM_OBJ_SYSTRAY_SUB_ID_CATEGORY_GET, ""),
EO_OP_DESCRIPTION(ELM_OBJ_SYSTRAY_SUB_ID_STATUS_SET, ""),
EO_OP_DESCRIPTION(ELM_OBJ_SYSTRAY_SUB_ID_STATUS_GET, ""),
EO_OP_DESCRIPTION(ELM_OBJ_SYSTRAY_SUB_ID_ATT_ICON_NAME_SET, ""),
EO_OP_DESCRIPTION(ELM_OBJ_SYSTRAY_SUB_ID_ATT_ICON_NAME_GET, ""),
EO_OP_DESCRIPTION(ELM_OBJ_SYSTRAY_SUB_ID_ICON_NAME_SET, ""),
EO_OP_DESCRIPTION(ELM_OBJ_SYSTRAY_SUB_ID_ICON_NAME_GET, ""),
EO_OP_DESCRIPTION(ELM_OBJ_SYSTRAY_SUB_ID_ICON_THEME_PATH_SET, ""),
EO_OP_DESCRIPTION(ELM_OBJ_SYSTRAY_SUB_ID_ICON_THEME_PATH_GET, ""),
EO_OP_DESCRIPTION(ELM_OBJ_SYSTRAY_SUB_ID_ID_SET, ""),
EO_OP_DESCRIPTION(ELM_OBJ_SYSTRAY_SUB_ID_ID_GET, ""),
EO_OP_DESCRIPTION(ELM_OBJ_SYSTRAY_SUB_ID_TITLE_SET, ""),
EO_OP_DESCRIPTION(ELM_OBJ_SYSTRAY_SUB_ID_TITLE_GET, ""),
EO_OP_DESCRIPTION(ELM_OBJ_SYSTRAY_SUB_ID_MENU_SET, ""),
EO_OP_DESCRIPTION(ELM_OBJ_SYSTRAY_SUB_ID_MENU_GET, ""),
EO_OP_DESCRIPTION(ELM_OBJ_SYSTRAY_SUB_ID_REGISTER, ""),
EO_OP_DESCRIPTION_SENTINEL
};
static const Eo_Class_Description class_desc = {
EO_VERSION,
"elm_systray",
EO_CLASS_TYPE_REGULAR,
EO_CLASS_DESCRIPTION_OPS
(&ELM_OBJ_SYSTRAY_BASE_ID, op_desc, ELM_OBJ_SYSTRAY_SUB_ID_LAST),
NULL,
0,
_class_constructor,
NULL//_class_destructor,
};
EO_DEFINE_CLASS(elm_obj_systray_class_get, &class_desc, EO_BASE_CLASS, NULL);

View File

@ -0,0 +1,324 @@
#ifndef ELM_SYSTRAY_H
#define ELM_SYSTRAY_H
#include "Eo.h"
#define ELM_OBJ_SYSTRAY_CLASS elm_obj_systray_class_get()
const Eo_Class *elm_obj_systray_class_get(void) EINA_CONST;
extern EAPI Eo_Op ELM_OBJ_SYSTRAY_BASE_ID;
enum
{
ELM_OBJ_SYSTRAY_SUB_ID_CATEGORY_SET,
ELM_OBJ_SYSTRAY_SUB_ID_CATEGORY_GET,
ELM_OBJ_SYSTRAY_SUB_ID_STATUS_SET,
ELM_OBJ_SYSTRAY_SUB_ID_STATUS_GET,
ELM_OBJ_SYSTRAY_SUB_ID_ATT_ICON_NAME_SET,
ELM_OBJ_SYSTRAY_SUB_ID_ATT_ICON_NAME_GET,
ELM_OBJ_SYSTRAY_SUB_ID_ICON_NAME_SET,
ELM_OBJ_SYSTRAY_SUB_ID_ICON_NAME_GET,
ELM_OBJ_SYSTRAY_SUB_ID_ICON_THEME_PATH_SET,
ELM_OBJ_SYSTRAY_SUB_ID_ICON_THEME_PATH_GET,
ELM_OBJ_SYSTRAY_SUB_ID_ID_SET,
ELM_OBJ_SYSTRAY_SUB_ID_ID_GET,
ELM_OBJ_SYSTRAY_SUB_ID_TITLE_SET,
ELM_OBJ_SYSTRAY_SUB_ID_TITLE_GET,
ELM_OBJ_SYSTRAY_SUB_ID_MENU_SET,
ELM_OBJ_SYSTRAY_SUB_ID_MENU_GET,
ELM_OBJ_SYSTRAY_SUB_ID_REGISTER,
ELM_OBJ_SYSTRAY_SUB_ID_LAST
};
#define ELM_OBJ_SYSTRAY_ID(sub_id) (ELM_OBJ_SYSTRAY_BASE_ID + sub_id)
/**
* @def elm_obj_systray_category_set
*
* Set the category of the Status Notifier Item.
*
* @param[in] cat Category
*
* @see Elm_Systray_Category
*
* @since 1.8
*/
#define elm_obj_systray_category_set(cat) \
ELM_OBJ_SYSTRAY_ID(ELM_OBJ_SYSTRAY_SUB_ID_CATEGORY_SET), \
EO_TYPECHECK(Elm_Systray_Category, cat)
/**
* @def elm_obj_systray_category_get
*
* Retrieve the category of the Status Notifier Item.
*
* @param[out] ret Category
*
* @see elm_obj_systray_category_set
*
* @since 1.8
*/
#define elm_obj_systray_category_get(ret) \
ELM_OBJ_SYSTRAY_ID(ELM_OBJ_SYSTRAY_SUB_ID_CATEGORY_GET), \
EO_TYPECHECK(Elm_Systray_Category *, ret)
/**
* @def elm_obj_systray_status_set
*
* Set the status of the Status Notifier Item.
*
* @param[in] st Status
*
* @see Elm_Systray_Status
*
* @since 1.8
*/
#define elm_obj_systray_status_set(st) \
ELM_OBJ_SYSTRAY_ID(ELM_OBJ_SYSTRAY_SUB_ID_STATUS_SET), \
EO_TYPECHECK(Elm_Systray_Status, st)
/**
* @def elm_obj_systray_status_get
*
* Retrieve the status of the Status Notifier Item.
*
* @param[out] ret Status
*
* @see elm_obj_systray_status_set
*
* @since 1.8
*/
#define elm_obj_systray_status_get(ret) \
ELM_OBJ_SYSTRAY_ID(ELM_OBJ_SYSTRAY_SUB_ID_STATUS_GET), \
EO_TYPECHECK(Elm_Systray_Status *, ret)
/**
* @def elm_obj_systray_att_icon_name_set
*
* Set the name of the attention icon to be used by the Status Notifier Item.
*
* @param[in] att_icon_name
*
* @see elm_obj_systray_att_icon_name_get
*
* @since 1.8
*/
#define elm_obj_systray_att_icon_name_set(att_icon_name) \
ELM_OBJ_SYSTRAY_ID(ELM_OBJ_SYSTRAY_SUB_ID_ATT_ICON_NAME_SET), \
EO_TYPECHECK(const char *, att_icon_name)
/**
* @def elm_obj_systray_att_icon_name_get
*
* Retrieve the name of the attention icon used by the Status Notifier Item.
*
* @param[out] ret
*
* @see elm_obj_systray_att_icon_name_set
*
* @since 1.8
*/
#define elm_obj_systray_att_icon_name_get(ret) \
ELM_OBJ_SYSTRAY_ID(ELM_OBJ_SYSTRAY_SUB_ID_ATT_ICON_NAME_GET), \
EO_TYPECHECK(const char **, ret)
/**
* @def elm_obj_systray_icon_name_set
*
* Set the name of the icon to be used by the Status Notifier Item.
*
* @param[in] icon_name
*
* @see elm_obj_systray_icon_name_get
*
* @since 1.8
*/
#define elm_obj_systray_icon_name_set(icon_name) \
ELM_OBJ_SYSTRAY_ID(ELM_OBJ_SYSTRAY_SUB_ID_ICON_NAME_SET), \
EO_TYPECHECK(const char *, icon_name)
/**
* @def elm_obj_systray_icon_name_get
*
* Retrieve the name of the icon used by the Status Notifier Item.
*
* @param[out] ret
*
* @see elm_obj_systray_icon_name_set
*
* @since 1.8
*/
#define elm_obj_systray_icon_name_get(ret) \
ELM_OBJ_SYSTRAY_ID(ELM_OBJ_SYSTRAY_SUB_ID_ICON_NAME_GET), \
EO_TYPECHECK(const char **, ret)
/**
* @def elm_obj_systray_icon_theme_path_set
*
* Set the path to the theme where the icons can be found.
* Set this value to "" to use the default path.
*
* @param[in] icon_theme_path
*
* @see elm_obj_systray_icon_theme_path_get
*
* @since 1.8
*/
#define elm_obj_systray_icon_theme_path_set(icon_theme_path) \
ELM_OBJ_SYSTRAY_ID(ELM_OBJ_SYSTRAY_SUB_ID_ICON_THEME_PATH_SET), \
EO_TYPECHECK(const char *, icon_theme_path)
/**
* @def elm_obj_systray_icon_theme_path_get
*
* Retrieve the path to the icon's theme currently in use.
*
* @param[out] ret
*
* @see elm_obj_systray_icon_theme_path_set
*
* @since 1.8
*/
#define elm_obj_systray_icon_theme_path_get(ret) \
ELM_OBJ_SYSTRAY_ID(ELM_OBJ_SYSTRAY_SUB_ID_ICON_THEME_PATH_GET), \
EO_TYPECHECK(const char **, ret)
/**
* @def elm_obj_systray_id_set
*
* Set the id of the Status Notifier Item.
*
* @param[in] id
*
* @see elm_obj_systray_id_get
*
* @since 1.8
*/
#define elm_obj_systray_id_set(id) \
ELM_OBJ_SYSTRAY_ID(ELM_OBJ_SYSTRAY_SUB_ID_ID_SET), \
EO_TYPECHECK(const char *, id)
/**
* @def elm_obj_systray_id_get
*
* Retrieve the id of the Status Notifier Item.
*
* @param[out] ret
*
* @see elm_obj_systray_id_set
*
* @since 1.8
*/
#define elm_obj_systray_id_get(ret) \
ELM_OBJ_SYSTRAY_ID(ELM_OBJ_SYSTRAY_SUB_ID_ID_GET), \
EO_TYPECHECK(const char **, ret)
/**
* @def elm_obj_systray_title_set
*
* Set the title of the Status Notifier Item.
*
* @param[in] title
*
* @see elm_obj_systray_title_get
*
* @since 1.8
*/
#define elm_obj_systray_title_set(title) \
ELM_OBJ_SYSTRAY_ID(ELM_OBJ_SYSTRAY_SUB_ID_TITLE_SET), \
EO_TYPECHECK(const char *, title)
/**
* @def elm_obj_systray_title_get
*
* Retrieve the title of the Status Notifier Item.
*
* @param[out] ret
*
* @see elm_obj_systray_title_set
*
* @since 1.8
*/
#define elm_obj_systray_title_get(ret) \
ELM_OBJ_SYSTRAY_ID(ELM_OBJ_SYSTRAY_SUB_ID_TITLE_GET), \
EO_TYPECHECK(const char **, ret)
/**
* @def elm_obj_systray_menu_set
*
* Set the object path of the D-Bus Menu that is to be show when the
* Status Notifier Item is activated by the user.
*
* @param[in] menu
*
* @see elm_obj_systray_menu_get
*
* @since 1.8
*/
#define elm_obj_systray_menu_set(menu) \
ELM_OBJ_SYSTRAY_ID(ELM_OBJ_SYSTRAY_SUB_ID_MENU_SET), \
EO_TYPECHECK(const Eo *, menu)
/**
* @def elm_obj_systray_menu_get
*
* Retrieve the object path of the D-Bus Menu currently in use.
*
* @param[out] ret
*
* @see elm_obj_systray_menu_set
*
* @since 1.8
*/
#define elm_obj_systray_menu_get(ret) \
ELM_OBJ_SYSTRAY_ID(ELM_OBJ_SYSTRAY_SUB_ID_MENU_GET), \
EO_TYPECHECK(const Eo **, ret)
/**
* @def elm_obj_systray_register
*
* Register this Status Notifier Item in the System Tray Watcher.
* This function should only be called after the event
* ELM_EVENT_SYSTRAY_READY is emitted.
*
* @param[out] ret
*
* @since 1.8
*/
#define elm_obj_systray_register(ret) \
ELM_OBJ_SYSTRAY_ID(ELM_OBJ_SYSTRAY_SUB_ID_REGISTER), \
EO_TYPECHECK(Eina_Bool *, ret)
/**
* Emitted when the systray is ready to be used by the application.
*/
EAPI extern int ELM_EVENT_SYSTRAY_READY;
/**
* Category of the Status Notifier Item.
*
* @since 1.8
*/
typedef enum _Elm_Systray_Category
{
ELM_SYSTRAY_CATEGORY_APP_STATUS, /**< Indicators of application status */
ELM_SYSTRAY_CATEGORY_COMMUNICATIONS, /**< Communications apps */
ELM_SYSTRAY_CATEGORY_SYS_SERVICES, /**< System Service apps */
ELM_SYSTRAY_CATEGORY_HARDWARE, /**< Hardware indicators */
ELM_SYSTRAY_CATEGORY_OTHER /**< Undefined category */
} Elm_Systray_Category;
/**
* Application status information.
*
* @since 1.8
*/
typedef enum _Elm_Systray_Status
{
ELM_SYSTRAY_STATUS_PASSIVE, /**< Passive (normal) */
ELM_SYSTRAY_STATUS_ACTIVE, /**< Active */
ELM_SYSTRAY_STATUS_ATTENTION /**< Needs Attention */
} Elm_Systray_Status;
#endif

View File

@ -0,0 +1,126 @@
#include "Elementary.h"
#include "elm_priv.h"
#include "elm_systray_watcher.h"
#ifdef ELM_EDBUS2
#define OBJ "/StatusNotifierWatcher"
#define BUS "org.kde.StatusNotifierWatcher"
#define INTERFACE "org.kde.StatusNotifierWatcher"
static Eina_Bool _elm_systray_watcher = EINA_FALSE;
static EDBus_Connection *_watcher_conn = NULL;
static EDBus_Object *_watcher_obj = NULL;
static EDBus_Proxy *_watcher_proxy = NULL;
static void
_status_notifier_item_register_cb(void *data EINA_UNUSED,
const EDBus_Message *msg,
EDBus_Pending *pending EINA_UNUSED)
{
const char *errname, *errmsg;
if (edbus_message_error_get(msg, &errname, &errmsg))
ERR("Edbus Error: %s %s", errname, errmsg);
}
#endif
Eina_Bool
_elm_systray_watcher_status_notifier_item_register(const char *obj)
{
#ifdef ELM_EDBUS2
EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
EINA_SAFETY_ON_NULL_RETURN_VAL(_watcher_proxy, EINA_FALSE);
if (!edbus_proxy_call(_watcher_proxy, "RegisterStatusNotifierItem",
_status_notifier_item_register_cb,
NULL, -1, "s", obj))
{
ERR("Error sending message: "INTERFACE".RegisterStatusNotifierItem.");
return EINA_FALSE;
}
return EINA_TRUE;
#else
(void) obj;
return EINA_FALSE;
#endif
}
#ifdef ELM_EDBUS2
static void
_release(void)
{
if (_watcher_proxy)
{
edbus_proxy_unref(_watcher_proxy);
_watcher_proxy = NULL;
}
if (_watcher_obj)
{
edbus_object_unref(_watcher_obj);
_watcher_obj = NULL;
}
}
static void
_update(void)
{
_release();
_watcher_obj = edbus_object_get(_watcher_conn, BUS, OBJ);
_watcher_proxy = edbus_proxy_get(_watcher_obj, INTERFACE);
ecore_event_add(ELM_EVENT_SYSTRAY_READY, NULL, NULL, NULL);
}
static void
_name_owner_changed_cb(void *data EINA_UNUSED,
const char *bus EINA_UNUSED,
const char *old_id EINA_UNUSED,
const char *new_id)
{
if ((!new_id) || (*new_id == '\0'))
_release();
else
_update();
}
#endif
Eina_Bool
_elm_systray_watcher_init(void)
{
#ifdef ELM_EDBUS2
if (_elm_systray_watcher) return EINA_TRUE;
if (!elm_need_edbus()) return EINA_FALSE;
_watcher_conn = edbus_connection_get(EDBUS_CONNECTION_TYPE_SESSION);
edbus_name_owner_changed_callback_add(_watcher_conn, BUS,
_name_owner_changed_cb, NULL,
EINA_TRUE);
_elm_systray_watcher = EINA_TRUE;
return EINA_TRUE;
#else
return EINA_FALSE;
#endif
}
void
_elm_systray_watcher_shutdown(void)
{
#ifdef ELM_EDBUS2
if (!_elm_systray_watcher) return;
_elm_systray_watcher = EINA_FALSE;
_release();
edbus_connection_unref(_watcher_conn);
_watcher_conn = NULL;
#endif
}

View File

@ -0,0 +1,10 @@
#ifndef ELM_SYSTRAY_WATCHER_H
#define ELM_SYSTRAY_WATCHER_H
Eina_Bool _elm_systray_watcher_status_notifier_item_register(const char *obj);
Eina_Bool _elm_systray_watcher_init(void);
void _elm_systray_watcher_shutdown(void);
#endif