Compare commits
8 Commits
master
...
devs/bu5hm
Author | SHA1 | Date |
---|---|---|
Marcel Hollerbach | 6bc93814fb | |
Marcel Hollerbach | 33a4f33410 | |
Marcel Hollerbach | da51b1a002 | |
Marcel Hollerbach | 6107f2fbe0 | |
Marcel Hollerbach | 240de1e05a | |
Marcel Hollerbach | 58e610ff0c | |
Marcel Hollerbach | af83d0111b | |
Marcel Hollerbach | d8a4888142 |
|
@ -173,7 +173,7 @@ _e_grabinput_focus_do(Ecore_Window win, E_Focus_Method method)
|
|||
#ifndef HAVE_WAYLAND_ONLY
|
||||
if (e_comp_util_has_x())
|
||||
{
|
||||
ecore_x_window_focus_at_time(win, ecore_x_current_time_get());
|
||||
ecore_x_window_focus(win);
|
||||
ecore_x_icccm_take_focus_send(win, ecore_x_current_time_get());
|
||||
}
|
||||
#endif
|
||||
|
@ -189,7 +189,7 @@ _e_grabinput_focus_do(Ecore_Window win, E_Focus_Method method)
|
|||
case E_FOCUS_METHOD_PASSIVE:
|
||||
#ifndef HAVE_WAYLAND_ONLY
|
||||
if (e_comp_util_has_x())
|
||||
ecore_x_window_focus_at_time(win, ecore_x_current_time_get());
|
||||
ecore_x_window_focus(win);
|
||||
#endif
|
||||
break;
|
||||
|
||||
|
|
|
@ -9,6 +9,11 @@ systray_DATA = src/modules/systray/e-module-systray.edj \
|
|||
systraypkgdir = $(MDIR)/systray/$(MODULE_ARCH)
|
||||
systraypkg_LTLIBRARIES = src/modules/systray/module.la
|
||||
|
||||
systraypkg_PROGRAMS = src/modules/systray/watcher
|
||||
src_modules_systray_watcher_SOURCES = src/modules/systray/watcher.c
|
||||
src_modules_systray_watcher_CPPFLAGS = $(MOD_CPPFLAGS) @e_cflags@
|
||||
src_modules_systray_watcher_LDADD = $(MOD_LIBS)
|
||||
|
||||
src_modules_systray_module_la_LIBADD = $(MOD_LIBS)
|
||||
src_modules_systray_module_la_CPPFLAGS = $(MOD_CPPFLAGS)
|
||||
src_modules_systray_module_la_LDFLAGS = $(MOD_LDFLAGS)
|
||||
|
@ -16,8 +21,7 @@ src_modules_systray_module_la_SOURCES = src/modules/systray/e_mod_main.h \
|
|||
src/modules/systray/e_mod_main.c \
|
||||
src/modules/systray/e_mod_notifier_host_private.h \
|
||||
src/modules/systray/e_mod_notifier_host.c \
|
||||
src/modules/systray/e_mod_notifier_host_dbus.c \
|
||||
src/modules/systray/e_mod_notifier_watcher.c
|
||||
src/modules/systray/e_mod_notifier_host_dbus.c
|
||||
|
||||
PHONIES += systray install-systray
|
||||
systray: $(systraypkg_LTLIBRARIES) $(systray_DATA)
|
||||
|
|
|
@ -2,27 +2,14 @@
|
|||
|
||||
static const char _Name[] = "Systray";
|
||||
static const char _name[] = "systray";
|
||||
static const char _group_gadget[] = "e/modules/systray/main";
|
||||
static const char _sig_source[] = "e";
|
||||
|
||||
static E_Module *systray_mod = NULL;
|
||||
static Systray_Context *ctx = NULL;
|
||||
EINTERN Instance *instance = NULL; /* only one systray ever possible */
|
||||
E_Module *systray_mod = NULL;
|
||||
static char tmpbuf[4096]; /* general purpose buffer, just use immediately */
|
||||
|
||||
#define SYSTRAY_MIN_W 16
|
||||
#define SYSTRAY_MIN_H 8
|
||||
|
||||
static Eina_Bool
|
||||
_systray_site_is_safe(E_Gadcon_Site site)
|
||||
{
|
||||
/* NB: filter out sites we know are not safe for a systray to sit.
|
||||
* This was done so that systray could be put into illume indicator
|
||||
* (or anywhere else really) that is 'safe' for systray to be.
|
||||
* Pretty much, this is anywhere but toolbars at the moment */
|
||||
return !e_gadcon_site_is_any_toolbar(site);
|
||||
}
|
||||
|
||||
static const char *
|
||||
_systray_theme_path(void)
|
||||
{
|
||||
|
@ -41,55 +28,6 @@ _systray_theme_path(void)
|
|||
#undef TF
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void *
|
||||
_cfg_data_create(E_Config_Dialog *cfd EINA_UNUSED)
|
||||
{
|
||||
E_Config_Dialog_Data *cfdata = calloc(1, sizeof(E_Config_Dialog_Data));
|
||||
return cfdata;
|
||||
}
|
||||
|
||||
static void
|
||||
_cfg_data_free(E_Config_Dialog *cfd EINA_UNUSED, E_Config_Dialog_Data *cfdata)
|
||||
{
|
||||
free(cfdata);
|
||||
}
|
||||
|
||||
static Evas_Object *
|
||||
_cfg_widgets_create(E_Config_Dialog *cfd EINA_UNUSED, Evas *evas, E_Config_Dialog_Data *cfdata)
|
||||
{
|
||||
Evas_Object *o, *of;
|
||||
o = e_widget_list_add(evas, 0, 0);
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
static int
|
||||
_cfg_data_apply(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata)
|
||||
{
|
||||
Instance *inst = cfd->data;
|
||||
|
||||
systray_size_updated(inst);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
_cb_menu_cfg(void *data, E_Menu *m EINA_UNUSED, E_Menu_Item *mi EINA_UNUSED)
|
||||
{
|
||||
E_Config_Dialog_View *v;
|
||||
|
||||
v = calloc(1, sizeof(E_Config_Dialog_View));
|
||||
v->create_cfdata = _cfg_data_create;
|
||||
v->free_cfdata = _cfg_data_free;
|
||||
v->basic.create_widgets = _cfg_widgets_create;
|
||||
v->basic.apply_cfdata = _cfg_data_apply;
|
||||
|
||||
e_config_dialog_new(NULL, _("Systray Settings"), "E",
|
||||
"_e_mod_systray_config_dialog",
|
||||
NULL, 0, v, data);
|
||||
}
|
||||
#endif
|
||||
static void
|
||||
_systray_menu_new(Instance *inst, Evas_Event_Mouse_Down *ev)
|
||||
{
|
||||
|
@ -109,7 +47,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_menu_activate_mouse(m, zone, x + ev->output.x, y + ev->output.y,
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -123,116 +61,42 @@ _systray_cb_mouse_down(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA
|
|||
_systray_menu_new(inst, ev);
|
||||
}
|
||||
|
||||
static void
|
||||
_systray_theme(Evas_Object *o, const char *shelf_style, const char *gc_style)
|
||||
void
|
||||
_hack_get_me_the_correct_min_size(Edje_Object *obj)
|
||||
{
|
||||
const char base_theme[] = "base/theme/modules/systray";
|
||||
const char *path = _systray_theme_path();
|
||||
char buf[128], *p;
|
||||
size_t len, avail;
|
||||
Evas_Coord w, h;
|
||||
E_Gadcon_Client *client;
|
||||
|
||||
len = eina_strlcpy(buf, _group_gadget, sizeof(buf));
|
||||
if (len >= sizeof(buf))
|
||||
goto fallback;
|
||||
p = buf + len;
|
||||
*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);
|
||||
client = evas_object_data_get(obj, "gadcon");
|
||||
evas_object_size_hint_min_get(obj, &w, &h);
|
||||
e_gadcon_client_min_size_set(client, MAX(w, SYSTRAY_MIN_W), MAX(h, SYSTRAY_MIN_H));
|
||||
}
|
||||
|
||||
|
||||
static E_Gadcon_Client *
|
||||
_gc_init(E_Gadcon *gc, const char *name, const char *id, const char *style)
|
||||
{
|
||||
Instance *inst;
|
||||
|
||||
Evas_Object *content;
|
||||
// fprintf(stderr, "SYSTRAY: init name=%s, id=%s, style=%s\n", name, id, style);
|
||||
|
||||
if (!systray_mod)
|
||||
return NULL;
|
||||
if ((!id) || (instance))
|
||||
{
|
||||
e_util_dialog_internal
|
||||
(_("Another systray exists"),
|
||||
_("There can be only one systray gadget and "
|
||||
"another one already exists."));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
inst = E_NEW(Instance, 1);
|
||||
if (!inst)
|
||||
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)
|
||||
{
|
||||
evas_object_del(inst->ui.gadget);
|
||||
E_FREE(inst);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
evas_object_data_set(content, "gadcon", inst->gcc);
|
||||
|
||||
e_gadcon_client_min_size_set(inst->gcc, SYSTRAY_MIN_W, SYSTRAY_MIN_H);
|
||||
|
||||
inst->gcc->data = inst;
|
||||
|
@ -240,9 +104,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,
|
||||
_systray_cb_mouse_down, inst);
|
||||
|
||||
inst->notifier = systray_notifier_host_new(inst, inst->gcc->gadcon);
|
||||
|
||||
instance = inst;
|
||||
return inst->gcc;
|
||||
}
|
||||
|
||||
|
@ -256,14 +117,8 @@ _gc_shutdown(E_Gadcon_Client *gcc)
|
|||
|
||||
if (!inst)
|
||||
return;
|
||||
|
||||
systray_notifier_host_free(inst->notifier);
|
||||
|
||||
evas_object_del(inst->ui.gadget);
|
||||
|
||||
if (instance == inst)
|
||||
instance = NULL;
|
||||
|
||||
if (inst->job.size_apply)
|
||||
ecore_job_del(inst->job.size_apply);
|
||||
|
||||
|
@ -377,7 +232,7 @@ static const E_Gadcon_Client_Class _gc_class =
|
|||
GADCON_CLIENT_CLASS_VERSION, _name,
|
||||
{
|
||||
_gc_init, _gc_shutdown, _gc_orient, _gc_label, _gc_icon, _gc_id_new, NULL,
|
||||
_systray_site_is_safe
|
||||
NULL
|
||||
},
|
||||
E_GADCON_CLIENT_STYLE_PLAIN
|
||||
};
|
||||
|
@ -389,30 +244,21 @@ e_modapi_init(E_Module *m)
|
|||
{
|
||||
systray_mod = m;
|
||||
|
||||
ctx = calloc(1, sizeof(Systray_Context));
|
||||
ctx->conf_edd = E_CONFIG_DD_NEW("Systray_Config", Systray_Config);
|
||||
ctx->notifier_item_edd = E_CONFIG_DD_NEW("Notifier_Item_Cache", Notifier_Item_Cache);
|
||||
#undef T
|
||||
#undef D
|
||||
#define T Notifier_Item_Cache
|
||||
#define D ctx->notifier_item_edd
|
||||
E_CONFIG_VAL(D, T, path, STR);
|
||||
#undef T
|
||||
#undef D
|
||||
#define T Systray_Config
|
||||
#define D ctx->conf_edd
|
||||
E_CONFIG_VAL(D, T, dbus, STR);
|
||||
E_CONFIG_HASH(D, T, items, ctx->notifier_item_edd);
|
||||
|
||||
ctx->config = e_config_domain_load(_name, ctx->conf_edd);
|
||||
if (!ctx->config)
|
||||
ctx->config = calloc(1, sizeof(Systray_Config));
|
||||
|
||||
e_gadcon_provider_register(&_gc_class);
|
||||
|
||||
systray_notifier_host_init();
|
||||
|
||||
return ctx;
|
||||
//start the watcher service
|
||||
char buf[PATH_MAX];
|
||||
|
||||
snprintf(buf, sizeof(buf), "%s/%s/watcher", e_module_dir_get(m), MODULE_ARCH);
|
||||
|
||||
if (!ecore_exe_run(buf, NULL))
|
||||
{
|
||||
printf("Starting watcher failed\n");
|
||||
}
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
E_API int
|
||||
|
@ -423,127 +269,12 @@ e_modapi_shutdown(E_Module *m EINA_UNUSED)
|
|||
|
||||
systray_notifier_host_shutdown();
|
||||
|
||||
E_CONFIG_DD_FREE(ctx->conf_edd);
|
||||
E_CONFIG_DD_FREE(ctx->notifier_item_edd);
|
||||
free(ctx->config);
|
||||
free(ctx);
|
||||
return 1;
|
||||
}
|
||||
|
||||
E_API int
|
||||
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;
|
||||
}
|
||||
|
||||
E_Gadcon_Orient
|
||||
systray_orient_get(const Instance *inst)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(inst, E_GADCON_ORIENT_HORIZ);
|
||||
return inst->gcc->gadcon->orient;
|
||||
}
|
||||
|
||||
const E_Gadcon *
|
||||
systray_gadcon_get(const Instance *inst)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(inst, NULL);
|
||||
return inst->gcc->gadcon;
|
||||
}
|
||||
|
||||
E_Gadcon_Client *
|
||||
systray_gadcon_client_get(const Instance *inst)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(inst, NULL);
|
||||
return inst->gcc;
|
||||
}
|
||||
|
||||
const char *
|
||||
systray_style_get(const Instance *inst)
|
||||
{
|
||||
const char *style;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(inst, NULL);
|
||||
style = inst->gcc->style;
|
||||
if (!style)
|
||||
style = "default";
|
||||
return style;
|
||||
}
|
||||
|
||||
Evas *
|
||||
systray_evas_get(const Instance *inst)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(inst, NULL);
|
||||
return inst->evas;
|
||||
}
|
||||
|
||||
Evas_Object *
|
||||
systray_edje_get(const Instance *inst)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(inst, NULL);
|
||||
return inst->ui.gadget;
|
||||
}
|
||||
|
||||
const Evas_Object *
|
||||
systray_box_get(const Instance *inst)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(inst, NULL);
|
||||
return edje_object_part_object_get(inst->ui.gadget, "box");
|
||||
}
|
||||
|
||||
void
|
||||
systray_edje_box_append(const Instance *inst, Evas_Object *child)
|
||||
{
|
||||
edje_object_part_box_append(inst->ui.gadget, "box", child);
|
||||
}
|
||||
|
||||
void
|
||||
systray_edje_box_prepend(const Instance *inst, Evas_Object *child)
|
||||
{
|
||||
edje_object_part_box_prepend(inst->ui.gadget, "box", child);
|
||||
}
|
||||
|
||||
void
|
||||
systray_edje_box_remove(const Instance *inst, Evas_Object *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
|
||||
_systray_size_apply_do(Instance *inst)
|
||||
{
|
||||
Evas_Coord w, h;
|
||||
|
||||
edje_object_message_signal_process(inst->ui.gadget);
|
||||
edje_object_size_min_calc(inst->ui.gadget, &w, &h);
|
||||
e_gadcon_client_min_size_set(inst->gcc, MAX(w, SYSTRAY_MIN_W), MAX(h, SYSTRAY_MIN_H));
|
||||
}
|
||||
|
||||
static void
|
||||
_systray_size_apply_delayed(void *data)
|
||||
{
|
||||
Instance *inst = data;
|
||||
_systray_size_apply_do(inst);
|
||||
inst->job.size_apply = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
systray_size_updated(Instance *inst)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN(inst);
|
||||
if (inst->job.size_apply) return;
|
||||
inst->job.size_apply = ecore_job_add(_systray_size_apply_delayed, inst);
|
||||
}
|
||||
|
||||
EINTERN Systray_Context *
|
||||
systray_ctx_get(void)
|
||||
{
|
||||
return ctx;
|
||||
}
|
||||
}
|
|
@ -13,19 +13,6 @@ typedef struct _Instance Instance;
|
|||
typedef struct _Context_Notifier_Host Context_Notifier_Host;
|
||||
typedef struct _Instance_Notifier_Host Instance_Notifier_Host;
|
||||
typedef struct _Notifier_Item Notifier_Item;
|
||||
typedef struct _Systray_Context Systray_Context;
|
||||
typedef struct Systray_Config Systray_Config;
|
||||
|
||||
struct _E_Config_Dialog_Data
|
||||
{
|
||||
};
|
||||
|
||||
struct _Systray_Context
|
||||
{
|
||||
Systray_Config *config;
|
||||
E_Config_DD *conf_edd;
|
||||
E_Config_DD *notifier_item_edd;
|
||||
};
|
||||
|
||||
struct _Instance
|
||||
{
|
||||
|
@ -42,39 +29,12 @@ struct _Instance
|
|||
} job;
|
||||
};
|
||||
|
||||
typedef struct Notifier_Item_Cache
|
||||
{
|
||||
Eina_Stringshare *path;
|
||||
} Notifier_Item_Cache;
|
||||
|
||||
struct Systray_Config
|
||||
{
|
||||
Eina_Stringshare *dbus;
|
||||
Eina_Hash *items;
|
||||
};
|
||||
|
||||
E_Gadcon_Orient systray_orient_get(const Instance *inst);
|
||||
const E_Gadcon *systray_gadcon_get(const Instance *inst);
|
||||
E_Gadcon_Client *systray_gadcon_client_get(const Instance *inst);
|
||||
const char *systray_style_get(const Instance *inst);
|
||||
void systray_size_updated(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_shutdown(void);
|
||||
|
||||
Evas_Object* systray_notifier_host_new(const char *shelfstyle, const char *style);
|
||||
|
||||
EINTERN Systray_Context *systray_ctx_get(void);
|
||||
extern Instance *instance;
|
||||
extern E_Module *systray_mod;
|
||||
/**
|
||||
* @addtogroup Optional_Gadgets
|
||||
* @{
|
||||
|
|
|
@ -1,11 +1,6 @@
|
|||
#include "e_mod_main.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[] = {
|
||||
"unknown", "SystemServices", NULL
|
||||
};
|
||||
|
@ -14,55 +9,81 @@ const char *Status_Names[] = {
|
|||
"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
|
||||
systray_notifier_item_free(Notifier_Item *item)
|
||||
static void
|
||||
_systray_theme(Evas_Object *o, const char *shelf_style, const char *gc_style)
|
||||
{
|
||||
Eldbus_Object *obj;
|
||||
Eldbus_Signal_Handler *sig;
|
||||
Instance_Notifier_Host *host_inst;
|
||||
EINA_INLIST_FOREACH(ctx->instances, host_inst)
|
||||
const char base_theme[] = "base/theme/modules/systray";
|
||||
char path[PATH_MAX];
|
||||
char buf[128], *p;
|
||||
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;
|
||||
EINA_INLIST_FOREACH(host_inst->ii_list, ii)
|
||||
{
|
||||
if (ii->item == item)
|
||||
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);
|
||||
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 (item->menu_path)
|
||||
e_dbusmenu_unload(item->menu_data);
|
||||
eina_stringshare_del(item->bus_id);
|
||||
eina_stringshare_del(item->path);
|
||||
free(item->imgdata);
|
||||
free(item->attnimgdata);
|
||||
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)
|
||||
eldbus_signal_handler_del(sig);
|
||||
obj = eldbus_proxy_object_get(item->proxy);
|
||||
eldbus_proxy_unref(item->proxy);
|
||||
eldbus_object_unref(obj);
|
||||
ctx->item_list = eina_inlist_remove(ctx->item_list, EINA_INLIST_GET(item));
|
||||
free(item);
|
||||
|
||||
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, "e/modules/systray/main"))
|
||||
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, "e/modules/systray/main");
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
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
|
||||
_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;
|
||||
E_Menu_Item *mi;
|
||||
E_Gadcon *gadcon = data;
|
||||
|
||||
if (gadcon)
|
||||
e_gadcon_locked_set(gadcon, 0);
|
||||
EINA_LIST_FOREACH(m->items, iter, mi)
|
||||
{
|
||||
if (mi->submenu)
|
||||
|
@ -177,31 +202,130 @@ _item_submenu_new(E_DBusMenu_Item *item, E_Menu_Item *mi)
|
|||
void
|
||||
_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;
|
||||
E_DBusMenu_Item *root_item;
|
||||
E_Menu *m;
|
||||
E_Zone *zone;
|
||||
int x, y;
|
||||
E_Gadcon *gadcon = evas_object_data_get(ii->icon, "gadcon");
|
||||
|
||||
if (ev->button != 1) return;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN(gadcon);
|
||||
if (!ii->item->dbus_item) return;
|
||||
root_item = ii->item->dbus_item;
|
||||
root_item = item->dbus_item;
|
||||
EINA_SAFETY_ON_FALSE_RETURN(root_item->is_submenu);
|
||||
|
||||
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);
|
||||
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_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);
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
static void
|
||||
_visualize_update(Evas_Object *icon, Notifier_Item *item)
|
||||
{
|
||||
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
|
||||
systray_notifier_update_menu(void *data, E_DBusMenu_Item *new_root_item)
|
||||
|
@ -210,170 +334,54 @@ systray_notifier_update_menu(void *data, E_DBusMenu_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
|
||||
systray_notifier_item_update(Notifier_Item *item)
|
||||
{
|
||||
Instance_Notifier_Host *inst;
|
||||
EINA_INLIST_FOREACH(ctx->instances, inst)
|
||||
_systray_notifier_inst_item_update(inst, item, EINA_TRUE);
|
||||
}
|
||||
Eina_List *node;
|
||||
Evas_Object *icon;
|
||||
|
||||
Instance_Notifier_Host *
|
||||
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)
|
||||
EINA_LIST_FOREACH(item->icons, node, icon)
|
||||
{
|
||||
Notifier_Item_Icon *ii = EINA_INLIST_CONTAINER_GET(notifier->ii_list, Notifier_Item_Icon);
|
||||
notifier->ii_list = eina_inlist_remove(notifier->ii_list,
|
||||
notifier->ii_list);
|
||||
free(ii);
|
||||
_visualize_update(icon, item);
|
||||
}
|
||||
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
|
||||
systray_notifier_host_init(void)
|
||||
systray_notifier_item_new(Notifier_Item *item)
|
||||
{
|
||||
ctx = calloc(1, sizeof(Context_Notifier_Host));
|
||||
EINA_SAFETY_ON_NULL_RETURN(ctx);
|
||||
systray_notifier_dbus_init(ctx);
|
||||
Evas_Object *traybar;
|
||||
Eina_List *node;
|
||||
|
||||
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;
|
||||
|
||||
EINA_LIST_FREE(ctx->pending, p) eldbus_pending_cancel(p);
|
||||
systray_notifier_dbus_shutdown(ctx);
|
||||
free(ctx);
|
||||
ctx = NULL;
|
||||
}
|
||||
Evas_Coord w, h;
|
||||
|
||||
edje_object_message_signal_process(obj);
|
||||
edje_object_size_min_calc(obj, &w, &h);
|
||||
evas_object_size_hint_min_set(obj, w, h);
|
||||
_hack_get_me_the_correct_min_size(obj);
|
||||
}
|
|
@ -346,7 +346,6 @@ static void
|
|||
notifier_item_add(const char *path, const char *bus_id, Context_Notifier_Host *ctx)
|
||||
{
|
||||
Eldbus_Proxy *proxy;
|
||||
Notifier_Item_Cache *nic;
|
||||
Notifier_Item *item = calloc(1, sizeof(Notifier_Item));
|
||||
Eldbus_Signal_Handler *s;
|
||||
EINA_SAFETY_ON_NULL_RETURN(item);
|
||||
|
@ -375,11 +374,8 @@ notifier_item_add(const char *path, const char *bus_id, Context_Notifier_Host *c
|
|||
item->signals = eina_list_append(item->signals, s);
|
||||
s = eldbus_proxy_signal_handler_add(proxy, "NewTitle", new_title_cb, item);
|
||||
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));
|
||||
nic->path = eina_stringshare_ref(path);
|
||||
eina_hash_add(systray_ctx_get()->config->items, bus_id, nic);
|
||||
e_config_save_queue();
|
||||
|
||||
systray_notifier_item_new(item);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -454,60 +450,16 @@ notifier_items_get_cb(void *data, const Eldbus_Message *msg, Eldbus_Pending *pen
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
item_registered_local_cb(void *data, const char *bus, const char *path)
|
||||
static Eina_Bool
|
||||
_delayed_start(void *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);
|
||||
}
|
||||
|
||||
static void
|
||||
name_request_cb(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending)
|
||||
{
|
||||
const char *error, *error_msg;
|
||||
unsigned flag;
|
||||
Eldbus_Object *obj;
|
||||
Context_Notifier_Host *ctx = data;
|
||||
|
||||
ctx->pending = eina_list_remove(ctx->pending, pending);
|
||||
if (eldbus_message_error_get(msg, &error, &error_msg))
|
||||
{
|
||||
ERR("%s %s", error, error_msg);
|
||||
goto end;
|
||||
}
|
||||
ctx->conn = eldbus_connection_get(ELDBUS_CONNECTION_TYPE_SESSION);
|
||||
|
||||
if (!eldbus_message_arguments_get(msg, "u", &flag))
|
||||
{
|
||||
ERR("Error reading message.");
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (flag == ELDBUS_NAME_REQUEST_REPLY_PRIMARY_OWNER)
|
||||
{
|
||||
systray_notifier_dbus_watcher_start(ctx->conn,
|
||||
item_registered_local_cb,
|
||||
item_unregistered_local_cb, ctx);
|
||||
return;
|
||||
}
|
||||
end:
|
||||
WRN("Bus name: %s already in use, getting data via dbus.\n", WATCHER_BUS);
|
||||
obj = eldbus_object_get(ctx->conn, WATCHER_BUS, WATCHER_PATH);
|
||||
|
||||
ctx->watcher = eldbus_proxy_get(obj, WATCHER_IFACE);
|
||||
eldbus_proxy_call(ctx->watcher, "RegisterStatusNotifierHost", NULL, NULL, -1, "s",
|
||||
HOST_REGISTRER);
|
||||
|
@ -517,20 +469,16 @@ end:
|
|||
notifier_item_add_cb, ctx);
|
||||
eldbus_proxy_signal_handler_add(ctx->watcher, "StatusNotifierItemUnregistered",
|
||||
notifier_item_del_cb, ctx);
|
||||
|
||||
return ECORE_CALLBACK_DONE;
|
||||
}
|
||||
|
||||
void
|
||||
systray_notifier_dbus_init(Context_Notifier_Host *ctx)
|
||||
{
|
||||
Eldbus_Pending *p;
|
||||
|
||||
eldbus_init();
|
||||
ctx->conn = eldbus_connection_get(ELDBUS_CONNECTION_TYPE_SESSION);
|
||||
if (!ctx->conn) return;
|
||||
p = eldbus_name_request(ctx->conn,
|
||||
WATCHER_BUS, ELDBUS_NAME_REQUEST_FLAG_REPLACE_EXISTING,
|
||||
name_request_cb, ctx);
|
||||
if (p) ctx->pending = eina_list_append(ctx->pending, p);
|
||||
|
||||
ecore_timer_add(1.0, _delayed_start, ctx);
|
||||
}
|
||||
|
||||
void systray_notifier_dbus_shutdown(Context_Notifier_Host *ctx)
|
||||
|
@ -543,9 +491,6 @@ void systray_notifier_dbus_shutdown(Context_Notifier_Host *ctx)
|
|||
EINA_INLIST_FOREACH_SAFE(ctx->item_list, safe_list, item)
|
||||
systray_notifier_item_free(item);
|
||||
|
||||
if (!ctx->watcher)
|
||||
systray_notifier_dbus_watcher_stop();
|
||||
else
|
||||
{
|
||||
Eldbus_Object *obj;
|
||||
obj = eldbus_proxy_object_get(ctx->watcher);
|
||||
|
@ -553,6 +498,7 @@ void systray_notifier_dbus_shutdown(Context_Notifier_Host *ctx)
|
|||
eldbus_object_unref(obj);
|
||||
ctx->watcher = NULL;
|
||||
}
|
||||
|
||||
eldbus_connection_unref(ctx->conn);
|
||||
eldbus_shutdown();
|
||||
}
|
||||
|
|
|
@ -14,19 +14,12 @@ typedef enum {
|
|||
STATUS_LAST
|
||||
} Tray_Status;
|
||||
|
||||
typedef struct _Notifier_Data
|
||||
{
|
||||
EINA_INLIST;
|
||||
Notifier_Item *item;
|
||||
Evas_Object *icon;
|
||||
} Notifier_Item_Icon;
|
||||
|
||||
struct _Instance_Notifier_Host
|
||||
{
|
||||
EINA_INLIST;
|
||||
Instance *inst;
|
||||
const Evas_Object *box;
|
||||
const Evas_Object *edje;
|
||||
const Edje_Object *edje;
|
||||
Eina_Inlist *ii_list;
|
||||
E_Gadcon *gadcon;
|
||||
};
|
||||
|
@ -61,17 +54,16 @@ struct _Notifier_Item
|
|||
int imgw, imgh;
|
||||
uint32_t *attnimgdata;
|
||||
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_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_item_update(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_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);
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
#include "e_mod_notifier_host_private.h"
|
||||
#include <Eina.h>
|
||||
#include <Eldbus.h>
|
||||
#include <Ecore.h>
|
||||
|
||||
#define WATCHER_BUS "org.kde.StatusNotifierWatcher"
|
||||
#define PATH "/StatusNotifierWatcher"
|
||||
#define IFACE "org.kde.StatusNotifierWatcher"
|
||||
#define PROTOCOL_VERSION 1
|
||||
|
@ -10,11 +13,8 @@
|
|||
static Eldbus_Connection *conn = NULL;
|
||||
static Eldbus_Service_Interface *iface = NULL;
|
||||
static Eina_List *items;
|
||||
static const char *host_service = NULL;
|
||||
static E_Notifier_Watcher_Item_Registered_Cb registered_cb;
|
||||
static E_Notifier_Watcher_Item_Unregistered_Cb unregistered_cb;
|
||||
static void *user_data;
|
||||
|
||||
static Eina_List *hosts;
|
||||
static Eina_Bool started;
|
||||
enum
|
||||
{
|
||||
ITEM_REGISTERED = 0,
|
||||
|
@ -27,31 +27,16 @@ static void
|
|||
item_name_monitor_cb(void *data, const char *bus, const char *old_id EINA_UNUSED, const char *new_id)
|
||||
{
|
||||
const char *svc, *service = data;
|
||||
Eina_List *l;
|
||||
|
||||
l = eina_list_data_find_list(items, service);
|
||||
if (strcmp(new_id, ""))
|
||||
{
|
||||
if (l) return;
|
||||
items = eina_list_append(items, service);
|
||||
svc = strchr(service, '/') + 1;
|
||||
registered_cb(user_data, bus, svc);
|
||||
return;
|
||||
}
|
||||
return;
|
||||
|
||||
svc = strchr(service, '/') + 1;
|
||||
|
||||
printf("Item gone!\n");
|
||||
|
||||
eldbus_service_signal_emit(iface, ITEM_UNREGISTERED, svc);
|
||||
if (l)
|
||||
{
|
||||
items = eina_list_remove_list(items, l);
|
||||
if (unregistered_cb)
|
||||
unregistered_cb(user_data, bus, svc);
|
||||
}
|
||||
bus = eina_stringshare_add(bus);
|
||||
if (eina_hash_del_by_key(systray_ctx_get()->config->items, bus))
|
||||
e_config_save_queue();
|
||||
eina_stringshare_del(bus);
|
||||
items = eina_list_remove(items, service);
|
||||
eldbus_name_owner_changed_callback_del(conn, bus, item_name_monitor_cb, service);
|
||||
eina_stringshare_del(service);
|
||||
}
|
||||
|
@ -70,7 +55,7 @@ register_item_cb(const Eldbus_Service_Interface *s_iface, const Eldbus_Message *
|
|||
* and is expecting to have its send id watched as it is not providing a real bus name here */
|
||||
stupid = !!strncmp(svc, "org.", 4);
|
||||
|
||||
snprintf(buf, sizeof(buf), "%s/%s", stupid ? eldbus_message_sender_get(msg) : svc, stupid ? svc : "/StatusNotifierItem");
|
||||
snprintf(buf, sizeof(buf), "%s/%s", stupid ? eldbus_message_sender_get(msg) : svc, stupid ? svc : "StatusNotifierItem");
|
||||
service = eina_stringshare_add(buf);
|
||||
if (eina_list_data_find(items, service))
|
||||
{
|
||||
|
@ -79,41 +64,51 @@ register_item_cb(const Eldbus_Service_Interface *s_iface, const Eldbus_Message *
|
|||
}
|
||||
|
||||
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,
|
||||
item_name_monitor_cb, service,
|
||||
EINA_FALSE);
|
||||
|
||||
if (registered_cb)
|
||||
registered_cb(user_data, stupid ? eldbus_message_sender_get(msg) : svc, stupid ? svc : "/StatusNotifierItem");
|
||||
printf("Item registered %s\n", service);
|
||||
|
||||
return eldbus_message_method_return_new(msg);
|
||||
}
|
||||
|
||||
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, ""))
|
||||
return;
|
||||
|
||||
printf("Host gone!\n");
|
||||
|
||||
eldbus_service_signal_emit(iface, HOST_UNREGISTERED);
|
||||
eina_stringshare_del(host_service);
|
||||
host_service = 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 *
|
||||
register_host_cb(const Eldbus_Service_Interface *s_iface, const Eldbus_Message *msg)
|
||||
{
|
||||
if (host_service)
|
||||
return eldbus_message_error_new(msg, ERROR_HOST_ALREADY_REGISTERED, "");
|
||||
const char *tmpservice = NULL, *service;
|
||||
|
||||
if (!eldbus_message_arguments_get(msg, "s", &host_service))
|
||||
printf("Host registed!\n");
|
||||
|
||||
if (!eldbus_message_arguments_get(msg, "s", &tmpservice))
|
||||
return NULL;
|
||||
|
||||
host_service = eina_stringshare_add(host_service);
|
||||
service = eina_stringshare_add(tmpservice);
|
||||
if (eina_list_data_find(hosts, service))
|
||||
{
|
||||
eina_stringshare_del(service);
|
||||
return eldbus_message_error_new(msg, ERROR_HOST_ALREADY_REGISTERED, "");
|
||||
}
|
||||
|
||||
hosts = eina_list_append(hosts, service);
|
||||
eldbus_service_signal_emit(s_iface, HOST_REGISTERED);
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -130,11 +125,14 @@ properties_get(const Eldbus_Service_Interface *s_iface EINA_UNUSED, const char *
|
|||
|
||||
eldbus_message_iter_arguments_append(iter, "as", &array);
|
||||
EINA_LIST_FOREACH(items, l, service)
|
||||
eldbus_message_iter_arguments_append(array, "s", service);
|
||||
{
|
||||
eldbus_message_iter_arguments_append(array, "s", service);
|
||||
printf("Add %s\n", service);
|
||||
}
|
||||
eldbus_message_iter_container_close(iter, array);
|
||||
}
|
||||
else if (!strcmp(propname, "IsStatusNotifierHostRegistered"))
|
||||
eldbus_message_iter_arguments_append(iter, "b", host_service ? EINA_TRUE : EINA_FALSE);
|
||||
eldbus_message_iter_arguments_append(iter, "b", hosts ? EINA_TRUE : EINA_FALSE);
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
|
@ -167,57 +165,11 @@ static const Eldbus_Service_Interface_Desc iface_desc = {
|
|||
IFACE, methods, signals, properties, properties_get, NULL
|
||||
};
|
||||
|
||||
|
||||
static void
|
||||
systray_notifier_item_hash_del(Notifier_Item_Cache *item)
|
||||
{
|
||||
eina_stringshare_del(item->path);
|
||||
free(item);
|
||||
}
|
||||
|
||||
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)
|
||||
systray_notifier_dbus_watcher_start(void)
|
||||
{
|
||||
const char *dbus;
|
||||
|
||||
EINA_SAFETY_ON_TRUE_RETURN(!!conn);
|
||||
conn = connection;
|
||||
started = EINA_TRUE;
|
||||
iface = eldbus_service_interface_register(conn, PATH, &iface_desc);
|
||||
registered_cb = registered;
|
||||
unregistered_cb = unregistered;
|
||||
user_data = (void *)data;
|
||||
host_service = eina_stringshare_add("internal");
|
||||
dbus = eldbus_connection_unique_name_get(conn);
|
||||
if (systray_ctx_get()->config->items)
|
||||
eina_hash_free_cb_set(systray_ctx_get()->config->items, (Eina_Free_Cb)systray_notifier_item_hash_del);
|
||||
if (dbus && systray_ctx_get()->config->dbus && systray_ctx_get()->config->items)
|
||||
{
|
||||
if (!strcmp(systray_ctx_get()->config->dbus, dbus))
|
||||
{
|
||||
Eina_Iterator *it;
|
||||
Eina_Hash_Tuple *t;
|
||||
|
||||
it = eina_hash_iterator_tuple_new(systray_ctx_get()->config->items);
|
||||
EINA_ITERATOR_FOREACH(it, t)
|
||||
{
|
||||
char buf[1024];
|
||||
Notifier_Item_Cache *nic = t->data;
|
||||
|
||||
snprintf(buf, sizeof(buf), "%s/%s", (char*)t->key, nic->path);
|
||||
eldbus_name_owner_changed_callback_add(conn, t->key,
|
||||
item_name_monitor_cb, eina_stringshare_add(buf),
|
||||
EINA_TRUE);
|
||||
}
|
||||
eina_iterator_free(it);
|
||||
return;
|
||||
}
|
||||
}
|
||||
eina_stringshare_replace(&systray_ctx_get()->config->dbus, dbus);
|
||||
if (systray_ctx_get()->config->items)
|
||||
eina_hash_free_buckets(systray_ctx_get()->config->items);
|
||||
else
|
||||
systray_ctx_get()->config->items = eina_hash_stringshared_new((Eina_Free_Cb)systray_notifier_item_hash_del);
|
||||
e_config_save_queue();
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -225,6 +177,8 @@ systray_notifier_dbus_watcher_stop(void)
|
|||
{
|
||||
const char *txt;
|
||||
|
||||
if (!started) return;
|
||||
|
||||
eldbus_service_interface_unregister(iface);
|
||||
EINA_LIST_FREE(items, txt)
|
||||
{
|
||||
|
@ -239,9 +193,58 @@ systray_notifier_dbus_watcher_stop(void)
|
|||
free(bus);
|
||||
eina_stringshare_del(txt);
|
||||
}
|
||||
if (host_service)
|
||||
eina_stringshare_del(host_service);
|
||||
conn = NULL;
|
||||
E_FREE_FUNC(systray_ctx_get()->config->items, eina_hash_free);
|
||||
eina_stringshare_replace(&systray_ctx_get()->config->dbus, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
name_request_cb(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending)
|
||||
{
|
||||
const char *error, *error_msg;
|
||||
unsigned flag;
|
||||
Eldbus_Object *obj;
|
||||
|
||||
if (eldbus_message_error_get(msg, &error, &error_msg))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!eldbus_message_arguments_get(msg, "u", &flag))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (flag == ELDBUS_NAME_REQUEST_REPLY_PRIMARY_OWNER)
|
||||
{
|
||||
systray_notifier_dbus_watcher_start();
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
//there is allready a daemon
|
||||
printf("There is allready a daemon");
|
||||
ecore_main_loop_quit();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
eina_init();
|
||||
ecore_init();
|
||||
eldbus_init();
|
||||
|
||||
conn = eldbus_connection_get(ELDBUS_CONNECTION_TYPE_SESSION);
|
||||
|
||||
eldbus_name_request(conn, WATCHER_BUS, ELDBUS_NAME_REQUEST_FLAG_REPLACE_EXISTING,
|
||||
name_request_cb, NULL);
|
||||
|
||||
ecore_main_loop_begin();
|
||||
|
||||
systray_notifier_dbus_watcher_stop();
|
||||
|
||||
eldbus_connection_unref(conn);
|
||||
|
||||
eldbus_shutdown();
|
||||
ecore_shutdown();
|
||||
eina_shutdown();
|
||||
return 1;
|
||||
}
|
Loading…
Reference in New Issue