diff --git a/src/bin/e_actions.c b/src/bin/e_actions.c index e81f15036..3e08742c9 100644 --- a/src/bin/e_actions.c +++ b/src/bin/e_actions.c @@ -1964,6 +1964,238 @@ ACT_FN_GO(desk_lock) e_desklock_show(); } +/***************************************************************************/ + +typedef struct _Delayed_Action Delayed_Action; + +struct _Delayed_Action +{ + int mouse; + int button; + const char *keyname; + E_Object *obj; + Ecore_Timer *timer; + struct { + const char *action; + const char *params; + } def, delayed; +}; + +static Evas_List *_delayed_actions = NULL; + +static void +_delayed_action_free(Delayed_Action *da) +{ + if (da->obj) e_object_unref(da->obj); + if (da->keyname) evas_stringshare_del(da->keyname); + if (da->timer) ecore_timer_del(da->timer); + if (da->def.action) evas_stringshare_del(da->def.action); + if (da->def.params) evas_stringshare_del(da->def.params); + if (da->delayed.action) evas_stringshare_del(da->delayed.action); + if (da->delayed.params) evas_stringshare_del(da->delayed.params); + free(da); +} + +static int +_delayed_action_cb_timer(void *data) +{ + Delayed_Action *da; + E_Action *act; + + da = data; + da->timer = NULL; + act = e_action_find(da->delayed.action); + if (act) + { + if (act->func.go) act->func.go(da->obj, da->delayed.params); + } + _delayed_actions = evas_list_remove(_delayed_actions, da); + _delayed_action_free(da); + return 0; +} + +static void +_delayed_action_do(Delayed_Action *da) +{ + E_Action *act; + + act = e_action_find(da->def.action); + if (act) + { + if (act->func.go) act->func.go(da->obj, da->def.params); + } +} + +static void +_delayed_action_list_parse_action(const char *str, double *delay, const char **action, const char **params) +{ + char fbuf[16]; + char buf[1024]; + const char *p; + + buf[0] = 0; + sscanf(str, "%10s %1000s", fbuf, buf); + *action = evas_stringshare_add(buf); + *delay = atof(fbuf); + p = strchr(str, ' '); + if (p) + { + p++; + p = strchr(p, ' '); + if (p) + { + p++; + *params = evas_stringshare_add(p); + } + } +} + +static int +_delayed_action_list_parse(Delayed_Action *da, const char *params) +{ + double delay = 2.0; + const char *p, + *a1start = NULL, *a1stop = NULL, + *a2start = NULL, *a2stop = NULL; + + // FORMAT: "[0.0 default_action param1 param2] [x.x action2 param1 param2]" + p = params; + while (*p) + { + if ((*p == '[') && ((p == params) || ((p > params) && (p[-1] != '\\')))) {a1start = p + 1; break;} + p++; + } + while (*p) + { + if ((*p == ']') && ((p == params) || ((p > params) && (p[-1] != '\\')))) {a1stop = p; break;} + p++; + } + while (*p) + { + if ((*p == '[') && ((p == params) || ((p > params) && (p[-1] != '\\')))) {a2start = p + 1; break;} + p++; + } + while (*p) + { + if ((*p == ']') && ((p == params) || ((p > params) && (p[-1] != '\\')))) {a2stop = p; break;} + p++; + } + if ((a1start) && (a2start) && (a1stop) && (a2stop)) + { + char *a1, *a2; + const char *action, *params; + + a1 = alloca(a1stop - a1start + 1); + strncpy(a1, a1start, a1stop - a1start); + a1[a1stop - a1start] = 0; + action = NULL; + params = NULL; + _delayed_action_list_parse_action(a1, &delay, &da->def.action, &da->def.params); + + a2 = alloca(a1stop - a1start + 1); + strncpy(a2, a2start, a2stop - a2start); + a2[a2stop - a2start] = 0; + _delayed_action_list_parse_action(a2, &delay, &da->delayed.action, &da->delayed.params); + } + da->timer = ecore_timer_add(delay, _delayed_action_cb_timer, da); +} + +static void +_delayed_action_key_add(E_Object *obj, const char *params, Ecore_X_Event_Key_Down *ev) +{ + Delayed_Action *da; + + da = E_NEW(Delayed_Action, 1); + if (!da) return; + if (obj) + { + da->obj = obj; + e_object_ref(da->obj); + } + da->mouse = 0; + da->keyname = evas_stringshare_add(ev->keyname); + if (params) _delayed_action_list_parse(da, params); + _delayed_actions = evas_list_append(_delayed_actions, da); +} + +static void +_delayed_action_key_del(E_Object *obj, const char *params, Ecore_X_Event_Key_Up *ev) +{ + Evas_List *l; + + for (l = _delayed_actions; l; l = l->next) + { + Delayed_Action *da; + + da = l->data; + if ((da->obj == obj) && (!da->mouse) && + (!strcmp(da->keyname, ev->keyname))) + { + _delayed_action_do(da); + _delayed_action_free(da); + _delayed_actions = evas_list_remove_list(_delayed_actions, l); + return; + } + } +} + +static void +_delayed_action_mouse_add(E_Object *obj, const char *params, Ecore_X_Event_Mouse_Button_Down *ev) +{ + Delayed_Action *da; + + da = E_NEW(Delayed_Action, 1); + if (!da) return; + if (obj) + { + da->obj = obj; + e_object_ref(da->obj); + } + da->mouse = 1; + da->button = ev->button; + if (params) _delayed_action_list_parse(da, params); + _delayed_actions = evas_list_append(_delayed_actions, da); +} + +static void +_delayed_action_mouse_del(E_Object *obj, const char *params, Ecore_X_Event_Mouse_Button_Up *ev) +{ + Evas_List *l; + + for (l = _delayed_actions; l; l = l->next) + { + Delayed_Action *da; + + da = l->data; + if ((da->obj == obj) && (da->mouse) && + (ev->button == da->button)) + { + _delayed_action_do(da); + _delayed_action_free(da); + _delayed_actions = evas_list_remove_list(_delayed_actions, l); + return; + } + } +} + +// obj , params , ev +ACT_FN_GO_KEY(delayed_action) +{ + _delayed_action_key_add(obj, params, ev); +} +ACT_FN_GO_MOUSE(delayed_action) +{ + _delayed_action_mouse_add(obj, params, ev); +} +ACT_FN_END_KEY(delayed_action) +{ + _delayed_action_key_del(obj, params, ev); +} +ACT_FN_END_MOUSE(delayed_action) +{ + _delayed_action_mouse_del(obj, params, ev); +} + /* local subsystem globals */ static Evas_Hash *actions = NULL; static Evas_List *action_list = NULL; @@ -2342,6 +2574,14 @@ e_actions_init(void) e_action_predef_name_set(_("Desktop"), _("Cleanup Windows"), "cleanup_windows", NULL, NULL, 0); + /* delayed_action */ + ACT_GO_KEY(delayed_action); + e_action_predef_name_set(_("Generic : Actions"), _("Delayed Action"), + "delayed_action", NULL, "[0.0 exec xterm] [0.3 exec xev]", 1); + ACT_GO_MOUSE(delayed_action); + ACT_END_KEY(delayed_action); + ACT_END_MOUSE(delayed_action); + return 1; } diff --git a/src/bin/e_manager.c b/src/bin/e_manager.c index 569acdb4c..acc1ebcdc 100644 --- a/src/bin/e_manager.c +++ b/src/bin/e_manager.c @@ -598,6 +598,16 @@ _e_manager_cb_key_down(void *data, int ev_type __UNUSED__, void *ev) static int _e_manager_cb_key_up(void *data, int ev_type __UNUSED__, void *ev) { + E_Manager *man; + Ecore_X_Event_Key_Up *e; + + man = data; + e = ev; + + if (e->event_win != man->root) return 1; + if (e->root_win != man->root) man = _e_manager_get_for_root(e->root_win); + if (e_bindings_key_up_event_handle(E_BINDING_CONTEXT_MANAGER, E_OBJECT(man), ev)) + return 0; return 1; }