rewrite host side

This commit is contained in:
Marcel Hollerbach 2016-01-10 15:13:10 +01:00
parent 6107f2fbe0
commit da51b1a002
6 changed files with 283 additions and 373 deletions

View File

@ -5,7 +5,7 @@ static const char _name[] = "systray";
static const char _group_gadget[] = "e/modules/systray/main"; static const char _group_gadget[] = "e/modules/systray/main";
static const char _sig_source[] = "e"; static const char _sig_source[] = "e";
static E_Module *systray_mod = NULL; E_Module *systray_mod = NULL;
static Systray_Context *ctx = NULL; static Systray_Context *ctx = NULL;
static char tmpbuf[4096]; /* general purpose buffer, just use immediately */ static char tmpbuf[4096]; /* general purpose buffer, just use immediately */
@ -49,7 +49,7 @@ _systray_menu_new(Instance *inst, Evas_Event_Mouse_Down *ev)
e_gadcon_canvas_zone_geometry_get(inst->gcc->gadcon, &x, &y, NULL, NULL); e_gadcon_canvas_zone_geometry_get(inst->gcc->gadcon, &x, &y, NULL, NULL);
e_menu_activate_mouse(m, zone, x + ev->output.x, y + ev->output.y, e_menu_activate_mouse(m, zone, x + ev->output.x, y + ev->output.y,
1, 1, E_MENU_POP_DIRECTION_AUTO, ev->timestamp); 1, 1, E_MENU_POP_DIRECTION_AUTO, ev->timestamp);
evas_event_feed_mouse_up(inst->gcc->gadcon->evas, ev->button, evas_event_feed_mouse_up(e_comp->evas, ev->button,
EVAS_BUTTON_NONE, ev->timestamp, NULL); EVAS_BUTTON_NONE, ev->timestamp, NULL);
} }
@ -63,108 +63,43 @@ _systray_cb_mouse_down(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA
_systray_menu_new(inst, ev); _systray_menu_new(inst, ev);
} }
static void void
_systray_theme(Evas_Object *o, const char *shelf_style, const char *gc_style) _hack_get_me_the_correct_min_size(Edje_Object *obj)
{ {
const char base_theme[] = "base/theme/modules/systray"; Evas_Coord w, h;
const char *path = _systray_theme_path(); E_Gadcon_Client *client;
char buf[128], *p;
size_t len, avail;
len = eina_strlcpy(buf, _group_gadget, sizeof(buf)); client = evas_object_data_get(obj, "gadcon");
if (len >= sizeof(buf)) evas_object_size_hint_min_get(obj, &w, &h);
goto fallback; e_gadcon_client_min_size_set(client, MAX(w, SYSTRAY_MIN_W), MAX(h, SYSTRAY_MIN_H));
p = buf + len; printf("MIAU %d %d\n", w ,h);
*p = '/';
p++;
avail = sizeof(buf) - len - 2;
if (shelf_style && gc_style)
{
size_t r;
r = snprintf(p, avail, "%s/%s", shelf_style, gc_style);
if (r < avail && e_theme_edje_object_set(o, base_theme, buf))
return;
}
if (shelf_style)
{
size_t r;
r = eina_strlcpy(p, shelf_style, avail);
if (r < avail && e_theme_edje_object_set(o, base_theme, buf))
return;
}
if (gc_style)
{
size_t r;
r = eina_strlcpy(p, gc_style, avail);
if (r < avail && e_theme_edje_object_set(o, base_theme, buf))
return;
}
if (e_theme_edje_object_set(o, base_theme, _group_gadget))
return;
if (shelf_style && gc_style)
{
size_t r;
r = snprintf(p, avail, "%s/%s", shelf_style, gc_style);
if (r < avail && edje_object_file_set(o, path, buf))
return;
}
if (shelf_style)
{
size_t r;
r = eina_strlcpy(p, shelf_style, avail);
if (r < avail && edje_object_file_set(o, path, buf))
return;
}
if (gc_style)
{
size_t r;
r = eina_strlcpy(p, gc_style, avail);
if (r < avail && edje_object_file_set(o, path, buf))
return;
}
fallback:
edje_object_file_set(o, path, _group_gadget);
} }
static E_Gadcon_Client * static E_Gadcon_Client *
_gc_init(E_Gadcon *gc, const char *name, const char *id, const char *style) _gc_init(E_Gadcon *gc, const char *name, const char *id, const char *style)
{ {
Instance *inst; Instance *inst;
Evas_Object *content;
// fprintf(stderr, "SYSTRAY: init name=%s, id=%s, style=%s\n", name, id, style); // fprintf(stderr, "SYSTRAY: init name=%s, id=%s, style=%s\n", name, id, style);
if (!systray_mod)
return NULL;
inst = E_NEW(Instance, 1); inst = E_NEW(Instance, 1);
if (!inst) if (!inst)
return NULL; return NULL;
inst->evas = gc->evas;
if (!e_comp)
{
E_FREE(inst);
return NULL;
}
inst->ui.gadget = edje_object_add(inst->evas); inst->ui.gadget = content = systray_notifier_host_new(gc->shelf ? gc->shelf->style : NULL, style);
_systray_theme(inst->ui.gadget, gc->shelf ? gc->shelf->style : NULL, style); inst->gcc = e_gadcon_client_new(gc, name, id, style, content);
inst->gcc = e_gadcon_client_new(gc, name, id, style, inst->ui.gadget);
if (!inst->gcc) if (!inst->gcc)
{ {
evas_object_del(inst->ui.gadget); evas_object_del(inst->ui.gadget);
E_FREE(inst); E_FREE(inst);
return NULL; return NULL;
} }
evas_object_data_set(content, "gadcon", inst->gcc);
e_gadcon_client_min_size_set(inst->gcc, SYSTRAY_MIN_W, SYSTRAY_MIN_H); e_gadcon_client_min_size_set(inst->gcc, SYSTRAY_MIN_W, SYSTRAY_MIN_H);
inst->gcc->data = inst; inst->gcc->data = inst;
@ -172,8 +107,6 @@ _gc_init(E_Gadcon *gc, const char *name, const char *id, const char *style)
evas_object_event_callback_add(inst->ui.gadget, EVAS_CALLBACK_MOUSE_DOWN, evas_object_event_callback_add(inst->ui.gadget, EVAS_CALLBACK_MOUSE_DOWN,
_systray_cb_mouse_down, inst); _systray_cb_mouse_down, inst);
inst->notifier = systray_notifier_host_new(inst, inst->gcc->gadcon);
return inst->gcc; return inst->gcc;
} }
@ -187,14 +120,8 @@ _gc_shutdown(E_Gadcon_Client *gcc)
if (!inst) if (!inst)
return; return;
systray_notifier_host_free(inst->notifier);
evas_object_del(inst->ui.gadget); evas_object_del(inst->ui.gadget);
if (instance == inst)
instance = NULL;
if (inst->job.size_apply) if (inst->job.size_apply)
ecore_job_del(inst->job.size_apply); ecore_job_del(inst->job.size_apply);
@ -334,7 +261,7 @@ e_modapi_init(E_Module *m)
printf("Starting watcher failed\n"); printf("Starting watcher failed\n");
} }
return ctx; return m;
} }
E_API int E_API int
@ -345,9 +272,6 @@ e_modapi_shutdown(E_Module *m EINA_UNUSED)
systray_notifier_host_shutdown(); systray_notifier_host_shutdown();
E_CONFIG_DD_FREE(ctx->conf_edd);
E_CONFIG_DD_FREE(ctx->notifier_item_edd);
free(ctx->config);
free(ctx); free(ctx);
return 1; return 1;
} }
@ -355,7 +279,7 @@ e_modapi_shutdown(E_Module *m EINA_UNUSED)
E_API int E_API int
e_modapi_save(E_Module *m EINA_UNUSED) e_modapi_save(E_Module *m EINA_UNUSED)
{ {
e_config_domain_save(_name, ctx->conf_edd, ctx->config); //e_config_domain_save(_name, ctx->conf_edd, ctx->config);
return 1; return 1;
} }
@ -431,13 +355,6 @@ systray_edje_box_remove(const Instance *inst, Evas_Object *child)
edje_object_part_box_remove(inst->ui.gadget, "box", child); edje_object_part_box_remove(inst->ui.gadget, "box", child);
} }
Ecore_X_Window
systray_root_get(const Instance *inst)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(inst, 0);
return e_comp->root;
}
static void static void
_systray_size_apply_do(Instance *inst) _systray_size_apply_do(Instance *inst)
{ {

View File

@ -59,22 +59,14 @@ E_Gadcon_Client *systray_gadcon_client_get(const Instance *inst);
const char *systray_style_get(const Instance *inst); const char *systray_style_get(const Instance *inst);
void systray_size_updated(Instance *inst); void systray_size_updated(Instance *inst);
Evas *systray_evas_get(const Instance *inst); Evas *systray_evas_get(const Instance *inst);
Evas_Object *systray_edje_get(const Instance *inst);
const Evas_Object *systray_box_get(const Instance *inst);
void systray_edje_box_append(const Instance *inst, Evas_Object *child);
void systray_edje_box_remove(const Instance *inst, Evas_Object *child);
void systray_edje_box_prepend(const Instance *inst, Evas_Object *child);
Ecore_X_Window systray_root_get(const Instance *inst);
Instance_Notifier_Host *systray_notifier_host_new(Instance *inst, E_Gadcon *gadcon);
void systray_notifier_host_free(Instance_Notifier_Host *notifier);
void systray_notifier_host_init(void); void systray_notifier_host_init(void);
void systray_notifier_host_shutdown(void); void systray_notifier_host_shutdown(void);
Evas_Object* systray_notifier_host_new(const char *shelfstyle, const char *style);
EINTERN Systray_Context *systray_ctx_get(void); EINTERN Systray_Context *systray_ctx_get(void);
extern Instance *instance; extern E_Module *systray_mod;
/** /**
* @addtogroup Optional_Gadgets * @addtogroup Optional_Gadgets
* @{ * @{

View File

@ -1,11 +1,6 @@
#include "e_mod_main.h"
#include "e_mod_notifier_host_private.h" #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_Names[] = { const char *Category_Names[] = {
"unknown", "SystemServices", NULL "unknown", "SystemServices", NULL
}; };
@ -14,55 +9,81 @@ const char *Status_Names[] = {
"unknown", "Active", "Passive", "NeedsAttention", NULL "unknown", "Active", "Passive", "NeedsAttention", NULL
}; };
static Context_Notifier_Host *ctx = NULL; static Eina_List *traybars; //known traybars
static Eina_List *items; //list of known Notifier_Item items
static void _systray_size_apply_do(Edje_Object *obj);
void static void
systray_notifier_item_free(Notifier_Item *item) _systray_theme(Evas_Object *o, const char *shelf_style, const char *gc_style)
{ {
Eldbus_Object *obj; const char base_theme[] = "base/theme/modules/systray";
Eldbus_Signal_Handler *sig; char path[PATH_MAX];
Instance_Notifier_Host *host_inst; char buf[128], *p;
EINA_INLIST_FOREACH(ctx->instances, host_inst) size_t len, avail;
snprintf(path, sizeof(path), "%s/e-module-systray.edj", e_module_dir_get(systray_mod));
len = eina_strlcpy(buf, "e/modules/systray/main", sizeof(buf));
if (len >= sizeof(buf))
goto fallback;
p = buf + len;
*p = '/';
p++;
avail = sizeof(buf) - len - 2;
if (shelf_style && gc_style)
{ {
Notifier_Item_Icon *ii; size_t r;
EINA_INLIST_FOREACH(host_inst->ii_list, ii) r = snprintf(p, avail, "%s/%s", shelf_style, gc_style);
{ if (r < avail && e_theme_edje_object_set(o, base_theme, buf))
if (ii->item == item) return;
break;
}
if (!ii)
continue;
host_inst->ii_list = eina_inlist_remove(host_inst->ii_list,
EINA_INLIST_GET(ii));
evas_object_del(ii->icon);
free(ii);
systray_size_updated(host_inst->inst);
} }
if (item->menu_path)
e_dbusmenu_unload(item->menu_data); if (shelf_style)
eina_stringshare_del(item->bus_id); {
eina_stringshare_del(item->path); size_t r;
free(item->imgdata); r = eina_strlcpy(p, shelf_style, avail);
free(item->attnimgdata); if (r < avail && e_theme_edje_object_set(o, base_theme, buf))
if (item->attention_icon_name) return;
eina_stringshare_del(item->attention_icon_name); }
if (item->icon_name)
eina_stringshare_del(item->icon_name); if (gc_style)
if (item->icon_path) {
eina_stringshare_del(item->icon_path); size_t r;
if (item->id) r = eina_strlcpy(p, gc_style, avail);
eina_stringshare_del(item->id); if (r < avail && e_theme_edje_object_set(o, base_theme, buf))
if (item->menu_path) return;
eina_stringshare_del(item->menu_path); }
if (item->title)
eina_stringshare_del(item->title); if (e_theme_edje_object_set(o, base_theme, "e/modules/systray/main"))
EINA_LIST_FREE(item->signals, sig) return;
eldbus_signal_handler_del(sig);
obj = eldbus_proxy_object_get(item->proxy); if (shelf_style && gc_style)
eldbus_proxy_unref(item->proxy); {
eldbus_object_unref(obj); size_t r;
ctx->item_list = eina_inlist_remove(ctx->item_list, EINA_INLIST_GET(item)); r = snprintf(p, avail, "%s/%s", shelf_style, gc_style);
free(item); if (r < avail && edje_object_file_set(o, path, buf))
return;
}
if (shelf_style)
{
size_t r;
r = eina_strlcpy(p, shelf_style, avail);
if (r < avail && edje_object_file_set(o, path, buf))
return;
}
if (gc_style)
{
size_t r;
r = eina_strlcpy(p, gc_style, avail);
if (r < avail && edje_object_file_set(o, path, buf))
return;
}
fallback:
edje_object_file_set(o, path, "e/modules/systray/main");
} }
static void static void
@ -113,6 +134,13 @@ image_load(const char *name, const char *path, uint32_t *imgdata, int w, int h,
e_util_icon_theme_set(image, "dialog-error"); e_util_icon_theme_set(image, "dialog-error");
} }
static void
image_scale(Evas_Object *icon)
{
//TODO make it the size of the shelf
//FIXME delayed on "after" zmike rewriting gadgets
evas_object_size_hint_min_set(icon, 30, 30);
}
static void static void
_sub_item_clicked_cb(void *data, E_Menu *m EINA_UNUSED, E_Menu_Item *mi EINA_UNUSED) _sub_item_clicked_cb(void *data, E_Menu *m EINA_UNUSED, E_Menu_Item *mi EINA_UNUSED)
{ {
@ -125,10 +153,7 @@ _menu_post_deactivate(void *data, E_Menu *m)
{ {
Eina_List *iter; Eina_List *iter;
E_Menu_Item *mi; E_Menu_Item *mi;
E_Gadcon *gadcon = data;
if (gadcon)
e_gadcon_locked_set(gadcon, 0);
EINA_LIST_FOREACH(m->items, iter, mi) EINA_LIST_FOREACH(m->items, iter, mi)
{ {
if (mi->submenu) if (mi->submenu)
@ -177,31 +202,132 @@ _item_submenu_new(E_DBusMenu_Item *item, E_Menu_Item *mi)
void void
_clicked_item_cb(void *data, Evas *evas, Evas_Object *obj EINA_UNUSED, void *event) _clicked_item_cb(void *data, Evas *evas, Evas_Object *obj EINA_UNUSED, void *event)
{ {
Notifier_Item_Icon *ii = data; Notifier_Item *item = data;
Evas_Event_Mouse_Down *ev = event; Evas_Event_Mouse_Down *ev = event;
E_DBusMenu_Item *root_item; E_DBusMenu_Item *root_item;
E_Menu *m; E_Menu *m;
E_Zone *zone;
int x, y; int x, y;
E_Gadcon *gadcon = evas_object_data_get(ii->icon, "gadcon");
if (ev->button != 1) return; if (ev->button != 1) return;
EINA_SAFETY_ON_NULL_RETURN(gadcon); root_item = item->dbus_item;
if (!ii->item->dbus_item) return;
root_item = ii->item->dbus_item;
EINA_SAFETY_ON_FALSE_RETURN(root_item->is_submenu); EINA_SAFETY_ON_FALSE_RETURN(root_item->is_submenu);
m = _item_submenu_new(root_item, NULL); m = _item_submenu_new(root_item, NULL);
e_gadcon_locked_set(gadcon, 1);
e_menu_post_deactivate_callback_set(m, _menu_post_deactivate, gadcon);
zone = e_gadcon_zone_get(gadcon);
ecore_evas_pointer_xy_get(e_comp->ee, &x, &y); ecore_evas_pointer_xy_get(e_comp->ee, &x, &y);
e_menu_activate_mouse(m, zone, x, y, 1, 1, E_MENU_POP_DIRECTION_DOWN, ev->timestamp); e_menu_activate_mouse(m, e_zone_current_get(), x, y, 1, 1, E_MENU_POP_DIRECTION_DOWN, ev->timestamp);
evas_event_feed_mouse_up(evas, ev->button, evas_event_feed_mouse_up(evas, ev->button,
EVAS_BUTTON_NONE, ev->timestamp, NULL); EVAS_BUTTON_NONE, ev->timestamp, NULL);
} }
static Evas_Object*
_visualize_add(Evas_Object *parent, Notifier_Item *item)
{
Evas_Object *obj;
obj = e_icon_add(parent);
image_load(item->icon_name,
item->icon_path,
item->imgdata,
30, 30, obj);
e_util_icon_theme_set(obj, "dialog-error");
image_scale(obj);
evas_object_show(obj);
evas_object_event_callback_add(obj, EVAS_CALLBACK_MOUSE_DOWN,
_clicked_item_cb, item);
printf("Add vis %p\n", obj);
return obj;
}
static void
_visualize_update(Evas_Object *icon, Notifier_Item *item)
{
printf("Update vis %p\n", icon);
switch (item->status)
{
case STATUS_ACTIVE:
{
image_load(item->icon_name, item->icon_path, item->imgdata, item->imgw, item->imgh, icon);
evas_object_show(icon);
break;
}
case STATUS_PASSIVE:
{
evas_object_hide(icon);
break;
}
case STATUS_ATTENTION:
{
image_load(item->attention_icon_name, item->icon_path, item->attnimgdata, item->attnimgw, item->attnimgh, icon);
evas_object_show(icon);
break;
}
default:
{
WRN("unhandled status");
break;
}
}
}
static Eina_Bool
_host_del_cb(void *data, Eo *obj, const Eo_Event_Description2 *desc, void *event)
{
traybars = eina_list_remove(traybars, obj);
return EO_CALLBACK_CONTINUE;
}
Evas_Object*
systray_notifier_host_new(const char *shelfstyle, const char *style)
{
Edje_Object *gadget;
gadget = edje_object_add(e_comp->evas);
_systray_theme(gadget, shelfstyle, style);
evas_object_show(gadget);
//add a new visualization to every single item for this tray bar
{
Eina_List *node;
Notifier_Item *item;
EINA_LIST_FOREACH(items, node, item)
{
Evas_Object *icon;
//create new icon
icon = _visualize_add(gadget, item);
//add data
_visualize_update(icon, item);
item->icons = eina_list_append(item->icons, icon);
edje_object_part_box_append(gadget, "box", icon);
_systray_size_apply_do(gadget);
}
}
traybars = eina_list_append(traybars, gadget);
return gadget;
}
static Context_Notifier_Host *ctx;
void
systray_notifier_host_init(void)
{
ctx = calloc(1, sizeof(Context_Notifier_Host));
systray_notifier_dbus_init(ctx);
}
void
systray_notifier_host_shutdown(void)
{
systray_notifier_dbus_shutdown(ctx);
}
void void
systray_notifier_update_menu(void *data, E_DBusMenu_Item *new_root_item) systray_notifier_update_menu(void *data, E_DBusMenu_Item *new_root_item)
@ -210,170 +336,57 @@ systray_notifier_update_menu(void *data, E_DBusMenu_Item *new_root_item)
item->dbus_item = new_root_item; item->dbus_item = new_root_item;
} }
static void
image_scale(Instance_Notifier_Host *notifier_inst, Notifier_Item_Icon *ii)
{
Evas_Coord sz;
switch (systray_gadcon_get(notifier_inst->inst)->orient)
{
case E_GADCON_ORIENT_FLOAT:
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:
if (systray_gadcon_get(notifier_inst->inst)->shelf)
sz = systray_gadcon_get(notifier_inst->inst)->shelf->h;
else
evas_object_geometry_get(notifier_inst->inst->gcc->o_frame ?:
notifier_inst->inst->gcc->o_base, NULL, NULL, NULL, &sz);
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:
if (systray_gadcon_get(notifier_inst->inst)->shelf)
sz = systray_gadcon_get(notifier_inst->inst)->shelf->w;
else
evas_object_geometry_get(notifier_inst->inst->gcc->o_frame ?:
notifier_inst->inst->gcc->o_base, NULL, NULL, &sz, NULL);
break;
}
sz = sz - 5;
evas_object_resize(ii->icon, sz, sz);
}
static void
_systray_notifier_inst_item_update(Instance_Notifier_Host *host_inst, Notifier_Item *item, Eina_Bool search)
{
Notifier_Item_Icon *ii = NULL;
if (!search)
goto jump_search;
EINA_INLIST_FOREACH(host_inst->ii_list, ii)
{
if (ii->item == item)
break;
}
jump_search:
if (!ii)
{
ii = calloc(1, sizeof(Notifier_Item_Icon));
ii->item = item;
host_inst->ii_list = eina_inlist_append(host_inst->ii_list,
EINA_INLIST_GET(ii));
}
if (!ii->icon)
{
ii->icon = e_icon_add(evas_object_evas_get(host_inst->edje));
EINA_SAFETY_ON_NULL_RETURN(ii->icon);
image_scale(host_inst, ii);
evas_object_data_set(ii->icon, "gadcon", host_inst->gadcon);
evas_object_event_callback_add(ii->icon, EVAS_CALLBACK_MOUSE_DOWN,
_clicked_item_cb, ii);
}
switch (item->status)
{
case STATUS_ACTIVE:
{
image_load(item->icon_name, item->icon_path, item->imgdata, item->imgw, item->imgh, ii->icon);
if (!evas_object_visible_get(ii->icon))
{
systray_edje_box_append(host_inst->inst, ii->icon);
evas_object_show(ii->icon);
}
break;
}
case STATUS_PASSIVE:
{
if (evas_object_visible_get(ii->icon))
{
systray_edje_box_remove(host_inst->inst, ii->icon);
evas_object_hide(ii->icon);
}
break;
}
case STATUS_ATTENTION:
{
image_load(item->attention_icon_name, item->icon_path, item->attnimgdata, item->attnimgw, item->attnimgh, ii->icon);
if (!evas_object_visible_get(ii->icon))
{
systray_edje_box_append(host_inst->inst, ii->icon);
evas_object_show(ii->icon);
}
break;
}
default:
{
WRN("unhandled status");
break;
}
}
systray_size_updated(host_inst->inst);
}
void void
systray_notifier_item_update(Notifier_Item *item) systray_notifier_item_update(Notifier_Item *item)
{ {
Instance_Notifier_Host *inst; Eina_List *node;
EINA_INLIST_FOREACH(ctx->instances, inst) Evas_Object *icon;
_systray_notifier_inst_item_update(inst, item, EINA_TRUE);
}
Instance_Notifier_Host * EINA_LIST_FOREACH(item->icons, node, icon)
systray_notifier_host_new(Instance *inst, E_Gadcon *gadcon)
{
Instance_Notifier_Host *host_inst = NULL;
Notifier_Item *item;
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;
ctx->instances = eina_inlist_append(ctx->instances, EINA_INLIST_GET(host_inst));
EINA_INLIST_FOREACH(ctx->item_list, item)
_systray_notifier_inst_item_update(host_inst, item, EINA_FALSE);
return host_inst;
}
void
systray_notifier_host_free(Instance_Notifier_Host *notifier)
{
while (notifier->ii_list)
{ {
Notifier_Item_Icon *ii = EINA_INLIST_CONTAINER_GET(notifier->ii_list, Notifier_Item_Icon); _visualize_update(icon, item);
notifier->ii_list = eina_inlist_remove(notifier->ii_list,
notifier->ii_list);
free(ii);
} }
ctx->instances = eina_inlist_remove(ctx->instances, EINA_INLIST_GET(notifier)); }
free(notifier); void
systray_notifier_item_free(Notifier_Item *item)
{
Evas_Object *icon;
EINA_LIST_FREE(item->icons, icon)
evas_object_del(icon);
} }
void void
systray_notifier_host_init(void) systray_notifier_item_new(Notifier_Item *item)
{ {
ctx = calloc(1, sizeof(Context_Notifier_Host)); Evas_Object *traybar;
EINA_SAFETY_ON_NULL_RETURN(ctx); Eina_List *node;
systray_notifier_dbus_init(ctx);
printf("Item new %p\n", item);
EINA_LIST_FOREACH(traybars, node, traybar)
{
Evas_Object *icon;
icon = _visualize_add(traybar, item);
edje_object_part_box_append(traybar, "box", icon);
_systray_size_apply_do(traybar);
item->icons = eina_list_append(item->icons, icon);
}
} }
void /**
systray_notifier_host_shutdown(void) * Hacky code to recalc the minsize of a object
*/
static void
_systray_size_apply_do(Edje_Object *obj)
{ {
Eldbus_Pending *p; Evas_Coord w, h;
EINA_LIST_FREE(ctx->pending, p) eldbus_pending_cancel(p); edje_object_message_signal_process(obj);
systray_notifier_dbus_shutdown(ctx); edje_object_size_min_calc(obj, &w, &h);
free(ctx); evas_object_size_hint_min_set(obj, w, h);
ctx = NULL; _hack_get_me_the_correct_min_size(obj);
} printf("New min size %d %d\n", w, h);
}

View File

@ -375,11 +375,8 @@ notifier_item_add(const char *path, const char *bus_id, Context_Notifier_Host *c
item->signals = eina_list_append(item->signals, s); item->signals = eina_list_append(item->signals, s);
s = eldbus_proxy_signal_handler_add(proxy, "NewTitle", new_title_cb, item); s = eldbus_proxy_signal_handler_add(proxy, "NewTitle", new_title_cb, item);
item->signals = eina_list_append(item->signals, s); item->signals = eina_list_append(item->signals, s);
if (eina_hash_find(systray_ctx_get()->config->items, bus_id)) return;
nic = malloc(sizeof(Notifier_Item_Cache)); systray_notifier_item_new(item);
nic->path = eina_stringshare_ref(path);
eina_hash_add(systray_ctx_get()->config->items, bus_id, nic);
e_config_save_queue();
} }
static void static void
@ -454,37 +451,16 @@ notifier_items_get_cb(void *data, const Eldbus_Message *msg, Eldbus_Pending *pen
} }
} }
static void static Eina_Bool
item_registered_local_cb(void *data, const char *bus, const char *path) _delayed_start(void *data)
{ {
Context_Notifier_Host *ctx = data; Context_Notifier_Host *ctx = data;
notifier_item_add(eina_stringshare_add(path), eina_stringshare_add(bus), ctx);
}
static void
item_unregistered_local_cb(void *data, const char *bus, const char *path)
{
Context_Notifier_Host *ctx = data;
Notifier_Item *item;
Eina_Stringshare *s, *p;
s = eina_stringshare_add(bus);
p = eina_stringshare_add(path);
item = notifier_item_find(p, s, ctx);
if (item)
systray_notifier_item_free(item);
eina_stringshare_del(s);
eina_stringshare_del(p);
}
void
systray_notifier_dbus_init(Context_Notifier_Host *ctx)
{
Eldbus_Object *obj; Eldbus_Object *obj;
eldbus_init(); ctx->conn = eldbus_connection_get(ELDBUS_CONNECTION_TYPE_SESSION);
obj = eldbus_object_get(ctx->conn, WATCHER_BUS, WATCHER_PATH); obj = eldbus_object_get(ctx->conn, WATCHER_BUS, WATCHER_PATH);
ctx->watcher = eldbus_proxy_get(obj, WATCHER_IFACE); ctx->watcher = eldbus_proxy_get(obj, WATCHER_IFACE);
eldbus_proxy_call(ctx->watcher, "RegisterStatusNotifierHost", NULL, NULL, -1, "s", eldbus_proxy_call(ctx->watcher, "RegisterStatusNotifierHost", NULL, NULL, -1, "s",
HOST_REGISTRER); HOST_REGISTRER);
@ -494,6 +470,16 @@ systray_notifier_dbus_init(Context_Notifier_Host *ctx)
notifier_item_add_cb, ctx); notifier_item_add_cb, ctx);
eldbus_proxy_signal_handler_add(ctx->watcher, "StatusNotifierItemUnregistered", eldbus_proxy_signal_handler_add(ctx->watcher, "StatusNotifierItemUnregistered",
notifier_item_del_cb, ctx); notifier_item_del_cb, ctx);
return ECORE_CALLBACK_DONE;
}
void
systray_notifier_dbus_init(Context_Notifier_Host *ctx)
{
eldbus_init();
ecore_timer_add(1.0, _delayed_start, ctx);
} }
void systray_notifier_dbus_shutdown(Context_Notifier_Host *ctx) void systray_notifier_dbus_shutdown(Context_Notifier_Host *ctx)
@ -506,9 +492,6 @@ void systray_notifier_dbus_shutdown(Context_Notifier_Host *ctx)
EINA_INLIST_FOREACH_SAFE(ctx->item_list, safe_list, item) EINA_INLIST_FOREACH_SAFE(ctx->item_list, safe_list, item)
systray_notifier_item_free(item); systray_notifier_item_free(item);
if (!ctx->watcher)
systray_notifier_dbus_watcher_stop();
else
{ {
Eldbus_Object *obj; Eldbus_Object *obj;
obj = eldbus_proxy_object_get(ctx->watcher); obj = eldbus_proxy_object_get(ctx->watcher);
@ -516,6 +499,7 @@ void systray_notifier_dbus_shutdown(Context_Notifier_Host *ctx)
eldbus_object_unref(obj); eldbus_object_unref(obj);
ctx->watcher = NULL; ctx->watcher = NULL;
} }
eldbus_connection_unref(ctx->conn); eldbus_connection_unref(ctx->conn);
eldbus_shutdown(); eldbus_shutdown();
} }

