diff --git a/src/bin/Makefile.mk b/src/bin/Makefile.mk index 5aa474bdd..6c7ad6f0c 100644 --- a/src/bin/Makefile.mk +++ b/src/bin/Makefile.mk @@ -101,6 +101,7 @@ src/bin/e_grab_dialog.h \ src/bin/e.h \ src/bin/e_hints.h \ src/bin/e_icon.h \ +src/bin/e_iconify.h \ src/bin/e_ilist.h \ src/bin/e_import_config_dialog.h \ src/bin/e_import_dialog.h \ @@ -266,6 +267,7 @@ src/bin/e_grabinput.c \ src/bin/e_grab_dialog.c \ src/bin/e_hints.c \ src/bin/e_icon.c \ +src/bin/e_iconify.c \ src/bin/e_ilist.c \ src/bin/e_import_config_dialog.c \ src/bin/e_import_dialog.c \ diff --git a/src/bin/e_comp_object.c b/src/bin/e_comp_object.c index cfa92452b..8019b8d7c 100644 --- a/src/bin/e_comp_object.c +++ b/src/bin/e_comp_object.c @@ -498,12 +498,18 @@ _e_comp_object_shadow_setup(E_Comp_Object *cw) if (cw->visible || cw->ec->re_manage) e_comp_object_signal_emit(cw->smart_obj, "e,state,visible", "e"); else if (cw->ec->iconic) - e_comp_object_signal_emit(cw->smart_obj, "e,action,iconify", "e"); + { + e_iconify_provider_obj_message(cw->ec, EINA_TRUE, cw->shobj); + e_comp_object_signal_emit(cw->smart_obj, "e,action,iconify", "e"); + } else e_comp_object_signal_emit(cw->smart_obj, "e,state,hidden", "e"); if (cw->ec->iconic && cw->ec->re_manage) - e_comp_object_signal_emit(cw->smart_obj, "e,action,iconify", "e"); + { + e_iconify_provider_obj_message(cw->ec, EINA_TRUE, cw->shobj); + e_comp_object_signal_emit(cw->smart_obj, "e,action,iconify", "e"); + } if (!cw->zoomap_disabled) e_zoomap_child_set(cw->zoomobj, NULL); if (cw->frame_object) @@ -1159,7 +1165,10 @@ _e_comp_intercept_hide(void *data, Evas_Object *obj) cw->animating = 1; e_object_ref(E_OBJECT(cw->ec)); if (cw->ec->iconic) - e_comp_object_signal_emit(obj, "e,action,iconify", "e"); + { + e_iconify_provider_obj_message(cw->ec, EINA_TRUE, cw->shobj); + e_comp_object_signal_emit(obj, "e,action,iconify", "e"); + } else e_comp_object_signal_emit(obj, "e,state,hidden", "e"); } @@ -1180,6 +1189,7 @@ _e_comp_intercept_show_helper(E_Comp_Object *cw) { if (cw->ec->iconic && cw->animating) { + e_iconify_provider_obj_message(cw->ec, EINA_FALSE, cw->shobj); e_comp_object_signal_emit(cw->smart_obj, "e,action,uniconify", "e"); cw->defer_hide = 0; } @@ -1831,7 +1841,10 @@ _e_comp_smart_show(Evas_Object *obj) e_comp_shape_queue(cw->comp); if (cw->ec->input_only) return; if (cw->ec->iconic) - e_comp_object_signal_emit(cw->smart_obj, "e,action,uniconify", "e"); + { + e_iconify_provider_obj_message(cw->ec, EINA_FALSE, cw->shobj); + e_comp_object_signal_emit(cw->smart_obj, "e,action,uniconify", "e"); + } else e_comp_object_signal_emit(cw->smart_obj, "e,state,visible", "e"); if (!cw->animating) diff --git a/src/bin/e_iconify.c b/src/bin/e_iconify.c new file mode 100644 index 000000000..6cf3372e6 --- /dev/null +++ b/src/bin/e_iconify.c @@ -0,0 +1,84 @@ +#include "e.h" + +typedef struct _E_Iconify_Provider E_Iconify_Provider; + +struct _E_Iconify_Provider +{ + E_Iconify_Provider_Cb func; + const void *data; + int pri; +}; + +static Eina_List *_e_iconify_providers = NULL; + +static E_Iconify_Provider * +_e_iconify_provider_get(void) +{ + Eina_List *l; + E_Iconify_Provider *prov, *prov_found = NULL; + int pri_found = -9999; + + EINA_LIST_FOREACH(_e_iconify_providers, l, prov) + { + if (prov->pri >= pri_found) prov_found = prov; + } + return prov_found; +} + +EAPI void +e_iconify_provider_add(int pri, E_Iconify_Provider_Cb provider, const void *data) +{ + E_Iconify_Provider *prov; + + prov = E_NEW(E_Iconify_Provider, 1); + if (!prov) return; + _e_iconify_providers = eina_list_append(_e_iconify_providers, prov); + prov->func = provider; + prov->data = data; + prov->pri = pri; +} + +EAPI void +e_iconify_provider_del(int pri, E_Iconify_Provider_Cb provider, const void *data) +{ + Eina_List *l; + E_Iconify_Provider *prov; + + EINA_LIST_FOREACH(_e_iconify_providers, l, prov) + { + if ((prov->func == provider) && + (prov->data == data) && + (prov->pri == pri)) + { + _e_iconify_providers = + eina_list_remove_list(_e_iconify_providers, l); + free(prov); + return; + } + } +} + +EAPI void +e_iconify_provider_obj_message(E_Client *ec, Eina_Bool iconify, Evas_Object *edje_target) +{ + E_Iconify_Provider *prov; + Evas_Coord ox, oy, ow, oh; + Edje_Message_Int_Set *msg; + int x, y, w, h; + + prov = _e_iconify_provider_get(); + if (!prov) return; + evas_object_geometry_get(edje_target, &ox, &oy, &ow, &oh); + x = ox + (ow / 2); + y = oy + (oh / 2); + w = 1; + h = 1; + prov->func((void *)(prov->data), ec, iconify, &x, &y, &w, &h); + msg = alloca(sizeof(Edje_Message_Int_Set) + ((4 - 1) * sizeof(int))); + msg->count = 4; + msg->val[0] = x - ox; + msg->val[1] = y - oy; + msg->val[2] = w; + msg->val[3] = h; + edje_object_message_send(edje_target, EDJE_MESSAGE_INT_SET, 10, msg); +} diff --git a/src/bin/e_iconify.h b/src/bin/e_iconify.h new file mode 100644 index 000000000..1642b725c --- /dev/null +++ b/src/bin/e_iconify.h @@ -0,0 +1,15 @@ +#ifdef E_TYPEDEFS + +typedef void (*E_Iconify_Provider_Cb) (void *data, E_Client *ec, Eina_Bool iconify, int *x, int *y, int *w, int *h); + +#else + +#ifndef E_ICONIFY_H +#define E_ICONIFY_H + +EAPI void e_iconify_provider_add(int pri, E_Iconify_Provider_Cb provider, const void *data); +EAPI void e_iconify_provider_del(int pri, E_Iconify_Provider_Cb provider, const void *data); +EAPI void e_iconify_provider_obj_message(E_Client *ec, Eina_Bool iconify, Evas_Object *edje_target); + +#endif +#endif diff --git a/src/bin/e_includes.h b/src/bin/e_includes.h index 79f7c75d7..be2712467 100644 --- a/src/bin/e_includes.h +++ b/src/bin/e_includes.h @@ -154,3 +154,4 @@ #include "e_comp_cfdata.h" #include "e_comp_canvas.h" #include "e_utils.h" +#include "e_iconify.h" diff --git a/src/modules/ibox/e_mod_main.c b/src/modules/ibox/e_mod_main.c index 8627267b1..16fb147ba 100644 --- a/src/modules/ibox/e_mod_main.c +++ b/src/modules/ibox/e_mod_main.c @@ -116,6 +116,35 @@ static E_Config_DD *conf_item_edd = NULL; Config *ibox_config = NULL; +static void +_ibox_cb_iconify_provider(void *data, E_Client *ec, Eina_Bool iconify EINA_UNUSED, int *x, int *y, int *w, int *h) +{ + Instance *inst = data; + IBox_Icon *ic; + Evas_Coord ox, oy, ow, oh; + Eina_List *l; + + EINA_LIST_FOREACH(inst->ibox->icons, l, ic) + { + if (ic->client == ec) + { + evas_object_geometry_get(ic->o_holder, &ox, &oy, &ow, &oh); + *x = ox; + *y = oy; + *w = ow; + *h = oh; + return; + } + } + // XXX: ibox doesn't know yet where a new icon might go... so assume right + // edge of ibox + evas_object_geometry_get(inst->ibox->o_box, &ox, &oy, &ow, &oh); + *x = ox + ow - 1; + *y = oy + (oh / 2); + *w = 1; + *h = 1; +} + static E_Gadcon_Client * _gc_init(E_Gadcon *gc, const char *name, const char *id, const char *style) { @@ -156,6 +185,9 @@ _gc_init(E_Gadcon *gc, const char *name, const char *id, const char *style) evas_object_event_callback_add(o, EVAS_CALLBACK_RESIZE, _ibox_cb_obj_moveresize, inst); ibox_config->instances = eina_list_append(ibox_config->instances, inst); + // add highest priority iconify provider - tasks and ibar can do this + // but lower priority + e_iconify_provider_add(100, _ibox_cb_iconify_provider, inst); return gcc; } @@ -165,6 +197,7 @@ _gc_shutdown(E_Gadcon_Client *gcc) Instance *inst; inst = gcc->data; + e_iconify_provider_del(100, _ibox_cb_iconify_provider, inst); inst->ci->gcc = NULL; ibox_config->instances = eina_list_remove(ibox_config->instances, inst); e_drop_handler_del(inst->drop_handler);