e systray: Initial commit of dbus notifier host

Patch by: José Roberto de Souza  <zehortigoza@profusion.mobi>



SVN revision: 82111
This commit is contained in:
José Roberto de Souza 2013-01-03 22:07:26 +00:00 committed by Lucas De Marchi
parent 3c6d7db5a3
commit 3014654d58
7 changed files with 738 additions and 6 deletions

View File

@ -17,14 +17,15 @@ group { name: "e/modules/systray/main";
part { name: "e.xembed.size"; type: RECT; mouse_events: 0;
description { state: "default" 0.0;
visible: 0;
rel1.offset: -1 0;
rel2.offset: 0 -1;
rel1.to: "e.xembed.box";
rel2.to: "e.xembed.box";
align: 0.0 0.5;
}
}
part { name: "e.xembed.box"; type: BOX;
description { state: "default" 0.0;
rel1.to: "e.xembed.size";
rel2.to: "e.xembed.size";
rel2.relative: 0.0 1.0;
align: 0.0 0.5;
box {
layout: "horizontal";
padding: 2 0;
@ -40,78 +41,113 @@ group { name: "e/modules/systray/main";
}
}
}
part { name: "e.dbus_notifier.box"; type: BOX;
description { state: "default" 0.0;
align: 1.0 0.5;
rel1 {
relative: 1.0 0.0;
to: "e.xembed.box";
}
box {
layout: "horizontal";
padding: 2 0;
align: 0.5 0.5;
min: 1 1;
}
}
description { state: "vertical" 0.0;
inherit: "default" 0.0;
box {
layout: "vertical";
padding: 0 2;
}
}
}
}
programs {
program {
signal: "e,action,orient,horiz"; source: "e";
action: STATE_SET "default" 0.0;
target: "e.xembed.box";
target: "e.dbus_notifier.box";
}
program {
signal: "e,action,orient,vert"; source: "e";
action: STATE_SET "vertical" 0.0;
target: "e.xembed.box";
target: "e.dbus_notifier.box";
}
program {
signal: "e,action,orient,left"; source: "e";
action: STATE_SET "vertical" 0.0;
target: "e.xembed.box";
target: "e.dbus_notifier.box";
}
program {
signal: "e,action,orient,right"; source: "e";
action: STATE_SET "vertical" 0.0;
target: "e.xembed.box";
target: "e.dbus_notifier.box";
}
program {
signal: "e,action,orient,top"; source: "e";
action: STATE_SET "default" 0.0;
target: "e.xembed.box";
target: "e.dbus_notifier.box";
}
program {
signal: "e,action,orient,bottom"; source: "e";
action: STATE_SET "default" 0.0;
target: "e.xembed.box";
target: "e.dbus_notifier.box";
}
program {
signal: "e,action,orient,corner_tl"; source: "e";
action: STATE_SET "default" 0.0;
target: "e.xembed.box";
target: "e.dbus_notifier.box";
}
program {
signal: "e,action,orient,corner_tr"; source: "e";
action: STATE_SET "default" 0.0;
target: "e.xembed.box";
target: "e.dbus_notifier.box";
}
program {
signal: "e,action,orient,corner_bl"; source: "e";
action: STATE_SET "default" 0.0;
target: "e.xembed.box";
target: "e.dbus_notifier.box";
}
program {
signal: "e,action,orient,corner_br"; source: "e";
action: STATE_SET "default" 0.0;
target: "e.xembed.box";
target: "e.dbus_notifier.box";
}
program {
signal: "e,action,orient,corner_lt"; source: "e";
action: STATE_SET "vertical" 0.0;
target: "e.xembed.box";
target: "e.dbus_notifier.box";
}
program {
signal: "e,action,orient,corner_rt"; source: "e";
action: STATE_SET "vertical" 0.0;
target: "e.xembed.box";
target: "e.dbus_notifier.box";
}
program {
signal: "e,action,orient,corner_lb"; source: "e";
action: STATE_SET "vertical" 0.0;
target: "e.xembed.box";
target: "e.dbus_notifier.box";
}
program {
signal: "e,action,orient,corner_rb"; source: "e";
action: STATE_SET "vertical" 0.0;
target: "e.xembed.box";
target: "e.dbus_notifier.box";
}
}
}