View File

@ -26,7 +26,7 @@ struct _Instance_Notifier_Host
EINA_INLIST; EINA_INLIST;
Instance *inst; Instance *inst;
const Evas_Object *box; const Evas_Object *box;
const Evas_Object *edje; const Edje_Object *edje;
Eina_Inlist *ii_list; Eina_Inlist *ii_list;
E_Gadcon *gadcon; E_Gadcon *gadcon;
}; };
@ -61,17 +61,19 @@ struct _Notifier_Item
int imgw, imgh; int imgw, imgh;
uint32_t *attnimgdata; uint32_t *attnimgdata;
int attnimgw, attnimgh; int attnimgw, attnimgh;
Eina_List *icons; //list of icons which gets updated
}; };
typedef void (*E_Notifier_Watcher_Item_Registered_Cb)(void *data, const char *service, const char *path); typedef void (*E_Notifier_Watcher_Item_Registered_Cb)(void *data, const char *service, const char *path);
typedef void (*E_Notifier_Watcher_Item_Unregistered_Cb)(void *data, const char *service, const char *path); typedef void (*E_Notifier_Watcher_Item_Unregistered_Cb)(void *data, const char *service, const char *path);
void _hack_get_me_the_correct_min_size(Edje_Object *obj);
void systray_notifier_update_menu(void *data, E_DBusMenu_Item *new_root_item); void systray_notifier_update_menu(void *data, E_DBusMenu_Item *new_root_item);
void systray_notifier_item_update(Notifier_Item *item); void systray_notifier_item_update(Notifier_Item *item);
void systray_notifier_item_free(Notifier_Item *item); void systray_notifier_item_free(Notifier_Item *item);
void systray_notifier_item_new(Notifier_Item *item);
void systray_notifier_dbus_init(Context_Notifier_Host *ctx); void systray_notifier_dbus_init(Context_Notifier_Host *ctx);
void systray_notifier_dbus_shutdown(Context_Notifier_Host *ctx); void systray_notifier_dbus_shutdown(Context_Notifier_Host *ctx);
void systray_notifier_dbus_watcher_start(Eldbus_Connection *connection, E_Notifier_Watcher_Item_Registered_Cb registered, E_Notifier_Watcher_Item_Unregistered_Cb unregistered, const void *data);
void systray_notifier_dbus_watcher_stop(void);

