[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:
parent
58b2fc2cd2
commit
abcc99fcd1
|
@ -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).
|
||||
|
|
|
@ -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:
|
||||
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
|
@ -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 */
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
*
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
|
@ -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
|
|
@ -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
|
||||
}
|
|
@ -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
|
Loading…
Reference in New Issue