View File

@ -9,7 +9,10 @@ systraypkg_LTLIBRARIES = systray/module.la
systray_module_la_SOURCES = systray/e_mod_main.h \
systray/e_mod_main.c \
systray/e_mod_xembed.c
systray/e_mod_xembed.c \
systray/e_mod_notifier_host_private.h \
systray/e_mod_notifier_host.c \
systray/e_mod_notifier_host_dbus.c
.PHONY: systray install-systray
systray: $(systraypkg_LTLIBRARIES) $(systray_DATA)

View File

@ -6,6 +6,7 @@ struct _Instance
E_Container *con;
Evas *evas;
Instance_Xembed *xembed;
Instance_Notifier_Host *notifier;
struct
{
Evas_Object *gadget;
@ -211,6 +212,7 @@ _gc_init(E_Gadcon *gc, const char *name, const char *id, const char *style)
_systray_cb_mouse_down, inst);
inst->xembed = systray_xembed_new(inst);
inst->notifier = systray_notifier_host_new(inst, inst->gcc->gadcon);
instance = inst;
return inst->gcc;
@ -228,6 +230,7 @@ _gc_shutdown(E_Gadcon_Client *gcc)
return;
systray_xembed_free(inst->xembed);
systray_notifier_host_free(inst->notifier);
evas_object_del(inst->ui.gadget);
@ -449,6 +452,16 @@ systray_edje_box_append(const Instance *inst, const char *part,
edje_object_part_box_append(inst->ui.gadget, part, child);
}
void
systray_edje_box_remove(const Instance *inst, const char *part,
Evas_Object *child)
{
EINA_SAFETY_ON_NULL_RETURN(inst);
EINA_SAFETY_ON_NULL_RETURN(part);
EINA_SAFETY_ON_NULL_RETURN(child);
edje_object_part_box_remove(inst->ui.gadget, part, child);
}
int
systray_manager_number_get(const Instance *inst)
{

View File

@ -11,6 +11,7 @@ EAPI int e_modapi_save(E_Module *m);
typedef struct _Instance Instance;
typedef struct _Instance_Xembed Instance_Xembed;
typedef struct _Instance_Notifier_Host Instance_Notifier_Host;
E_Gadcon_Orient systray_orient_get(const Instance *inst);
const E_Gadcon *systray_gadcon_get(const Instance *inst);
@ -21,6 +22,7 @@ Evas *systray_evas_get(const Instance *inst);
Evas_Object *systray_edje_get(const Instance *inst);
void systray_edje_emit(const Instance *inst, const char *sig);
void systray_edje_box_append(const Instance *inst, const char *part, Evas_Object *child);
void systray_edje_box_remove(const Instance *inst, const char *part, Evas_Object *child);
int systray_manager_number_get(const Instance *inst);
Ecore_X_Window systray_root_get(const Instance *inst);
@ -33,6 +35,9 @@ void systray_xembed_free(Instance_Xembed *xembed);
void systray_xembed_orient_set(Instance_Xembed *xembed, E_Gadcon_Orient orient);
void systray_xembed_size_updated(Instance_Xembed *xembed);
Instance_Notifier_Host *systray_notifier_host_new(Instance *inst, E_Gadcon *gadcon);
void systray_notifier_host_free(Instance_Notifier_Host *notifier);
/**
* @addtogroup Optional_Gadgets
* @{

View File

@ -0,0 +1,192 @@
#include "e_mod_notifier_host_private.h"
#define WATCHER_BUS "org.kde.StatusNotifierWatcher"
#define WATCHER_PATH "/StatusNotifierWatcher"
#define WATCHER_IFACE "org.kde.StatusNotifierWatcher"
#define ITEM_IFACE "org.kde.StatusNotifierItem"
const char *Category_Name[] = {
"unknown", "SystemServices"
};
const char *Status_Names[] = {
"unknown", "Active", "Passive", "NeedsAttention"
};
static const char *box_part_name = "e.dbus_notifier.box";
void
systray_notifier_item_free(Notifier_Item *item)
{
EDBus_Object *obj;
EDBus_Signal_Handler *sig;
evas_object_del(item->icon_object);
if (item->menu_path)
{
e_dbusmenu_unload(item->menu_data);
//TODO free evas_object of menu
}
eina_stringshare_del(item->bus_id);
eina_stringshare_del(item->path);
if (item->attention_icon_name)
eina_stringshare_del(item->attention_icon_name);
if (item->icon_name)
eina_stringshare_del(item->icon_name);
if (item->icon_path)
eina_stringshare_del(item->icon_path);
if (item->id)
eina_stringshare_del(item->id);
if (item->menu_path)
eina_stringshare_del(item->menu_path);
if (item->title)
eina_stringshare_del(item->title);
EINA_LIST_FREE(item->signals, sig)
edbus_signal_handler_del(sig);
obj = edbus_proxy_object_get(item->proxy);
edbus_proxy_unref(item->proxy);
edbus_object_unref(obj);
item->host_inst->items_list = eina_inlist_remove(item->host_inst->items_list,
EINA_INLIST_GET(item));
systray_size_updated(item->host_inst->inst);
free(item);
}
static void
image_load(const char *name, const char *path, Evas_Object *image)
{
if (path && strlen(path))
{
char buf[1024];
sprintf(buf, "%s/%s", path, name);
if (!e_icon_file_set(image, buf))
e_util_icon_theme_set(image, "dialog-error");
return;
}
if (!e_util_icon_theme_set(image, name))
e_util_icon_theme_set(image, "dialog-error");
}
void
_clicked_item_cb(void *data __UNUSED__, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event)
{
Notifier_Item *item = data;
Evas_Event_Mouse_Down *ev = event;
if (ev->button == 1)
{
DBG("left %s", item->id);
return;
}
}
static void
image_scale(Notifier_Item *item)
{
Evas_Coord sz;
switch (systray_gadcon_get(item->host_inst->inst)->orient)
{
case E_GADCON_ORIENT_HORIZ:
case E_GADCON_ORIENT_TOP:
case E_GADCON_ORIENT_BOTTOM:
case E_GADCON_ORIENT_CORNER_TL:
case E_GADCON_ORIENT_CORNER_TR:
case E_GADCON_ORIENT_CORNER_BL:
case E_GADCON_ORIENT_CORNER_BR:
sz = systray_gadcon_get(item->host_inst->inst)->shelf->h;
break;
case E_GADCON_ORIENT_VERT:
case E_GADCON_ORIENT_LEFT:
case E_GADCON_ORIENT_RIGHT:
case E_GADCON_ORIENT_CORNER_LT:
case E_GADCON_ORIENT_CORNER_RT:
case E_GADCON_ORIENT_CORNER_LB:
case E_GADCON_ORIENT_CORNER_RB:
default:
sz = systray_gadcon_get(item->host_inst->inst)->shelf->w;
}
sz = sz - 5;
evas_object_resize(item->icon_object, sz, sz);
}
void
systray_notifier_item_update(Notifier_Item *item)
{
if (!item->icon_object)
{
item->icon_object = e_icon_add(evas_object_evas_get(item->host_inst->edje));
EINA_SAFETY_ON_NULL_RETURN(item->icon_object);
image_scale(item);
systray_size_updated(item->host_inst->inst);
evas_object_event_callback_add(item->icon_object, EVAS_CALLBACK_MOUSE_DOWN,
_clicked_item_cb, item);
}
switch (item->status)
{
case STATUS_ACTIVE:
{
image_load(item->icon_name, item->icon_path, item->icon_object);
if (!item->in_box)
{
systray_edje_box_append(item->host_inst->inst, box_part_name,
item->icon_object);
evas_object_show(item->icon_object);
}
item->in_box = EINA_TRUE;
break;
}
case STATUS_PASSIVE:
{
if (item->in_box)
{
systray_edje_box_remove(item->host_inst->inst, box_part_name,
item->icon_object);
evas_object_hide(item->icon_object);
}
item->in_box = EINA_FALSE;
break;
}
case STATUS_ATTENTION:
{
image_load(item->attention_icon_name, item->icon_path,
item->icon_object);
if (!item->in_box)
{
systray_edje_box_append(item->host_inst->inst, box_part_name,
item->icon_object);
evas_object_show(item->icon_object);
}
item->in_box = EINA_TRUE;
break;
}
default:
{
ERR("Status unexpected.");
break;
}
}
systray_size_updated(item->host_inst->inst);
}
Instance_Notifier_Host *
systray_notifier_host_new(Instance *inst, E_Gadcon *gadcon)
{
Instance_Notifier_Host *host_inst = NULL;
host_inst = calloc(1, sizeof(Instance_Notifier_Host));
EINA_SAFETY_ON_NULL_RETURN_VAL(host_inst, NULL);
host_inst->inst = inst;
host_inst->edje = systray_edje_get(inst);
host_inst->gadcon = gadcon;
systray_notifier_dbus_init(host_inst);
return host_inst;
}
void
systray_notifier_host_free(Instance_Notifier_Host *notifier)
{
systray_notifier_dbus_shutdown(notifier);
free(notifier);
}

View File

@ -0,0 +1,429 @@
#include "e_mod_notifier_host_private.h"
#define WATCHER_BUS "org.kde.StatusNotifierWatcher"
#define WATCHER_PATH "/StatusNotifierWatcher"
#define WATCHER_IFACE "org.kde.StatusNotifierWatcher"
#define ITEM_IFACE "org.kde.StatusNotifierItem"
#define HOST_REGISTRER "/bla" //TODO check what watcher expect we send to him
extern const char *Category_Name[];
extern const char *Status_Names[];
typedef struct _Notifier_Host_Data {
Instance_Notifier_Host *host_inst;
void *data;
} Notifier_Host_Data;
static Eina_Bool
service_string_parse(const char *item, const char **path, const char **bus_id)
{
unsigned i;
for (i = 0; i < strlen(item); i++)
{
if (item[i] != '/')
continue;
*path = eina_stringshare_add(item+i);
*bus_id = eina_stringshare_nprintf(i+1, "%s", item);
return EINA_TRUE;
}
return EINA_FALSE;
}
static Notifier_Item *
notifier_item_find(const char *path, const char *bus_id, Instance_Notifier_Host *host_inst)
{
Notifier_Item *item;
EINA_INLIST_FOREACH(host_inst->items_list, item)
{
if (item->bus_id == bus_id && item->path == path)
return item;
}
return NULL;
}
static int
id_find(const char *text, const char *array_of_names[], unsigned max)
{
unsigned i;
for (i = 0; i < max; i++)
{
if (strcmp(text, array_of_names[i]))
continue;
return i;
}
return 0;
}
static void
item_prop_get(void *data, const void *key, EDBus_Message_Iter *var)
{
Notifier_Item *item = data;
if (!strcmp(key, "Category"))
{
const char *category;
edbus_message_iter_arguments_get(var, "s", &category);
item->category = id_find(category, Category_Name, CATEGORY_LAST);
}
else if (!strcmp(key, "IconName"))
{
const char *name;
edbus_message_iter_arguments_get(var, "s", &name);
eina_stringshare_replace(&item->icon_name, name);
}
else if (!strcmp(key, "AttentionIconName"))
{
const char *name;
edbus_message_iter_arguments_get(var, "s", &name);
eina_stringshare_replace(&item->attention_icon_name, name);
}
else if (!strcmp(key, "IconThemePath"))
{
const char *path;
edbus_message_iter_arguments_get(var, "s", &path);
eina_stringshare_replace(&item->icon_path, path);
}
else if (!strcmp(key, "Menu"))
{
const char *path;
edbus_message_iter_arguments_get(var, "o", &path);
eina_stringshare_replace(&item->menu_path, path);
}
else if (!strcmp(key, "Status"))
{
const char *status;
edbus_message_iter_arguments_get(var, "s", &status);
item->status = id_find(status, Status_Names, STATUS_LAST);
}
else if (!strcmp(key, "Id"))
{
const char *id;
edbus_message_iter_arguments_get(var, "s", &id);
eina_stringshare_replace(&item->id, id);
}
else if (!strcmp(key, "Title"))
{
const char *title;
edbus_message_iter_arguments_get(var, "s", &title);
eina_stringshare_replace(&item->title, title);
}
}
//debug
static void
render_menu_itens(void *data, E_DBusMenu_Item *new_root_item)
{
Notifier_Item *item = data;
E_DBusMenu_Item *child;
//TODO create evas_object of menu
printf("icon = %s\n", item->id);
EINA_SAFETY_ON_FALSE_RETURN(new_root_item->is_submenu);
EINA_INLIST_FOREACH(new_root_item->sub_items, child)
{
if (child->type == E_DBUSMENU_ITEM_TYPE_SEPARATOR)
printf("\tseparator\n");
else
{
printf("\tLabel= %s | Icon name=%s | Toggle type=%d | Toggle state=%d | Visible = %d | Enabled = %d\n",
child->label, child->icon_name, child->toggle_type,
child->toggle_state, child->visible, child->enabled);
}
}
}
static void
props_changed(void *data, const EDBus_Message *msg)
{
Notifier_Item *item = data;
const char *interface, *menu = item->menu_path;
EDBus_Message_Iter *changed, *invalidate;
if (!edbus_message_arguments_get(msg, "sa{sv}as", &interface, &changed, &invalidate))
{
ERR("Error reading message");
return;
}
edbus_message_iter_dict_iterate(changed, "sv", item_prop_get, item);
if (menu != item->menu_path)
{
EDBus_Connection *conn = edbus_object_connection_get(edbus_proxy_object_get(item->proxy));
e_dbusmenu_unload(item->menu_data);
item->menu_data = e_dbusmenu_load(conn, item->bus_id, item->menu_path, item);
}
}
static void
props_get_all_cb(void *data, const EDBus_Message *msg, EDBus_Pending *pending EINA_UNUSED)
{
const char *error, *error_name;
EDBus_Message_Iter *dict;
Notifier_Item *item = data;
EDBus_Connection *conn;
if (edbus_message_error_get(msg, &error, &error_name))
{
ERR("%s %s", error, error_name);
return;
}
if (!edbus_message_arguments_get(msg, "a{sv}", &dict))
{
ERR("Error getting arguments.");
return;
}
edbus_message_iter_dict_iterate(dict, "sv", item_prop_get, item);
if (!item->menu_path)
ERR("Notifier item %s dont have menu path.", item->menu_path);
conn = edbus_object_connection_get(edbus_proxy_object_get(item->proxy));
item->menu_data = e_dbusmenu_load(conn, item->bus_id, item->menu_path, item);
e_dbusmenu_update_cb_set(item->menu_data, render_menu_itens);
systray_notifier_item_update(item);
}
static Eina_Bool
basic_prop_get(const char *propname, void *data, const EDBus_Message *msg)
{
EDBus_Message_Iter *var;
const char *error, *error_msg;
if (edbus_message_error_get(msg, &error, &error_msg))
{
ERR("%s %s", error, error_msg);
return EINA_FALSE;
}
if (!edbus_message_arguments_get(msg, "v", &var))
{
ERR("Error reading message.");
return EINA_FALSE;
}
item_prop_get(data, propname, var);
return EINA_TRUE;
}
static void
attention_icon_get_cb(void *data, const EDBus_Message *msg, EDBus_Pending *pending EINA_UNUSED)
{
Notifier_Item *item = data;
const char *propname = "AttentionIconName";
basic_prop_get(propname, item, msg);
systray_notifier_item_update(item);
}
static void
new_attention_icon_cb(void *data, const EDBus_Message *msg EINA_UNUSED)
{
Notifier_Item *item = data;
edbus_proxy_property_get(item->proxy, "AttentionIconName", attention_icon_get_cb, item);
}
static void
icon_get_cb(void *data, const EDBus_Message *msg, EDBus_Pending *pending EINA_UNUSED)
{
Notifier_Item *item = data;
const char *propname = "IconName";
basic_prop_get(propname, item, msg);
systray_notifier_item_update(item);
}
static void
new_icon_cb(void *data, const EDBus_Message *msg EINA_UNUSED)
{
Notifier_Item *item = data;
edbus_proxy_property_get(item->proxy, "IconName", icon_get_cb, item);
}
static void
title_get_cb(void *data, const EDBus_Message *msg, EDBus_Pending *pending EINA_UNUSED)
{
Notifier_Item *item = data;
const char *propname = "Title";
basic_prop_get(propname, item, msg);
systray_notifier_item_update(item);
}
static void
new_title_cb(void *data, const EDBus_Message *msg EINA_UNUSED)
{
Notifier_Item *item = data;
edbus_proxy_property_get(item->proxy, "Title", title_get_cb, item);
}
static void
new_icon_theme_path_cb(void *data, const EDBus_Message *msg)
{
Notifier_Item *item = data;
const char *path;
if (!edbus_message_arguments_get(msg, "s", &path))
{
ERR("Error reading message.");
return;
}
eina_stringshare_replace(&item->icon_path, path);
systray_notifier_item_update(item);
}
static void
new_status_cb(void *data, const EDBus_Message *msg)
{
Notifier_Item *item = data;
const char *status;
if (!edbus_message_arguments_get(msg, "s", &status))
{
ERR("Error reading message.");
return;
}
item->status = id_find(status, Status_Names, STATUS_LAST);
systray_notifier_item_update(item);
}
static void
notifier_item_add(const char *path, const char *bus_id, Instance_Notifier_Host *host_inst)
{
EDBus_Proxy *proxy;
Notifier_Item *item = calloc(1, sizeof(Notifier_Item));
EDBus_Signal_Handler *s;
EINA_SAFETY_ON_NULL_RETURN(item);
item->path = path;
item->bus_id = bus_id;
host_inst->items_list = eina_inlist_append(host_inst->items_list,
EINA_INLIST_GET(item));
item->host_inst = host_inst;
proxy = edbus_proxy_get(edbus_object_get(host_inst->conn, bus_id, path),
ITEM_IFACE);
item->proxy = proxy;
edbus_proxy_property_get_all(proxy, props_get_all_cb, item);
s = edbus_proxy_properties_changed_callback_add(proxy, props_changed, item);
item->signals = eina_list_append(item->signals, s);
s = edbus_proxy_signal_handler_add(proxy, "NewAttentionIcon",
new_attention_icon_cb, item);
item->signals = eina_list_append(item->signals, s);
s = edbus_proxy_signal_handler_add(proxy, "NewIcon",
new_icon_cb, item);
item->signals = eina_list_append(item->signals, s);
s = edbus_proxy_signal_handler_add(proxy, "NewIconThemePath",
new_icon_theme_path_cb, item);
item->signals = eina_list_append(item->signals, s);
s = edbus_proxy_signal_handler_add(proxy, "NewStatus", new_status_cb, item);
item->signals = eina_list_append(item->signals, s);
s = edbus_proxy_signal_handler_add(proxy, "NewTitle", new_title_cb, item);
item->signals = eina_list_append(item->signals, s);
}
static void
notifier_item_add_cb(void *data, const EDBus_Message *msg)
{
const char *item, *bus, *path;
Instance_Notifier_Host *host_inst = data;
if (!edbus_message_arguments_get(msg, "s", &item))
{
ERR("Error getting arguments from msg.");
return;
}
DBG("add %s", item);
if (service_string_parse(item, &path, &bus))
notifier_item_add(path, bus, host_inst);
}
static void
notifier_item_del_cb(void *data, const EDBus_Message *msg)
{
const char *service, *bus, *path;
Notifier_Item *item;
Instance_Notifier_Host *host_inst = data;
if (!edbus_message_arguments_get(msg, "s", &service))
{
ERR("Error getting arguments from msg.");
return;
}
DBG("service %s", service);
if (!service_string_parse(service, &path, &bus))
return;
item = notifier_item_find(path, bus, host_inst);
if (item)
systray_notifier_item_free(item);
eina_stringshare_del(path);
eina_stringshare_del(bus);
}
static void
notifier_items_get_cb(void *data, const EDBus_Message *msg, EDBus_Pending *pending EINA_UNUSED)
{
const char *item;
const char *error, *error_msg;
EDBus_Message_Iter *array, *variant;
Instance_Notifier_Host *host_inst = data;
if (edbus_message_error_get(msg, &error, &error_msg))
{
ERR("%s %s", error, error_msg);
return;
}
if (!edbus_message_arguments_get(msg, "v", &variant))
{
ERR("Error getting arguments from msg.");
return;
}
if (!edbus_message_iter_arguments_get(variant, "as", &array))
{
ERR("Error getting arguments from msg.");
return;
}
while (edbus_message_iter_get_and_next(array, 's', &item))
{
const char *bus, *path;
if (service_string_parse(item, &path, &bus))
notifier_item_add(path, bus, host_inst);
}
}
void systray_notifier_dbus_init(Instance_Notifier_Host *host_inst)
{
EDBus_Object *obj;
edbus_init();
host_inst->conn = edbus_connection_get(EDBUS_CONNECTION_TYPE_SESSION);
obj = edbus_object_get(host_inst->conn, WATCHER_BUS, WATCHER_PATH);
host_inst->watcher = edbus_proxy_get(obj, WATCHER_IFACE);
edbus_proxy_call(host_inst->watcher, "RegisterStatusNotifierHost", NULL, NULL, -1, "s",
HOST_REGISTRER);
edbus_proxy_property_get(host_inst->watcher, "RegisteredStatusNotifierItems",
notifier_items_get_cb, host_inst);
edbus_proxy_signal_handler_add(host_inst->watcher, "StatusNotifierItemRegistered",
notifier_item_add_cb, host_inst);
edbus_proxy_signal_handler_add(host_inst->watcher, "StatusNotifierItemUnregistered",
notifier_item_del_cb, host_inst);
}
void systray_notifier_dbus_shutdown(Instance_Notifier_Host *host_inst)
{
Eina_Inlist *safe_list;
Notifier_Item *item;
EDBus_Object *obj;
EINA_INLIST_FOREACH_SAFE(host_inst->items_list, safe_list, item)
systray_notifier_item_free(item);
obj = edbus_proxy_object_get(host_inst->watcher);
edbus_proxy_unref(host_inst->watcher);
edbus_object_unref(obj);
edbus_connection_unref(host_inst->conn);
edbus_shutdown();
}

View File

@ -0,0 +1,54 @@
#include "e_mod_main.h"
typedef enum {
CATEGORY_UNKNOWN = 0,
CATEGORY_SYSTEM_SERVICES,
CATEGORY_LAST
} Category;
typedef enum {
STATUS_UNKNOWN = 0,
STATUS_ACTIVE,
STATUS_PASSIVE,
STATUS_ATTENTION,
STATUS_LAST
} Status;
struct _Instance_Notifier_Host
{
Instance *inst;
Eina_Inlist *items_list;
const Evas_Object *box;
const Evas_Object *edje;
EDBus_Connection *conn;
EDBus_Proxy *watcher;
E_Gadcon *gadcon;
};
typedef struct _Notifier_Item
{
EINA_INLIST;
const char *bus_id;
const char *path;
EDBus_Proxy *proxy;
Category category;
Status status;
const char *id;
const char *title;
const char *icon_name;
const char *attention_icon_name;
const char *icon_path;
Evas_Object *icon_object;
Instance_Notifier_Host *host_inst;
const char *menu_path;
E_DBusMenu_Ctx *menu_data;
Eina_List *signals;
Eina_Bool in_box;
} Notifier_Item;
void systray_notifier_item_update(Notifier_Item *item);
void systray_notifier_item_free(Notifier_Item *item);
void systray_notifier_dbus_init(Instance_Notifier_Host *host_inst);
void systray_notifier_dbus_shutdown(Instance_Notifier_Host *host_inst);