#include "e.h" #include "e_mod_main.h" /* TODO * - keybinding configuration */ #define DRAG_OFF_WINDOW #define INPUTLEN 256 #define MATCH_LAG 0.15 #define INITIAL_MATCH_LAG 0.3 #if defined (CHECK_TIME) || defined (CHECK_REFS) #undef DBG #define DBG(...) ERR(__VA_ARGS__) #else #undef DBG #define DBG(...) #endif static Eina_Bool _evry_cb_desklock(Evry_Window *win, int type EINA_UNUSED, E_Event_Desklock *ev); static void _evry_matches_update(Evry_Selector *sel, int async); static void _evry_plugin_action(Evry_Selector *sel, int finished); static void _evry_plugin_select(Evry_State *s, Evry_Plugin *p); static void _evry_plugin_list_insert(Evry_State *s, Evry_Plugin *p); static int _evry_backspace(Evry_Selector *sel); static void _evry_update(Evry_Selector *sel, int fetch); static void _evry_update_text_label(Evry_State *s); static int _evry_clear(Evry_Selector *sel); static Eina_Bool _evry_cb_update_timer(void *data); static Evry_State *_evry_state_new(Evry_Selector *sel, Eina_List *plugins); static void _evry_state_pop(Evry_Selector *sel, int immediate); static void _evry_state_clear(Evry_Window *win); static void _evry_hide_func(Evry_Window *win, int finished); static Evry_Selector *_evry_selector_new(Evry_Window *win, int type); static void _evry_selector_free(Evry_Selector *sel); static void _evry_selector_activate(Evry_Selector *sel, int slide); static void _evry_selector_update(Evry_Selector *sel); static int _evry_selector_plugins_get(Evry_Selector *sel, Evry_Item *it, const char *plugin_name); static void _evry_selector_update_actions(Evry_Selector *sel); static void _evry_selector_item_update(Evry_Selector *sel); static void _evry_selector_item_clear(Evry_Selector *sel); static void _evry_selector_label_set(Evry_Selector *sel, const char *part, const char *label); static void _evry_selector_signal_emit(Evry_Selector *sel, const char *msg); static int _evry_selectors_shift(Evry_Window *win, int dir); static int _evry_selectors_switch(Evry_Window *win, int dir); static Evry_Window *_evry_window_new(E_Zone *zone, E_Zone_Edge edge); static void _evry_cb_win_delete(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED); static void _evry_window_free(Evry_Window *win); static void _evry_list_win_show(Evry_Window *win); static void _evry_list_win_hide(Evry_Window *win); static void _evry_list_win_update(Evry_State *s); static int _evry_view_create(Evry_State *s); static void _evry_view_clear(Evry_State *s); static int _evry_view_update(Evry_Window *win, Evry_State *s); static int _evry_view_key_press(Evry_State *s, Ecore_Event_Key *ev); static void _evry_view_show(Evry_Window *win, Evry_View *v, int slide); static void _evry_view_hide(Evry_Window *win, Evry_View *v, int slide); static void _evry_item_desel(Evry_State *s); static void _evry_item_sel(Evry_State *s, Evry_Item *it); static void _evry_cb_show(Evry_Window *win, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED); static Eina_Bool _evry_cb_key_down(void *data, int type, void *event); static Eina_Bool _evry_cb_selection_notify(void *data, int type, void *event); static Eina_Bool _evry_cb_mouse(void *data, int type, void *event); static Eina_Bool _evry_delay_hide_timer(void *data); static Eina_Bool _evry_focus_out_timer(void *data); static Eina_List *windows = NULL; #ifdef CHECK_TIME double _evry_time; #endif #ifdef CHECK_REFS static int _item_cnt = 0; Eina_List *_refd = NULL; #endif #define SUBJ_SEL win->selectors[0] #define ACTN_SEL win->selectors[1] #define OBJ_SEL win->selectors[2] #define CUR_SEL win->selector int evry_init(void) { return 1; } int evry_shutdown(void) { while (windows) evry_hide(windows->data, 0); return 1; } static int _evry_aggregator_fetch(Evry_State *s) { Eina_List *l; if (!s) { ERR("no state"); return 0; } if (s->aggregator->fetch(s->aggregator, s->input)) { l = eina_list_data_find_list(s->cur_plugins, s->aggregator); if (!l) s->cur_plugins = eina_list_prepend(s->cur_plugins, s->aggregator); else s->cur_plugins = eina_list_promote_list(s->cur_plugins, l); return 1; } s->cur_plugins = eina_list_remove(s->cur_plugins, s->aggregator); return 1; } static Eina_Bool _evry_cb_item_changed(EINA_UNUSED void *data, EINA_UNUSED int type, void *event) { Evry_Event_Item_Changed *ev = event; Evry_Selector *sel; Evry_Item *it = ev->item; if (!it || !it->plugin || !it->plugin->state) return ECORE_CALLBACK_PASS_ON; sel = it->plugin->state->selector; if (sel->state && sel->state->cur_item == it) { _evry_selector_update(sel); } return ECORE_CALLBACK_PASS_ON; } static Eina_Bool _evry_focus_out_timer(void *data) { Evry_Window *win = data; E_Client *ec; win->delay_hide_action = NULL; ec = e_win_client_get(win->ewin); if (ec && (!e_object_is_del(E_OBJECT(ec)))) evry_hide(win, 0); return ECORE_CALLBACK_CANCEL; } static void _evry_focus_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) { Evry_Window *win = data; if (!win->grab) return; if (win->delay_hide_action) ecore_timer_del(win->delay_hide_action); win->delay_hide_action = ecore_timer_loop_add(0.0, _evry_focus_out_timer, win); } static void _evry_focus_in(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) { Evry_Window *win = data; if (!win->grab) return; E_FREE_FUNC(win->delay_hide_action, ecore_timer_del); } Evry_Window * evry_show(E_Zone *zone, E_Zone_Edge edge, const char *params, Eina_Bool popup) { Evry_Window *win; Evry_Selector *sel; #ifdef CHECK_TIME _evry_time = ecore_time_get(); DBG("_____evry_show______"); #endif E_OBJECT_CHECK_RETURN(zone, 0); E_OBJECT_TYPE_CHECK_RETURN(zone, E_ZONE_TYPE, 0); if (popup) { // only one popup please Eina_List *l; EINA_LIST_FOREACH(windows, l, win) if (win->grab) return NULL; } if (!(win = _evry_window_new(zone, edge))) return NULL; if (popup) { E_Client *ec; ecore_evas_name_class_set(e_win_ee_get(win->ewin), "E", "everything"); evas_object_show(win->ewin); ec = e_win_client_get(win->ewin); if (ec) { #ifndef HAVE_WAYLAND_ONLY if (e_comp->comp_type == E_PIXMAP_TYPE_X) ecore_x_netwm_window_type_set(elm_win_window_id_get(win->ewin), ECORE_X_WINDOW_TYPE_UTILITY); #endif ec->netwm.state.skip_taskbar = 1; EC_CHANGED(ec); evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_FOCUS_OUT, _evry_focus_out, win); evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_FOCUS_IN, _evry_focus_in, win); } win->grab = 1; } evry_history_load(); if (params) win->plugin_dedicated = EINA_TRUE; win->sel_list = E_NEW(Evry_Selector *, 4); win->sel_list[3] = NULL; win->selectors = win->sel_list; _evry_selector_new(win, EVRY_PLUGIN_SUBJECT); _evry_selector_new(win, EVRY_PLUGIN_ACTION); _evry_selector_new(win, EVRY_PLUGIN_OBJECT); E_LIST_HANDLER_APPEND(win->handlers, ECORE_EVENT_KEY_DOWN, _evry_cb_key_down, win); #ifndef HAVE_WAYLAND_ONLY if (e_comp->comp_type == E_PIXMAP_TYPE_X) E_LIST_HANDLER_APPEND(win->handlers, ECORE_X_EVENT_SELECTION_NOTIFY, _evry_cb_selection_notify, win); #endif evas_object_event_callback_add(e_win_client_get(win->ewin)->frame, EVAS_CALLBACK_SHOW, (Evas_Object_Event_Cb)_evry_cb_show, win); E_LIST_HANDLER_APPEND(win->handlers, _evry_events[EVRY_EVENT_ITEM_CHANGED], _evry_cb_item_changed, win); E_LIST_HANDLER_APPEND(win->handlers, ECORE_EVENT_MOUSE_BUTTON_DOWN, _evry_cb_mouse, win); E_LIST_HANDLER_APPEND(win->handlers, ECORE_EVENT_MOUSE_BUTTON_UP, _evry_cb_mouse, win); E_LIST_HANDLER_APPEND(win->handlers, E_EVENT_DESKLOCK, _evry_cb_desklock, win); #if 0 E_LIST_HANDLER_APPEND(win->handlers, ECORE_EVENT_MOUSE_MOVE, _evry_cb_mouse, win); E_LIST_HANDLER_APPEND(win->handlers, ECORE_EVENT_MOUSE_WHEEL, _evry_cb_mouse, win); E_LIST_HANDLER_APPEND(win->handlers, ECORE_X_EVENT_MOUSE_IN, _evry_cb_mouse_in, win); E_LIST_HANDLER_APPEND(win->handlers, ECORE_X_EVENT_MOUSE_OUT, _evry_cb_mouse_out, win); #endif _evry_selector_plugins_get(SUBJ_SEL, NULL, params); _evry_selector_update(SUBJ_SEL); windows = eina_list_append(windows, win); _evry_selector_activate(SUBJ_SEL, 0); if ((!evry_conf->hide_list) || (edge)) { sel = CUR_SEL; if (sel && sel->state && evry_conf->views) { /* if (evry_conf->first_run) * { * evry_view_toggle(sel->state, "?"); * evry_conf->first_run = EINA_FALSE; * } */ edje_object_signal_emit(win->o_main, "list:e,state,list_show", "e"); edje_object_signal_emit(win->o_main, "list:e,state,entry_show", "e"); win->visible = EINA_TRUE; } } win->func.hide = &_evry_hide_func; win->delay_hide_action = ecore_timer_loop_add(0.2, _evry_delay_hide_timer, win); return win; } static Eina_Bool _evry_delay_hide_timer(void *data) { Evry_Window *win = data; win->delay_hide_action = NULL; return ECORE_CALLBACK_CANCEL; } static void _evry_hide_func(Evry_Window *win, int finished) { if ((finished) && (win->grab)) evry_hide(win, 0); } void evry_hide(Evry_Window *win, int clear) { Ecore_Event_Handler *ev; int i; if (!win) return; evas_object_event_callback_del(win->ewin, EVAS_CALLBACK_DEL, _evry_cb_win_delete); evas_object_event_callback_del(e_win_client_get(win->ewin)->frame, EVAS_CALLBACK_FOCUS_OUT, _evry_focus_out); evas_object_hide(win->ewin); _evry_state_clear(win); if ((clear && CUR_SEL) && /* pop states */ ((eina_list_count((SUBJ_SEL)->states) > 1) || /* move to subject selector */ (CUR_SEL != SUBJ_SEL) || /* clear input */ (((CUR_SEL)->state) && ((CUR_SEL)->state->input[0])))) { int slide = 0; Evry_Selector *sel; Evry_State *s; if (CUR_SEL != SUBJ_SEL) { if (CUR_SEL == ACTN_SEL) _evry_selectors_switch(win, -1); else if (CUR_SEL == OBJ_SEL) _evry_selectors_switch(win, 1); } /* just to be sure */ CUR_SEL = SUBJ_SEL; while ((CUR_SEL)->states->next) { slide = SLIDE_RIGHT; _evry_state_pop(CUR_SEL, 1); } sel = CUR_SEL; s = sel->state; _evry_clear(sel); _evry_clear(sel); _evry_aggregator_fetch(s); _evry_selector_update(sel); _evry_update_text_label(s); if (s->view) { _evry_view_show(win, s->view, slide); s->view->update(s->view); } return; } if (_evry_selectors_shift(win, -1)) return; win->visible = EINA_FALSE; if (win->sel_list) { for (i = 0; win->sel_list[i]; i++) _evry_selector_free(win->sel_list[i]); } E_FREE(win->sel_list); EINA_LIST_FREE (win->handlers, ev) ecore_event_handler_del(ev); if (win->delay_hide_action) ecore_timer_del(win->delay_hide_action); if (win->grab) e_grabinput_release(elm_win_window_id_get(win->ewin), elm_win_window_id_get(win->ewin)); windows = eina_list_remove(windows, win); _evry_window_free(win); evry_history_unload(); #ifdef CHECK_REFS Evry_Item *_it; int _cnt = eina_list_count(_refd); Eina_List *_l; printf("__________________________"); EINA_LIST_FOREACH (_refd, _l, _it) printf("%d %s\n", _it->ref, _it->label); printf("sum: %d", _cnt); #endif } static int _evry_selectors_shift(Evry_Window *win, int dir) { if ((dir > 0) && (win->level == 0)) { void *new_sel; Evry_Selector *sel; Evry_State *s; int i; for (i = 1; i < 3; i++) _evry_selector_item_clear(win->selectors[i]); if (!(new_sel = realloc(win->sel_list, sizeof(Evry_Selector *) * 6))) return 0; win->sel_list = new_sel; edje_object_signal_emit(win->o_main, "e,state,object_selector_hide", "e"); win->sel_list[5] = NULL; win->selectors = win->sel_list + 2; _evry_selector_new(win, EVRY_PLUGIN_ACTION); _evry_selector_new(win, EVRY_PLUGIN_OBJECT); CUR_SEL = SUBJ_SEL; sel = CUR_SEL; _evry_selector_signal_emit(sel, "e,state,selected"); _evry_selector_item_update(SUBJ_SEL); _evry_selector_item_update(ACTN_SEL); _evry_selector_item_update(OBJ_SEL); /* was checked before. anyway */ if ((s = sel->state) && (s->cur_item)) _evry_selector_update_actions(sel); win->level++; return 1; } else if ((dir < 0) && (win->level > 0)) { _evry_selector_item_clear(SUBJ_SEL); _evry_selector_free(ACTN_SEL); _evry_selector_free(OBJ_SEL); win->selectors = win->sel_list; win->sel_list[3] = NULL; CUR_SEL = NULL; edje_object_signal_emit(win->o_main, "e,state,object_selector_show", "e"); _evry_selector_item_update(SUBJ_SEL); _evry_selector_item_update(ACTN_SEL); _evry_selector_item_update(OBJ_SEL); _evry_selector_activate(OBJ_SEL, 0); win->level = 0; return 1; } return 0; } Evry_Item * evry_item_new(Evry_Item *it, Evry_Plugin *p, const char *label, Evas_Object *(*icon_get)(Evry_Item * it, Evas * e), void (*cb_free)(Evry_Item *item)) { if (!it) { it = E_NEW(Evry_Item, 1); if (!it) return NULL; } if (p && EVRY_ITEM(p)->subtype) it->type = EVRY_ITEM(p)->subtype; it->plugin = p; if (label) it->label = eina_stringshare_add(label); it->free = cb_free; it->icon_get = icon_get; it->ref = 1; #ifdef CHECK_REFS _item_cnt++; _refd = eina_list_append(_refd, it); #endif #ifdef PRINT_REFS printf("%d, %d\t new : %s\n", it->ref, _item_cnt, it->label); #endif return it; } void evry_item_free(Evry_Item *it) { if (!it) return; it->ref--; #ifdef PRINT_REFS printf("%d, %d\t unref: %s\n", it->ref, _item_cnt, it->label); #endif if (it->ref > 0) return; #ifdef CHECK_REFS _item_cnt--; _refd = eina_list_remove(_refd, it); #endif IF_RELEASE(it->label); IF_RELEASE(it->id); IF_RELEASE(it->context); IF_RELEASE(it->detail); IF_RELEASE(it->icon); if (it->free) it->free(it); else E_FREE(it); } void evry_item_ref(Evry_Item *it) { it->ref++; #ifdef PRINT_REFS printf("%d, %d\t ref : %s\n", it->ref, _item_cnt, it->label); #endif } static int _evry_selector_update_actions_do(Evry_Selector *sel) { Evry_State *s; Evry_Window *win = sel->win; if (sel->action_timer) { ecore_timer_del(sel->action_timer); sel->action_timer = NULL; } if ((s = (SUBJ_SEL)->state)) _evry_selector_plugins_get(sel, s->cur_item, NULL); _evry_selector_update(sel); return 1; } static Eina_Bool _evry_timer_cb_actions_get(void *data) { Evry_Selector *sel = data; Evry_Window *win = sel->win; Evry_State *s; _evry_selector_update_actions_do(sel); if ((CUR_SEL == sel) && (s = sel->state)) { if (_evry_view_update(win, s)) _evry_view_show(win, s->view, 0); } return ECORE_CALLBACK_CANCEL; } static void _evry_selector_update_actions(Evry_Selector *sel) { if (sel->action_timer) ecore_timer_del(sel->action_timer); _evry_selector_item_clear(sel); sel->action_timer = ecore_timer_loop_add(0.2, _evry_timer_cb_actions_get, sel); } void evry_item_select(const Evry_State *state, Evry_Item *it) { Evry_State *s = (Evry_State *)state; Evry_Selector *sel; Evry_Window *win; if ((!s) || (s->delete_me)) return; sel = s->selector; win = sel->win; s->plugin_auto_selected = EINA_FALSE; s->item_auto_selected = EINA_FALSE; _evry_item_sel(s, it); if (s == sel->state) { _evry_selector_update(sel); if (CUR_SEL == SUBJ_SEL) _evry_selector_update_actions(ACTN_SEL); if (CUR_SEL == ACTN_SEL) { while (OBJ_SEL->state) _evry_state_pop(OBJ_SEL, 1); } } } void evry_item_mark(const Evry_State *state, Evry_Item *it, Eina_Bool mark) { Evry_State *s = (Evry_State *)state; if ((!s) || (s->delete_me)) return; if (mark && !it->marked) { it->marked = EINA_TRUE; s->sel_items = eina_list_append(s->sel_items, it); } else if (it->marked) { it->marked = EINA_FALSE; s->sel_items = eina_list_remove(s->sel_items, it); } } void evry_plugin_update(Evry_Plugin *p, int action) { Evry_State *s; Evry_Selector *sel; Evry_Window *win; if (!(s = p->state) || (s->delete_me)) return; if (!(sel = s->selector)) return; if (!(win = sel->win)) return; if (sel->state->request != p->request) return; DBG("update %d %d %s", s->request, p->request, p->name); if (action == EVRY_UPDATE_ADD) { /* clear marked items */ if (s->sel_items) { eina_list_free(s->sel_items); s->sel_items = NULL; } if ((!p->items) && (!s->trigger_active)) { /* remove plugin */ if (!(eina_list_data_find(s->cur_plugins, p))) return; s->cur_plugins = eina_list_remove(s->cur_plugins, p); if (p == s->plugin) _evry_plugin_select(s, NULL); } else { /* add plugin to current plugins*/ _evry_plugin_list_insert(s, p); } if (sel->state == s) { _evry_aggregator_fetch(s); /* select first plugin */ if ((!s->plugin) || (s->plugin_auto_selected) || !(eina_list_data_find(s->cur_plugins, s->plugin))) { _evry_plugin_select(s, NULL); } if ((s->plugin && (sel->state == s)) && /* plugin is current */ ((s->plugin == p) || /* plugin items are shown in aggregator */ ((s->plugin == s->aggregator) && p->config->aggregate))) { _evry_selector_update(sel); if (_evry_view_update(win, s)) /* XXX when there is a case where view disappears check this one! is swallow always visible ? */ _evry_view_show(win, s->view, 0); } /* switch back to subject selector when no current items */ if ((sel == SUBJ_SEL) && (!(s->plugin) || !(s->plugin->items)) && (CUR_SEL == ACTN_SEL)) { _evry_selectors_switch(win, -1); _evry_clear(SUBJ_SEL); } } } else if (action == EVRY_UPDATE_REFRESH) { _evry_view_clear(s); _evry_view_update(win, s); } } static void _evry_list_win_show(Evry_Window *win) { if (win->visible) return; win->visible = EINA_TRUE; _evry_list_win_update((CUR_SEL)->state); edje_object_signal_emit(win->o_main, "list:e,state,list_show", "e"); edje_object_signal_emit(win->o_main, "list:e,state,entry_show", "e"); } static void _evry_list_win_hide(Evry_Window *win) { Evry_Selector *sel = CUR_SEL; if (!win->visible) return; if (!evry_conf->hide_list) return; if (sel->state) _evry_view_clear(sel->state); win->visible = EINA_FALSE; edje_object_signal_emit(win->o_main, "list:e,state,list_hide", "e"); if (evry_conf->hide_input && (!(sel->state) || (sel->state->input[0]))) edje_object_signal_emit(win->o_main, "list:e,state,entry_hide", "e"); } static void _evry_cb_win_delete(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) { evry_hide(data, 0); } static Evry_Window * _evry_window_new(E_Zone *zone, E_Zone_Edge edge) { int x, y, mw, mh, h, w; Evry_Window *win; Evas_Object *o; const char *tmp; int offset_s = 0; win = E_NEW(Evry_Window, 1); win->ewin = elm_win_add(NULL, NULL, ELM_WIN_UTILITY); elm_win_borderless_set(win->ewin, 1); e_win_no_remember_set(win->ewin, 1); e_win_placed_set(win->ewin, 1); elm_win_override_set(win->ewin, 1); win->evas = evas_object_evas_get(win->ewin); win->zone = zone; evas_object_data_set(win->ewin, "evry_win", win); o = edje_object_add(win->evas); win->o_main = o; elm_win_resize_object_add(win->ewin, o); E_EXPAND(o); E_FILL(o); e_theme_edje_object_set(o, "base/theme/modules/everything", "e/modules/everything/main"); edje_object_signal_emit(o, "e,state,composited", "e"); edje_object_signal_emit(o, "list:e,state,composited", "e"); edje_object_message_signal_process(o); edje_object_calc_force(o); tmp = edje_object_data_get(o, "shadow_offset"); offset_s = tmp ? atoi(tmp) : 0; edje_object_size_min_calc(o, &mw, &mh); if (edge == E_ZONE_EDGE_NONE) { w = evry_conf->width; h = evry_conf->height; } else { w = evry_conf->edge_width; h = evry_conf->edge_height; } evas_object_size_hint_min_set(win->ewin, mw, mh); evry_conf->min_w = mw; if (w > mw) mw = w; evry_conf->min_h = mh; if (h > mh) mh = h; if (edge == E_ZONE_EDGE_NONE) { mw += offset_s * 2; mh += offset_s * 2; x = (zone->x + (zone->w * evry_conf->rel_x)) - (mw / 2); y = (zone->y + (zone->h * evry_conf->rel_y)) - (mh / 2); } else { int to_side = 0; switch (edge) { case E_ZONE_EDGE_TOP_LEFT: x = to_side - offset_s; y = to_side - offset_s; break; case E_ZONE_EDGE_TOP_RIGHT: x = zone->w - (mw + offset_s + to_side); y = to_side - offset_s; break; case E_ZONE_EDGE_BOTTOM_RIGHT: x = zone->w - (mw + offset_s + to_side); y = zone->h - (mh + offset_s + to_side); break; case E_ZONE_EDGE_BOTTOM_LEFT: x = to_side - offset_s; y = zone->h - (mh + offset_s + to_side); break; default: mw += offset_s * 2; mh += offset_s * 2; x = (zone->w * evry_conf->rel_x) - (mw / 2); y = (zone->h * evry_conf->rel_y) - (mh / 2); break; } x += zone->x; y += zone->y; mw += offset_s * 2; mh += offset_s * 2; } evas_object_geometry_set(win->ewin, x, y, mw, mh); evas_object_show(o); evas_event_feed_mouse_in(win->evas, 0, NULL); evas_event_feed_mouse_move(win->evas, -1000000, -1000000, 0, NULL); evas_object_event_callback_add(win->ewin, EVAS_CALLBACK_DEL, _evry_cb_win_delete, win); return win; } #if 0 static void _evry_cb_drag_finished(E_Drag *drag, int dropped) { E_FREE(drag->data); } #endif static Eina_Bool _evry_cb_desklock(Evry_Window *win, int type EINA_UNUSED, E_Event_Desklock *ev) { if (ev->on) evry_hide(win, 0); return ECORE_CALLBACK_RENEW; } static Eina_Bool _evry_cb_mouse(void *data, int type, void *event) { Ecore_Event_Mouse_Button *ev; Evry_Window *win = data; Evas_Object *ewin; int x, y, w, h; ev = event; if (!win->grab) return ECORE_CALLBACK_PASS_ON; if ((ev->event_window != ecore_evas_window_get(e_comp->ee)) && (ev->event_window != elm_win_window_id_get(win->ewin))) return ECORE_CALLBACK_PASS_ON; ewin = win->ewin; #if 0 if (type == ECORE_EVENT_MOUSE_MOVE) { Ecore_Event_Mouse_Move *ev = event; Evry_State *s; if ((win->mouse_button == 3) && (s = (CUR_SEL)->state) && (s->cur_item) && (CHECK_TYPE(s->cur_item, EVRY_TYPE_FILE)) && (!E_INSIDE(ev->x, ev->y, win->zone->x, win->zone->y, ewin->w, ewin->h))) { const char *drag_types[] = { "text/uri-list" }; E_Drag *d; Evas_Object *o; const char *uri; int s_len, sel_length = 0; char *tmp, *sel = NULL; GET_FILE(file, s->cur_item); if (!(uri = evry_file_url_get(file))) return ECORE_CALLBACK_PASS_ON; s_len = strlen(uri); if (!(tmp = realloc(sel, sel_length + s_len + 2 + 1))) return ECORE_CALLBACK_PASS_ON; sel = tmp; memcpy(sel + sel_length, uri, s_len); memcpy(sel + sel_length + s_len, "\r\n", 2); sel_length += s_len + 2; d = e_drag_new(e_comp), ev->x, ev->y, drag_types, 1, sel, sel_length, NULL, _evry_cb_drag_finished); e_drag_resize(d, 128, 128); o = evry_util_icon_get(s->cur_item, e_drag_evas_get(d)); e_drag_object_set(d, o); e_drag_xdnd_start(d, ev->x, ev->y); evry_hide(win, 0); return ECORE_CALLBACK_PASS_ON; } } else if (type == ECORE_EVENT_MOUSE_WHEEL) { Ecore_Event_Mouse_Wheel *ev = event; } else #endif evas_object_geometry_get(ewin, &x, &y, &w, &h); if (type == ECORE_EVENT_MOUSE_BUTTON_DOWN) { win->mouse_out = 0; if (e_comp->comp_type == E_PIXMAP_TYPE_WL) { if (ev->event_window == ecore_evas_window_get(e_comp->ee)) { if (!E_INSIDE(e_comp_canvas_x_root_adjust(ev->root.x), e_comp_canvas_y_root_adjust(ev->root.y), x, y, w, h)) win->mouse_out = 1; } } else if (!E_INSIDE(e_comp_canvas_x_root_adjust(ev->root.x), e_comp_canvas_y_root_adjust(ev->root.y), x, y, w, h)) win->mouse_out = 1; if (win->mouse_out) return ECORE_CALLBACK_PASS_ON; win->mouse_button = ev->buttons; } else if (type == ECORE_EVENT_MOUSE_BUTTON_UP) { win->mouse_button = 0; if (win->mouse_out) { evry_hide(win, 0); return ECORE_CALLBACK_PASS_ON; } } return ECORE_CALLBACK_PASS_ON; } static void _evry_window_free(Evry_Window *win) { evas_event_freeze(win->evas); evas_object_event_callback_del(e_win_client_get(win->ewin)->frame, EVAS_CALLBACK_SHOW, (Evas_Object_Event_Cb)_evry_cb_show); evas_object_del(win->ewin); free(win); } static void _evry_selector_cb_down(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info) { Evas_Event_Mouse_Down *ev = event_info; Evry_Selector *sel = data; if (ev->button == 1) { if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK) evry_plugin_action(sel->win, 1); } } static void _evry_selector_cb_wheel(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info) { Evas_Event_Mouse_Wheel *ev = event_info; Evry_Selector *sel = data; Evry_Window *win = sel->win; if (ev->z > 0) { /* FIXME dont loose selector 2 state until state 0 changed: */ if (CUR_SEL != OBJ_SEL) _evry_selectors_switch(sel->win, 1); } else if (ev->z < 0) { _evry_selectors_switch(sel->win, -1); } } static void _evry_selector_cb_up(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info) { Evas_Event_Mouse_Up *ev = event_info; Evry_Selector *sel = data; Evry_Window *win = sel->win; if (sel == CUR_SEL) return; if (ev->button == 3) { evry_plugin_action(win, 0); } else if (ev->button == 1) { if (sel == SUBJ_SEL) { if (CUR_SEL == ACTN_SEL) _evry_selectors_switch(win, -1); else _evry_selectors_switch(win, 1); } else if (sel == ACTN_SEL) { if (CUR_SEL == SUBJ_SEL) _evry_selectors_switch(win, 1); else _evry_selectors_switch(win, -1); } else if (sel == OBJ_SEL) { if (CUR_SEL == ACTN_SEL) _evry_selectors_switch(win, 1); } } } static Evry_Selector * _evry_selector_new(Evry_Window *win, int type) { Plugin_Config *pc; Eina_List *l, *pcs = NULL; Evry_Selector *sel = E_NEW(Evry_Selector, 1); const Evas_Object *o = NULL; sel->aggregator = evry_aggregator_new(type); if (type == EVRY_PLUGIN_SUBJECT) { pcs = evry_conf->conf_subjects; sel->edje_part = "subject_selector"; } else if (type == EVRY_PLUGIN_ACTION) { pcs = evry_conf->conf_actions; sel->edje_part = "action_selector"; } else if (type == EVRY_PLUGIN_OBJECT) { pcs = evry_conf->conf_objects; sel->edje_part = "object_selector"; } if ((o = edje_object_part_object_get(win->o_main, sel->edje_part))) { sel->event_object = o; evas_object_event_callback_add((Evas_Object*) o, EVAS_CALLBACK_MOUSE_DOWN, _evry_selector_cb_down, sel); evas_object_event_callback_add((Evas_Object*) o, EVAS_CALLBACK_MOUSE_UP, _evry_selector_cb_up, sel); evas_object_event_callback_add((Evas_Object*) o, EVAS_CALLBACK_MOUSE_WHEEL, _evry_selector_cb_wheel, sel); } EINA_LIST_FOREACH (pcs, l, pc) { if (!pc->plugin) continue; if (pc->plugin == sel->aggregator) continue; sel->plugins = eina_list_append(sel->plugins, pc->plugin); } win->selectors[type] = sel; sel->win = win; return sel; } static void _evry_selector_free(Evry_Selector *sel) { Evry_Window *win = sel->win; if (sel->event_object) { evas_object_event_callback_del_full((Evas_Object*)sel->event_object, EVAS_CALLBACK_MOUSE_DOWN, _evry_selector_cb_down, sel); evas_object_event_callback_del_full((Evas_Object*)sel->event_object, EVAS_CALLBACK_MOUSE_UP, _evry_selector_cb_up, sel); evas_object_event_callback_del_full((Evas_Object*)sel->event_object, EVAS_CALLBACK_MOUSE_WHEEL, _evry_selector_cb_wheel, sel); } _evry_selector_item_clear(sel); if (win->visible && (sel == CUR_SEL)) _evry_view_clear(sel->state); while (sel->states) _evry_state_pop(sel, 1); EVRY_PLUGIN_FREE(sel->aggregator); if (sel->plugins) eina_list_free(sel->plugins); if (sel->update_timer) ecore_timer_del(sel->update_timer); if (sel->action_timer) ecore_timer_del(sel->action_timer); E_FREE(sel); } static void _evry_selector_signal_emit(Evry_Selector *sel, const char *msg) { Evry_Window *win = sel->win; char buf[128]; snprintf(buf, sizeof(buf), "%s:%s", sel->edje_part, msg); edje_object_signal_emit(win->o_main, buf, "e"); } static void _evry_selector_label_set(Evry_Selector *sel, const char *part, const char *label) { Evry_Window *win = sel->win; char buf[128]; snprintf(buf, sizeof(buf), "%s:%s", sel->edje_part, part); edje_object_part_text_set(win->o_main, buf, label); } static void _evry_selector_activate(Evry_Selector *sel, int slide) { Evry_Window *win; Evry_State *s; if (!sel) { ERR("selector == NULL"); return; } win = sel->win; if (CUR_SEL) { Evry_Selector *cur = CUR_SEL; _evry_selector_signal_emit(cur, "e,state,unselected"); if (cur->state && cur->state->view) _evry_view_hide(win, cur->state->view, slide); if (!slide && evry_conf->hide_list) _evry_list_win_hide(win); } CUR_SEL = sel; _evry_selector_signal_emit(sel, "e,state,selected"); /* do delayed actions fetch now */ if (sel->action_timer) _evry_selector_update_actions_do(sel); if ((s = sel->state)) { _evry_update_text_label(s); if (s->cur_item) _evry_selector_label_set(sel, "e.text.plugin", EVRY_ITEM(s->cur_item->plugin)->label); if (_evry_view_create(s)) { _evry_view_show(win, s->view, slide); s->view->update(s->view); } } } static void _evry_selector_thumb_gen(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) { Evas_Coord w, h; Evry_Selector *sel = data; Evry_Window *win = sel->win; char buf[64]; if (sel->o_icon) { evas_object_del(sel->o_icon); sel->o_icon = NULL; } e_icon_size_get(sel->o_thumb, &w, &h); evas_object_size_hint_aspect_set(sel->o_thumb, EVAS_ASPECT_CONTROL_BOTH, w, h); snprintf(buf, sizeof(buf), "%s:e.swallow.thumb", sel->edje_part); edje_object_part_swallow(win->o_main, buf, sel->o_thumb); evas_object_show(sel->o_thumb); _evry_selector_signal_emit(sel, "e,action,thumb,show"); /* edje_object_signal_emit(sel->o_main, "e,action,thumb,show", "e"); */ sel->do_thumb = EINA_FALSE; } static int _evry_selector_thumb(Evry_Selector *sel, const Evry_Item *it) { Evry_Window *win = sel->win; char *suffix = NULL; if (sel->do_thumb) e_thumb_icon_end(sel->o_thumb); if (sel->o_thumb) evas_object_del(sel->o_thumb); sel->o_thumb = NULL; if (it->type != EVRY_TYPE_FILE) return 0; GET_FILE(file, it); if (!file->mime) return 0; if (!(evry_file_path_get(file))) return 0; if ((!strncmp(file->mime, "image/", 6)) || ((suffix = strrchr(file->path, '.')) && (!strncmp(suffix, ".edj", 4)))) { sel->o_thumb = e_thumb_icon_add(win->evas); e_thumb_icon_size_set(sel->o_thumb, 128, 128); evas_object_smart_callback_add(sel->o_thumb, "e_thumb_gen", _evry_selector_thumb_gen, sel); if (suffix) { e_thumb_icon_file_set(sel->o_thumb, file->path, "e/desktop/background"); e_thumb_icon_size_set(sel->o_thumb, 128, 80); } else e_thumb_icon_file_set(sel->o_thumb, file->path, NULL); e_thumb_icon_begin(sel->o_thumb); sel->do_thumb = EINA_TRUE; return 1; } return 0; } static void _evry_selector_item_clear(Evry_Selector *sel) { if (sel->o_icon) { evas_object_del(sel->o_icon); sel->o_icon = NULL; } if (sel->o_thumb) { if (sel->do_thumb) e_thumb_icon_end(sel->o_thumb); evas_object_del(sel->o_thumb); sel->o_thumb = NULL; } } static void _evry_selector_item_update(Evry_Selector *sel) { Evry_State *s = sel->state; Evry_Item *it = NULL; Evas_Object *o = NULL; Evry_Window *win = sel->win; _evry_selector_item_clear(sel); if ((!s) || !(s->cur_item)) { /* no items for this state - clear selector */ _evry_selector_label_set(sel, "e.text.label", ""); if (sel == CUR_SEL && s && s->plugin) _evry_selector_label_set(sel, "e.text.plugin", EVRY_ITEM(s->plugin)->label); else _evry_selector_label_set(sel, "e.text.plugin", ""); if (!s) return; } if ((it = s->cur_item)) { _evry_selector_label_set(sel, "e.text.label", it->label); _evry_selector_label_set(sel, "e.text.plugin", EVRY_ITEM(it->plugin)->label); if (!_evry_selector_thumb(sel, it)) { o = evry_util_icon_get(it, win->evas); if ((!o) && it->plugin) o = evry_util_icon_get(EVRY_ITEM(it->plugin), win->evas); } } if ((!o) && (s->plugin && (EVRY_ITEM(s->plugin)->icon))) { o = evry_icon_theme_get(EVRY_ITEM(s->plugin)->icon, win->evas); } if (o) { char buf[64]; snprintf(buf, sizeof(buf), "%s:e.swallow.icons", sel->edje_part); edje_object_part_swallow(win->o_main, buf, o); evas_object_show(o); sel->o_icon = o; } } static void _evry_selector_update(Evry_Selector *sel) { Evry_State *s = sel->state; Evry_Item *it = NULL; Eina_Bool item_changed = EINA_FALSE; Evry_Window *win = sel->win; DBG("%p", sel); if (!s) { _evry_selector_item_update(sel); return; } if ((it = s->cur_item)) { if (!s->plugin || !eina_list_data_find_list(s->plugin->items, it)) { _evry_item_desel(s); item_changed = EINA_TRUE; } } /* get first item */ if (s->plugin && ((!s->cur_item) || s->item_auto_selected)) { it = eina_list_data_get(s->plugin->items); s->item_auto_selected = EINA_TRUE; if (!s->cur_plugins || (it != s->cur_item)) item_changed = EINA_TRUE; _evry_item_sel(s, it); } _evry_selector_item_update(sel); if ((sel == SUBJ_SEL) && (item_changed)) _evry_selector_update_actions(ACTN_SEL); } static void _evry_list_win_update(Evry_State *s) { Evry_Window *win = s->selector->win; if (s != (CUR_SEL)->state) return; if (!win->visible) return; if (_evry_view_update(win, s)) _evry_view_show(win, s->view, 0); } static int _evry_selector_plugins_get(Evry_Selector *sel, Evry_Item *it, const char *plugin_name) { Eina_List *l, *plugins = NULL; Evry_Plugin *p, *pp; Evry_Window *win = sel->win; Evry_Action *act = NULL; while (sel->state) _evry_state_pop(sel, 1); if ((sel != SUBJ_SEL) && (!it)) return 0; if (it && CHECK_TYPE(it, EVRY_TYPE_ACTION)) act = (Evry_Action *)it; EINA_LIST_FOREACH (sel->plugins, l, p) { if (!p->config->enabled && !win->plugin_dedicated) continue; if (plugin_name && strcmp(plugin_name, p->name)) continue; if (act && (!CHECK_SUBTYPE(p, act->it2.type))) continue; if (p->begin && (pp = p->begin(p, it))) plugins = eina_list_append(plugins, pp); } _evry_state_new(sel, plugins); if (plugins) _evry_matches_update(sel, 1); return 1; } static Evry_State * _evry_state_new(Evry_Selector *sel, Eina_List *plugins) { Evry_State *s = E_NEW(Evry_State, 1); Eina_List *l; Evry_Plugin *p; if (!s) return NULL; s->inp = calloc(1, INPUTLEN); s->inp[0] = 0; s->input = s->inp; s->plugins = plugins; s->selector = sel; sel->states = eina_list_prepend(sel->states, s); sel->state = s; p = sel->aggregator->begin(sel->aggregator, NULL); s->plugins = eina_list_append(s->plugins, p); s->aggregator = p; EINA_LIST_FOREACH (s->plugins, l, p) p->state = s; return s; } static void _evry_state_pop(Evry_Selector *sel, int immediate) { Evry_Plugin *p; Evry_State *prev; Evry_Window *win = sel->win; Evry_State *s = sel->state; _evry_item_desel(s); if (sel->update_timer) { ecore_timer_del(sel->update_timer); sel->update_timer = NULL; } if (sel->action_timer) { ecore_timer_del(sel->action_timer); sel->action_timer = NULL; } if (s->view) { if (immediate) { s->view->destroy(s->view); } else { _evry_view_hide(win, s->view, SLIDE_RIGHT); /* XXX delay free state? is it possible that view can receive events here? */ s->delete_me = EINA_TRUE; } } if (s->sel_items) eina_list_free(s->sel_items); if (s->cur_plugins) eina_list_free(s->cur_plugins); sel->states = eina_list_remove_list(sel->states, sel->states); prev = eina_list_data_get(sel->states); EINA_LIST_FREE (s->plugins, p) { /* skip non top-level plugins */ if (prev && eina_list_data_find(prev->plugins, p)) { p->state = prev; continue; } EVRY_ITEM_FREE(p); } if (!s->delete_me) { if (win->state_clearing == s) win->state_clearing = NULL; ecore_timer_del(s->clear_timer); E_FREE(s->inp); E_FREE(s); } sel->state = prev; } int evry_state_push(Evry_Selector *sel, Eina_List *plugins) { Evry_State *s, *new_state; Eina_List *l; Evry_Plugin *p; Evry_View *view = NULL; Evry_Window *win = sel->win; s = sel->state; if (!(new_state = _evry_state_new(sel, plugins))) { DBG("no new state"); return 0; } EINA_LIST_FOREACH (plugins, l, p) p->state = new_state; if (s && s->view) { _evry_view_hide(win, s->view, SLIDE_LEFT); view = s->view; } _evry_matches_update(sel, 1); s = new_state; _evry_selector_update(sel); if (view && win->visible) { s->view = view->create(view, s, win->o_main); if (s->view) { s->view->state = s; _evry_view_show(win, s->view, SLIDE_LEFT); s->view->update(s->view); } } _evry_update_text_label(sel->state); return 1; } int evry_browse_item(Evry_Item *it) { Evry_State *s, *new_state; Evry_Selector *sel; Eina_List *l, *plugins = NULL; Evry_Plugin *p, *pp, *pref = NULL; Evry_View *view = NULL; int browse_aggregator = 0; Evry_Window *win; if (!(it) || !(it->plugin) || !(it->browseable)) { DBG("no item"); return 0; } if (!(s = it->plugin->state)) { DBG("no state"); return 0; } sel = s->selector; win = sel->win; /* aggregator */ if (CHECK_TYPE(it, EVRY_TYPE_PLUGIN)) { browse_aggregator = 1; plugins = eina_list_append(plugins, it); } else { if ((it->plugin->browse) && (pp = it->plugin->browse(it->plugin, it))) { plugins = eina_list_append(plugins, pp); pref = pp; } /* items of type NONE can only be browsed by their own plugin */ if (!CHECK_TYPE(it, EVRY_TYPE_NONE)) { EINA_LIST_FOREACH (sel->plugins, l, p) { if (!p->browse) continue; if ((pref) && (!strcmp(p->name, pref->name))) continue; if ((pp = p->browse(p, it))) plugins = eina_list_append(plugins, pp); } } } if (!(plugins)) { DBG("no plugins"); return 0; } if (!(new_state = _evry_state_new(sel, plugins))) { DBG("no new state"); return 0; } if (s->view) { _evry_view_hide(win, s->view, SLIDE_LEFT); view = s->view; } if (browse_aggregator) { it->hi = NULL; if (!EVRY_PLUGIN(it)->items) { evry_history_item_add(it, NULL, s->input); s = new_state; EVRY_PLUGIN(it)->state = s; _evry_matches_update(sel, 1); } else { evry_history_item_add(it, NULL, NULL); strncpy(new_state->input, s->input, INPUTLEN); s = new_state; EVRY_PLUGIN(it)->state = s; s->cur_plugins = eina_list_append(s->cur_plugins, it); } _evry_plugin_select(s, EVRY_PLUGIN(it)); } else { if (it->plugin->history) evry_history_item_add(it, NULL, s->input); _evry_matches_update(sel, 1); s = new_state; _evry_plugin_select(s, pref); } _evry_selector_update(sel); if (view && win->visible) { s->view = view->create(view, s, win->o_main); if (s->view) { s->view->state = s; s->view->update(s->view); _evry_view_show(win, s->view, SLIDE_LEFT); } } _evry_update_text_label(sel->state); return 1; } int evry_browse_back(Evry_Selector *sel) { Evry_Window *win; if (!sel) return 0; if ((!sel) || !(win = sel->win)) return 0; if ((!sel->state) || (!sel->states->next)) return 0; _evry_state_pop(sel, 0); _evry_selector_update(sel); _evry_update_text_label(sel->state); if (sel == SUBJ_SEL) _evry_selector_update_actions(ACTN_SEL); if (sel->state->view) { _evry_view_show(win, sel->state->view, SLIDE_RIGHT); sel->state->view->update(sel->state->view); } return 1; } int evry_selectors_switch(Evry_Window *win, int dir, int slide) { Evry_State *s = (CUR_SEL)->state; if ((CUR_SEL)->update_timer) { if ((CUR_SEL == SUBJ_SEL) || (CUR_SEL == ACTN_SEL)) { _evry_matches_update(CUR_SEL, 0); _evry_selector_update(CUR_SEL); } } if (CUR_SEL != SUBJ_SEL && dir == 0) { edje_object_signal_emit(win->o_main, "e,state,object_selector_hide", "e"); _evry_selector_activate(SUBJ_SEL, (slide * SLIDE_RIGHT)); return 1; } if (CUR_SEL == SUBJ_SEL && dir > 0) { if (s->cur_item) { _evry_selector_activate(ACTN_SEL, slide * SLIDE_LEFT); return 1; } } else if (CUR_SEL == ACTN_SEL && dir > 0) { Evry_Item *it; if (!s || !(it = s->cur_item) || !(CHECK_TYPE(it, EVRY_TYPE_ACTION))) return 0; GET_ACTION(act, it); if (!act->it2.type) return 0; _evry_selector_plugins_get(OBJ_SEL, it, NULL); _evry_selector_update(OBJ_SEL); edje_object_signal_emit(win->o_main, "e,state,object_selector_show", "e"); _evry_selector_activate(OBJ_SEL, (slide * SLIDE_LEFT)); return 1; } else if (CUR_SEL == ACTN_SEL && dir < 0) { _evry_selector_activate(SUBJ_SEL, (slide * SLIDE_RIGHT)); edje_object_signal_emit(win->o_main, "e,state,object_selector_hide", "e"); return 1; } else if (CUR_SEL == OBJ_SEL && dir < 0) { _evry_selector_activate(ACTN_SEL, (slide * SLIDE_RIGHT)); return 1; } return 0; } static int _evry_selectors_switch(Evry_Window *win, int dir) { return evry_selectors_switch(win, dir, 0); } static int _evry_input_complete(Evry_State *s) { int action = 0; char *input = NULL; Evry_Item *it = s->cur_item; Evry_Window *win = s->selector->win; if (!it) return 0; evry_item_ref(it); s->item_auto_selected = EINA_FALSE; if (it->plugin->complete) action = it->plugin->complete(it->plugin, it, &input); else evry_browse_item(it); if (input && action == EVRY_COMPLETE_INPUT) { strncpy(s->input, input, INPUTLEN - 1); _evry_update_text_label(s); if (CUR_SEL->update_timer) { ecore_timer_del(CUR_SEL->update_timer); CUR_SEL->update_timer = NULL; } _evry_cb_update_timer(CUR_SEL); evry_item_select(s, it); } evry_item_free(it); E_FREE(input); return 1; } static int _evry_cheat_history(Evry_State *s, int promote, int delete) { History_Entry *he; History_Item *hi; History_Types *ht; Eina_List *l, *ll; Evry_Item *it = s->cur_item; if (!it) return 0; if (!(ht = evry_history_types_get(it->type))) return 1; if (!(he = eina_hash_find(ht->types, (it->id ? it->id : it->label)))) return 1; EINA_LIST_FOREACH_SAFE (he->items, l, ll, hi) { if (hi->plugin != it->plugin->name) continue; if (delete) { if (hi->input) eina_stringshare_del(hi->input); if (hi->plugin) eina_stringshare_del(hi->plugin); if (hi->context) eina_stringshare_del(hi->context); E_FREE(hi); he->items = eina_list_remove_list(he->items, l); } else if (promote) { hi->count += 5; hi->last_used = ecore_time_unix_get(); } else /* demote */ { hi->count -= 5; if (hi->count < 0) hi->count = 1; } } if (s->plugin == s->aggregator) _evry_aggregator_fetch(s); if (s->view) s->view->update(s->view); return 1; } static Eina_Bool _evry_cb_key_down(void *data, int type EINA_UNUSED, void *event) { Ecore_Event_Key *ev = event; Evry_State *s; Evry_Selector *sel; Evry_Window *win = data; const char *old; if ((win->grab && (ev->event_window != ecore_evas_window_get(e_comp->ee))) && (ev->event_window != elm_win_window_id_get(win->ewin))) return ECORE_CALLBACK_PASS_ON; if (!strcmp(ev->key, "Escape")) { evry_hide(win, 0); return ECORE_CALLBACK_PASS_ON; } #ifdef DRAG_OFF_WINDOW else if (win->grab && !strcmp(ev->key, "F1")) { Evas_Object *ewin = win->ewin; E_Client *ec; e_grabinput_release(elm_win_window_id_get(ewin), elm_win_window_id_get(ewin)); ec = e_win_client_get(ewin); elm_win_borderless_set(ewin, 0); ec->override = 0; #ifndef HAVE_WAYLAND_ONLY if (e_comp->comp_type == E_PIXMAP_TYPE_X) ecore_x_netwm_window_type_set(elm_win_window_id_get(ewin), ECORE_X_WINDOW_TYPE_DIALOG); #endif evas_object_layer_set(ec->frame, E_LAYER_CLIENT_NORMAL); EC_CHANGED(ec); ec->netwm.fetch.type = 1; ec->netwm.state.skip_taskbar = 0; ec->netwm.update.state = 1; ec->internal_no_remember = 1; e_comp_object_frame_theme_set(ec->frame, E_COMP_OBJECT_FRAME_RESHADOW); win->grab = 0; return ECORE_CALLBACK_PASS_ON; } #endif else if ((ev->modifiers) && (!win->delay_hide_action)) { Eina_List *l; E_Config_Binding_Key *binding; E_Binding_Modifier mod; EINA_LIST_FOREACH(e_bindings->key_bindings, l, binding) { if (binding->action && strcmp(binding->action, "everything")) continue; mod = 0; if (ev->modifiers & ECORE_EVENT_MODIFIER_SHIFT) mod |= E_BINDING_MODIFIER_SHIFT; if (ev->modifiers & ECORE_EVENT_MODIFIER_CTRL) mod |= E_BINDING_MODIFIER_CTRL; if (ev->modifiers & ECORE_EVENT_MODIFIER_ALT) mod |= E_BINDING_MODIFIER_ALT; if (ev->modifiers & ECORE_EVENT_MODIFIER_WIN) mod |= E_BINDING_MODIFIER_WIN; if (!(binding->key && (!strcmp(binding->key, ev->key)) && (((unsigned int)binding->modifiers == mod) || (binding->any_mod)))) continue; if (win->level > 0) return ECORE_CALLBACK_PASS_ON; if (!(binding->params) && (CUR_SEL == OBJ_SEL) && ((CUR_SEL)->state && (CUR_SEL)->state->cur_item)) { _evry_selectors_shift(win, 1); return ECORE_CALLBACK_PASS_ON; } evry_hide(win, 1); #if 0 /* FIXME this causes segv when triggering a plugin keybinding twice */ if (win && CUR_SEL && binding->params) { Eina_List *ll; Evry_Plugin *p; EINA_LIST_FOREACH ((SUBJ_SEL)->plugins, ll, p) if (!strcmp(binding->params, p->name)) break; if (p) { _evry_plugin_select((CUR_SEL)->state, p); _evry_selector_update(CUR_SEL); _evry_view_update(win, (CUR_SEL)->state); } } #endif return ECORE_CALLBACK_PASS_ON; } } old = ev->key; win->request_selection = EINA_FALSE; if (!strcmp(ev->key, "KP_Enter")) { ev->key = "Return"; } else if (ev->modifiers & ECORE_EVENT_MODIFIER_ALT) { if (!strcmp(ev->key, "Tab")) { ev->key = "Down"; } else if (!strcmp(ev->key, "ISO_Left_Tab") || (!strcmp(ev->key, "Tab") && (ev->modifiers & ECORE_EVENT_MODIFIER_SHIFT))) { ev->key = "Up"; ev->modifiers = 0; } else if (!strcmp(ev->key, "q")) { evry_hide(win, 0); return 1; } else if (!strcmp(ev->key, "w")) { ev->key = "Return"; ev->modifiers = 0; } else if (evry_conf->quick_nav == 1) { if (!strcmp(ev->key, "k") || (!strcmp(ev->key, "K"))) ev->key = "Up"; else if (!strcmp(ev->key, "j") || (!strcmp(ev->key, "J"))) ev->key = "Down"; else if (!strcmp(ev->key, "n") || (!strcmp(ev->key, "N"))) ev->key = "Next"; else if (!strcmp(ev->key, "p") || (!strcmp(ev->key, "P"))) ev->key = "Prior"; else if (!strcmp(ev->key, "l") || (!strcmp(ev->key, "L"))) ev->key = "Right"; else if (!strcmp(ev->key, "h") || (!strcmp(ev->key, "H"))) ev->key = "Left"; else if (!strcmp(ev->key, "i") || (!strcmp(ev->key, "I"))) ev->key = "Tab"; else if (!strcmp(ev->key, "m") || (!strcmp(ev->key, "M"))) ev->key = "Return"; } else if (evry_conf->quick_nav == 3) { if (!strcmp(ev->key, "p") || (!strcmp(ev->key, "P"))) ev->key = "Up"; else if (!strcmp(ev->key, "n") || (!strcmp(ev->key, "N"))) ev->key = "Down"; else if (!strcmp(ev->key, "f") || (!strcmp(ev->key, "F"))) ev->key = "Right"; else if (!strcmp(ev->key, "b") || (!strcmp(ev->key, "B"))) ev->key = "Left"; else if (!strcmp(ev->key, "i") || (!strcmp(ev->key, "I"))) ev->key = "Tab"; else if (!strcmp(ev->key, "m") || (!strcmp(ev->key, "M"))) ev->key = "Return"; } } if (!(sel = CUR_SEL)) goto end; if (!strcmp(ev->key, "Tab") && !((ev->modifiers & ECORE_EVENT_MODIFIER_CTRL) || (ev->modifiers & ECORE_EVENT_MODIFIER_SHIFT))) { if (!_evry_selectors_switch(win, 1)) _evry_selectors_switch(win, 0); goto end; } if (!(s = sel->state)) goto end; if (!win->visible && (!strcmp(ev->key, "Down"))) { _evry_list_win_show(win); goto end; } else if ((!strcmp(ev->key, "ISO_Left_Tab") || (((ev->modifiers & ECORE_EVENT_MODIFIER_CTRL) || (ev->modifiers & ECORE_EVENT_MODIFIER_SHIFT)) && (!strcmp(ev->key, "Tab"))))) { _evry_input_complete(s); goto end; } else if ((ev->modifiers & ECORE_EVENT_MODIFIER_CTRL) && (!strcmp(ev->key, "Delete") || !strcmp(ev->key, "Insert"))) { int delete = (!strcmp(ev->key, "Delete") && (ev->modifiers & ECORE_EVENT_MODIFIER_SHIFT)); int promote = (!strcmp(ev->key, "Insert")); _evry_cheat_history(s, promote, delete); goto end; } else if (ev->modifiers & ECORE_EVENT_MODIFIER_CTRL) { if (!strcmp(ev->key, "u")) { if (!_evry_clear(sel)) evry_browse_back(sel); goto end; } else if (!strcmp(ev->key, "1")) evry_view_toggle(s, NULL); else if (!strcmp(ev->key, "Return")) _evry_plugin_action(sel, 0); else if (!strcmp(ev->key, "v")) { #ifndef HAVE_WAYLAND_ONLY if (e_comp->comp_type == E_PIXMAP_TYPE_X) { win->request_selection = EINA_TRUE; ecore_x_selection_primary_request (elm_win_window_id_get(win->ewin), ECORE_X_SELECTION_TARGET_UTF8_STRING); } #endif } else { _evry_view_key_press(s, ev); } goto end; } if ((s->plugin && s->plugin->cb_key_down) && (s->plugin->cb_key_down(s->plugin, ev))) { /* let plugin intercept keypress */ goto end; } else if (_evry_view_key_press(s, ev)) { /* let view intercept keypress */ goto end; } else if (!strcmp(ev->key, "Right")) { if (!evry_browse_item(sel->state->cur_item)) evry_selectors_switch(win, 1, EINA_TRUE); } else if (!strcmp(ev->key, "Left")) { if (!evry_browse_back(sel)) evry_selectors_switch(win, -1, EINA_TRUE); } else if (!strcmp(ev->key, "Return")) { if (ev->modifiers & ECORE_EVENT_MODIFIER_SHIFT) { _evry_plugin_action(sel, 0); } else if (s->cur_item && s->cur_item->browseable) { evry_browse_item(sel->state->cur_item); } else { _evry_plugin_action(sel, 1); } } else if (!strcmp(ev->key, "BackSpace")) { if (!_evry_backspace(sel)) evry_browse_back(sel); } else if ((ev->compose && !(ev->modifiers & ECORE_EVENT_MODIFIER_ALT))) { unsigned int len = strlen(s->inp); if (len == 0 && (evry_view_toggle(s, ev->compose))) goto end; if (len < (INPUTLEN - strlen(ev->compose))) { strcat(s->inp, ev->compose); _evry_update(sel, 1); } } end: ev->key = old; return ECORE_CALLBACK_PASS_ON; } static int _evry_backspace(Evry_Selector *sel) { Evry_State *s = sel->state; int len, val, pos; if (!(len = strlen(s->inp))) return 0; pos = evas_string_char_prev_get(s->inp, len, &val); if ((pos < len) && (pos >= 0)) { val = *(s->inp + pos); s->inp[pos] = 0; if (s->trigger_active && s->inp[0] != 0) s->input = s->inp + 1; else s->input = s->inp; if (pos == 0) s->trigger_active = EINA_FALSE; if ((pos == 0) || !isspace(val)) _evry_update(sel, 1); return 1; } return 0; } static void _evry_update_text_label(Evry_State *s) { Evry_Window *win = s->selector->win; if (!win->visible && evry_conf->hide_input) { if (strlen(s->inp) > 0) edje_object_signal_emit(win->o_main, "list:e,state,entry_show", "e"); else edje_object_signal_emit(win->o_main, "list:e,state,entry_hide", "e"); } edje_object_part_text_set(win->o_main, "list:e.text.label", s->inp); } static void _evry_update(Evry_Selector *sel, int fetch) { Evry_State *s = sel->state; Evry_Window *win = sel->win; _evry_update_text_label(s); if (fetch) { if (sel->update_timer) ecore_timer_del(sel->update_timer); sel->update_timer = ecore_timer_loop_add(MATCH_LAG, _evry_cb_update_timer, sel); edje_object_signal_emit(win->o_main, "list:e,signal,update", "e"); } } static Eina_Bool _evry_cb_update_timer(void *data) { Evry_Selector *sel = data; _evry_matches_update(sel, 1); _evry_selector_update(sel); _evry_list_win_update(sel->state); sel->update_timer = NULL; return ECORE_CALLBACK_CANCEL; } static int _evry_clear(Evry_Selector *sel) { Evry_State *s = sel->state; Evry_Window *win = sel->win; if (!(s->inp) || (s->inp[0] == 0)) return 0; if (s->trigger_active && s->inp[1] != 0) { s->inp[1] = 0; s->input = s->inp + 1; } else { s->inp[0] = 0; s->input = s->inp; s->trigger_active = EINA_FALSE; } _evry_update(sel, 1); if (!win->visible && evry_conf->hide_input) edje_object_signal_emit(win->o_main, "list:e,state,entry_hide", "e"); return 1; } static void _evry_cb_free_action_performed(void *data EINA_UNUSED, void *event) { Evry_Event_Action_Performed *ev = event; if (ev->it1) EVRY_ITEM_FREE(ev->it1); if (ev->it2) EVRY_ITEM_FREE(ev->it2); IF_RELEASE(ev->action); E_FREE(ev); } static int _evry_action_do(Evry_Action *act) { Evry_Event_Action_Performed *ev; int ret; if ((ret = act->action(act))) { ev = E_NEW(Evry_Event_Action_Performed, 1); ev->action = eina_stringshare_ref(act->name); ev->it1 = act->it1.item; ev->it2 = act->it2.item; if (ev->it1) EVRY_ITEM_REF(ev->it1); if (ev->it2) EVRY_ITEM_REF(ev->it2); ecore_event_add(_evry_events[EVRY_EVENT_ACTION_PERFORMED], ev, _evry_cb_free_action_performed, NULL); return ret; } return 0; } void evry_plugin_action(Evry_Window *win, int finished) { _evry_plugin_action(CUR_SEL, finished); } static void _evry_plugin_action(Evry_Selector *sel, int finished) { Evry_State *s_subj, *s_act, *s_obj = NULL; Evry_Item *it, *it_subj, *it_act, *it_obj = NULL; Evry_Window *win = sel->win; Eina_List *l; int ret = 0; if ((SUBJ_SEL)->update_timer) { _evry_matches_update(SUBJ_SEL, 0); _evry_selector_update(SUBJ_SEL); } /* do delayed fetch actions now */ if ((ACTN_SEL)->action_timer) _evry_selector_update_actions_do(ACTN_SEL); if (!(s_subj = (SUBJ_SEL)->state)) return; if (!(it_subj = s_subj->cur_item)) return; if ((CUR_SEL == SUBJ_SEL) && (ACTN_SEL)->update_timer) { /* _evry_selector_actions_get(it_subj); */ _evry_selector_plugins_get(ACTN_SEL, it_subj, NULL); if (!(ACTN_SEL)->state) return; _evry_selector_update(ACTN_SEL); } if (!(s_act = (ACTN_SEL)->state)) return; if (!(it_act = s_act->cur_item)) return; if (CHECK_TYPE(it_act, EVRY_TYPE_ACTION) || CHECK_SUBTYPE(it_act, EVRY_TYPE_ACTION)) { GET_ACTION(act, it_act); if (!act->action) return; /* get object item for action, when required */ if (act->it2.type) { /* check if object is provided */ if ((s_obj = (OBJ_SEL)->state) && (!s_obj->delete_me)) { it_obj = s_obj->cur_item; } if (!it_obj) { if (SUBJ_SEL == CUR_SEL) _evry_selectors_switch(win, 1); if (ACTN_SEL == CUR_SEL) _evry_selectors_switch(win, 1); return; } act->it2.item = it_obj; } if (s_obj && s_obj->sel_items && !(act->it2.accept_list)) { if (!(act->it1.item && CHECK_TYPE(act->it1.item, EVRY_TYPE_PLUGIN))) act->it1.item = it_subj; EINA_LIST_FOREACH (s_obj->sel_items, l, it) { if (it->type != act->it2.type) continue; act->it2.item = it; _evry_action_do(act); } } else if (s_subj->sel_items && !(act->it1.accept_list)) { EINA_LIST_FOREACH (s_subj->sel_items, l, it) { if (it->type != act->it1.type) continue; act->it1.item = it; _evry_action_do(act); } } else { if (!(act->it1.item && CHECK_TYPE(act->it1.item, EVRY_TYPE_PLUGIN))) { act->it1.item = it_subj; act->it1.items = s_subj->sel_items; } if (s_obj) act->it2.items = s_obj->sel_items; ret = _evry_action_do(act); if (ret == EVRY_ACTION_OTHER) return; } } else return; if (s_subj && it_subj && it_subj->plugin->history) evry_history_item_add(it_subj, NULL, s_subj->input); if (s_act && it_act && it_act->plugin->history) evry_history_item_add(it_act, it_subj->context, s_act->input); if (s_obj && it_obj && it_obj->plugin->history) evry_history_item_add(it_obj, it_act->context, s_obj->input); if (ret == EVRY_ACTION_CONTINUE) return; if (ret == EVRY_ACTION_CLEAR) { _evry_clear(CUR_SEL); } else { win->func.hide(win, finished); } } static void _evry_view_list_swallow_set(Evas_Object *obj, const char *part, Evas_Object *swallow) { Evas_Object *o; o = edje_object_part_swallow_get(obj, part); if (o != swallow) { evas_object_hide(o); edje_object_part_unswallow(obj, o); edje_object_part_unswallow(obj, swallow); edje_object_part_swallow(obj, part, swallow); evas_object_show(swallow); } } static void _evry_view_show(Evry_Window *win, Evry_View *v, int slide) { if (!v) return; if (v->o_bar) { edje_object_part_swallow(win->o_main, "list:e.swallow.bar", v->o_bar); evas_object_show(v->o_bar); } if (!v->o_list) return; if (slide == SLIDE_LEFT) { _evry_view_list_swallow_set(win->o_main, "list:e.swallow.list2", v->o_list); edje_object_signal_emit(win->o_main, "list:e,action,slide,left", "e"); edje_object_signal_emit(v->o_list, "e,action,show,list", "e"); } else if (slide == SLIDE_RIGHT) { _evry_view_list_swallow_set(win->o_main, "list:e.swallow.list", v->o_list); edje_object_signal_emit(win->o_main, "list:e,action,slide,right", "e"); edje_object_signal_emit(v->o_list, "e,action,show,list", "e"); } else { _evry_view_list_swallow_set(win->o_main, "list:e.swallow.list", v->o_list); edje_object_signal_emit(win->o_main, "list:e,action,slide,default", "e"); edje_object_signal_emit(v->o_list, "e,action,show,list", "e"); } } static Eina_Bool _clear_timer(void *data) { _evry_state_clear(data); return ECORE_CALLBACK_CANCEL; } static void _evry_state_clear(Evry_Window *win) { Evry_State *s; Evry_View *v; if (!win->state_clearing) return; s = win->state_clearing; win->state_clearing = NULL; ecore_timer_del(s->clear_timer); s->clear_timer = NULL; if (s->delete_me) { if (s->view) s->view->destroy(s->view); s->clear_timer = NULL; E_FREE(s->inp); E_FREE(s); } else if ((v = s->view)) { v->clear(v); if (v->o_list) { evas_object_hide(v->o_list); edje_object_part_unswallow(win->o_main, v->o_list); } } /* replay mouse down to allow direct sliding back */ if (win->mouse_button) evas_event_feed_mouse_down(win->evas, win->mouse_button, 0, 0, NULL); } static void _evry_view_hide(Evry_Window *win, Evry_View *v, int slide) { _evry_state_clear(win); if (!v || v->state->delete_me) return; if (slide && v->o_list) { win->state_clearing = v->state; if (slide == SLIDE_RIGHT) { _evry_view_list_swallow_set(win->o_main, "list:e.swallow.list2", v->o_list); } else /* if (slide == SLIDE_LEFT) */ { _evry_view_list_swallow_set(win->o_main, "list:e.swallow.list", v->o_list); } edje_object_signal_emit(v->o_list, "e,action,hide,list", "e"); /* FIXME get signal from theme when anim finished */ v->state->clear_timer = ecore_timer_loop_add(1.5, _clear_timer, win); if (v->o_bar) { evas_object_hide(v->o_bar); edje_object_part_unswallow(win->o_main, v->o_bar); } return; } v->clear(v); if (v->o_list) { evas_object_hide(v->o_list); edje_object_part_unswallow(win->o_main, v->o_list); } if (v->o_bar) { evas_object_hide(v->o_bar); edje_object_part_unswallow(win->o_main, v->o_bar); } } static int _evry_view_create(Evry_State *s) { Evry_View *view; if (s->view) return 1; if (s->plugin && s->plugin->view) view = s->plugin->view; else view = eina_list_data_get(evry_conf->views); s->view = view->create(view, s, s->selector->win->o_main); if (s->view) { s->view->state = s; return 1; } return 0; } static int _evry_view_update(Evry_Window *win, Evry_State *s) { if (!win->visible) return 0; /* TODO check this again !!!!*/ if (s->view) { s->view->update(s->view); return 0; } if (_evry_view_create(s)) { s->view->update(s->view); return 1; } return 0; } static void _evry_view_clear(Evry_State *s) { if (!s || !s->view) return; s->view->clear(s->view); } static int _evry_view_key_press(Evry_State *s, Ecore_Event_Key *ev) { if (!s || !s->view || !s->view->cb_key_down) return 0; return s->view->cb_key_down(s->view, ev); } int evry_view_toggle(Evry_State *s, const char *trigger) { Evry_View *view, *v = NULL; Eina_List *l, *ll; Eina_Bool triggered = EINA_FALSE; Evry_Window *win = s->selector->win; if (trigger) { EINA_LIST_FOREACH (evry_conf->views, ll, view) { if (view->trigger && !strncmp(trigger, view->trigger, 1) && (!s->view || (view->id != s->view->id)) && (v = view->create(view, s, win->o_main))) { triggered = EINA_TRUE; goto found; } } } else { if (s->view) l = eina_list_data_find_list(evry_conf->views, s->view->id); else { view = evry_conf->views->data; v = view->create(view, s, win->o_main); goto found; } if (l && l->next) l = l->next; else l = evry_conf->views; EINA_LIST_FOREACH (l, ll, view) { if ((!view->trigger) && ((!s->view || (view->id != s->view->id)) && (v = view->create(view, s, win->o_main)))) goto found; } } found: if (!v) return 0; _evry_list_win_show(win); if (s->view) { _evry_view_hide(win, s->view, 0); s->view->destroy(s->view); } s->view = v; s->view->state = s; _evry_view_show(win, s->view, 0); view->update(s->view); return triggered; } static void _evry_matches_update(Evry_Selector *sel, int async) { Evry_State *s = sel->state; Evry_Plugin *p; Eina_List *l; Evry_Item *it; Evry_Window *win = sel->win; const char *input = NULL; size_t len_inp = 0; s->changed = 1; s->request++; #ifdef CHECK_TIME DBG("matches update %f", ecore_time_get() - _evry_time); #endif if (sel->update_timer) { ecore_timer_del(sel->update_timer); sel->update_timer = NULL; } if (s->sel_items) { eina_list_free(s->sel_items); s->sel_items = NULL; } if (s->inp[0]) { len_inp = strlen(s->inp); input = s->inp; } /* use current plugins */ if (s->trigger_active) { s->plugin_auto_selected = EINA_FALSE; EINA_LIST_FOREACH (s->cur_plugins, l, p) { p->request = s->request; p->fetch(p, s->input); } goto found; } EINA_LIST_FREE (s->cur_plugins, p) ; /* check if input matches plugin trigger */ if (input) { size_t len_trigger = 0; EINA_LIST_FOREACH (s->plugins, l, p) { size_t len; if (!p->config->trigger) continue; len = strlen(p->config->trigger); if (len_trigger && len != len_trigger) continue; if ((len_inp >= len) && (!strncmp(s->inp, p->config->trigger, len))) { len_trigger = len; s->cur_plugins = eina_list_append(s->cur_plugins, p); p->request = s->request; if (len_inp == len) p->fetch(p, NULL); else p->fetch(p, s->input + len); } } if (s->cur_plugins) { s->trigger_active = EINA_TRUE; /* replace trigger with indicator */ if (len_trigger > 1) { s->inp[0] = ':'; if (s->inp[len_trigger]) strcpy(s->inp + 1, s->inp + len_trigger); else s->inp[1] = 0; } s->input = s->inp + 1; _evry_update_text_label(s); goto found; } } /* query all other plugins for this state */ EINA_LIST_FOREACH (s->plugins, l, p) { p->request = s->request; if (p == s->aggregator) goto next; /* dont wait for async plugin. use their current items */ if (!async && p->async_fetch && p->items) { s->cur_plugins = eina_list_append(s->cur_plugins, p); goto next; } if (!((sel->states->next) || ((CUR_SEL == SUBJ_SEL) && (win->plugin_dedicated)))) { /* skip plugins in toplevel which trigger-only */ if ((sel == SUBJ_SEL) && (p->config->top_level) && (p->config->trigger_only)) goto next; /* skip non-toplevel plugins when input < min_query */ if ((!p->config->top_level) && ((size_t) p->config->min_query > len_inp)) goto next; } if (p->fetch(p, input)) { #ifdef CHECK_TIME DBG("fetch %s %f", p->name, ecore_time_get() - _evry_time); #endif s->cur_plugins = eina_list_append(s->cur_plugins, p); continue; } next: if (s->plugin == p) s->plugin = NULL; } found: _evry_aggregator_fetch(s); if (s->plugin_auto_selected) s->plugin = NULL; _evry_plugin_select(s, s->plugin); if (!s->plugin) return; EINA_LIST_FOREACH (s->plugin->items, l, it) if (it->marked) s->sel_items = eina_list_append(s->sel_items, it); } static void _evry_item_desel(Evry_State *s) { Evry_Item *it = s->cur_item; if (it) { it->selected = EINA_FALSE; evry_item_free(it); } s->cur_item = NULL; } static void _evry_item_sel(Evry_State *s, Evry_Item *it) { if (s->cur_item == it) return; _evry_item_desel(s); evry_item_ref(it); it->selected = EINA_TRUE; s->cur_item = it; } static void _evry_plugin_select(Evry_State *s, Evry_Plugin *p) { if (!s) return; if (p) { s->plugin_auto_selected = EINA_FALSE; } else { p = eina_list_data_get(s->cur_plugins); s->plugin_auto_selected = EINA_TRUE; } s->plugin = p; if ((s->view && s->plugin && s->plugin->view) && (s->view->name != s->plugin->view->name)) { s->view->destroy(s->view); s->view = NULL; if (_evry_view_create(s)) { _evry_view_show(s->selector->win, s->view, 0); s->view->update(s->view); } } } static void _evry_cb_free_plugin_selected(void *data EINA_UNUSED, void *event) { Evry_Event_Item_Selected *ev = event; evry_item_free(ev->item); E_FREE(ev); } void evry_plugin_select(Evry_Plugin *p) { Evry_Event_Item_Selected *ev; if (!p) return; if (!p->state) { ERR("no state!"); return; } _evry_plugin_select(p->state, p); _evry_selector_update(p->state->selector); ev = E_NEW(Evry_Event_Item_Selected, 1); ev->item = EVRY_ITEM(p); EVRY_ITEM_REF(p); ecore_event_add(_evry_events[EVRY_EVENT_PLUGIN_SELECTED], ev, _evry_cb_free_plugin_selected, NULL); } static void _evry_plugin_list_insert(Evry_State *s, Evry_Plugin *p) { Eina_List *l; Evry_Plugin *p2; EINA_LIST_FOREACH (s->cur_plugins, l, p2) { if (p == p2) return; if (p->config->priority < p2->config->priority) break; } if (l) s->cur_plugins = eina_list_prepend_relative_list(s->cur_plugins, p, l); else s->cur_plugins = eina_list_append(s->cur_plugins, p); } static void _evry_cb_show(Evry_Window *win, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) { if (win->grab) e_grabinput_get(elm_win_window_id_get(win->ewin), 0, elm_win_window_id_get(win->ewin)); } #ifndef HAVE_WAYLAND_ONLY static Eina_Bool _evry_cb_selection_notify(void *data, int type EINA_UNUSED, void *event) { Ecore_X_Event_Selection_Notify *ev; Evry_Window *win = data; Evry_State *s = (CUR_SEL)->state; if (!s || (data != win)) return ECORE_CALLBACK_PASS_ON; if (!win->request_selection) return ECORE_CALLBACK_PASS_ON; win->request_selection = EINA_FALSE; ev = event; if ((ev->selection == ECORE_X_SELECTION_CLIPBOARD) || (ev->selection == ECORE_X_SELECTION_PRIMARY)) { if (strcmp(ev->target, ECORE_X_SELECTION_TARGET_UTF8_STRING) == 0) { Ecore_X_Selection_Data_Text *text_data; text_data = ev->data; strncat(s->input, text_data->text, (INPUTLEN - strlen(s->input)) - 1); _evry_update(CUR_SEL, 1); } } return ECORE_CALLBACK_PASS_ON; } #endif void evry_item_app_free(Evry_Item_App *app) { efreet_desktop_free(app->desktop); eina_stringshare_del(app->file); free(app); } void evry_item_file_free(Evry_Item_File *file) { eina_stringshare_del(file->url); eina_stringshare_del(file->path); eina_stringshare_del(file->mime); free(file); }