View File

@ -48,8 +48,6 @@ register_item_cb(const Eldbus_Service_Interface *s_iface, const Eldbus_Message *
char buf[1024]; char buf[1024];
Eina_Bool stupid; Eina_Bool stupid;
printf("Item registered\n");
if (!eldbus_message_arguments_get(msg, "s", &service)) if (!eldbus_message_arguments_get(msg, "s", &service))
return NULL; return NULL;
svc = service; svc = service;
@ -66,16 +64,18 @@ register_item_cb(const Eldbus_Service_Interface *s_iface, const Eldbus_Message *
} }
items = eina_list_append(items, service); items = eina_list_append(items, service);
eldbus_service_signal_emit(s_iface, ITEM_REGISTERED, svc); eldbus_service_signal_emit(s_iface, ITEM_REGISTERED, service);
eldbus_name_owner_changed_callback_add(conn, stupid ? eldbus_message_sender_get(msg) : svc, eldbus_name_owner_changed_callback_add(conn, stupid ? eldbus_message_sender_get(msg) : svc,
item_name_monitor_cb, service, item_name_monitor_cb, service,
EINA_FALSE); EINA_FALSE);
printf("Item registered %s\n", service);
return eldbus_message_method_return_new(msg); return eldbus_message_method_return_new(msg);
} }
static void static void
host_name_monitor_cb(void *data EINA_UNUSED, const char *bus, const char *old_id EINA_UNUSED, const char *new_id) host_name_monitor_cb(void *data, const char *bus, const char *old_id EINA_UNUSED, const char *new_id)
{ {
if (strcmp(new_id, "")) if (strcmp(new_id, ""))
return; return;
@ -84,6 +84,8 @@ host_name_monitor_cb(void *data EINA_UNUSED, const char *bus, const char *old_id
eldbus_service_signal_emit(iface, HOST_UNREGISTERED); eldbus_service_signal_emit(iface, HOST_UNREGISTERED);
eldbus_name_owner_changed_callback_del(conn, bus, host_name_monitor_cb, NULL); eldbus_name_owner_changed_callback_del(conn, bus, host_name_monitor_cb, NULL);
hosts = eina_list_remove(hosts, data);
eina_stringshare_del(data);
} }
static Eldbus_Message * static Eldbus_Message *
@ -106,7 +108,7 @@ register_host_cb(const Eldbus_Service_Interface *s_iface, const Eldbus_Message *
hosts = eina_list_append(hosts, service); hosts = eina_list_append(hosts, service);
eldbus_service_signal_emit(s_iface, HOST_REGISTERED); eldbus_service_signal_emit(s_iface, HOST_REGISTERED);
eldbus_name_owner_changed_callback_add(conn, eldbus_message_sender_get(msg), eldbus_name_owner_changed_callback_add(conn, eldbus_message_sender_get(msg),
host_name_monitor_cb, NULL, EINA_FALSE); host_name_monitor_cb, service, EINA_FALSE);
return eldbus_message_method_return_new(msg); return eldbus_message_method_return_new(msg);
} }
@ -130,7 +132,7 @@ properties_get(const Eldbus_Service_Interface *s_iface EINA_UNUSED, const char *
eldbus_message_iter_container_close(iter, array); eldbus_message_iter_container_close(iter, array);
} }
else if (!strcmp(propname, "IsStatusNotifierHostRegistered")) else if (!strcmp(propname, "IsStatusNotifierHostRegistered"))
eldbus_message_iter_arguments_append(iter, "b", EINA_TRUE); eldbus_message_iter_arguments_append(iter, "b", hosts ? EINA_TRUE : EINA_FALSE);
return EINA_TRUE; return EINA_TRUE;
} }