1 #include "e.h"
2 #include "e_mod_main.h"
3
4 /* TODO
5 * - keybinding configuration
6 */
7
8 #define DRAG_OFF_WINDOW
9
10 #define INPUTLEN 256
11 #define MATCH_LAG 0.15
12 #define INITIAL_MATCH_LAG 0.3
13
14 #if defined (CHECK_TIME) || defined (CHECK_REFS)
15 #undef DBG
16 #define DBG(...) ERR(__VA_ARGS__)
17 #else
18 #undef DBG
19 #define DBG(...)
20 #endif
21
22 static Eina_Bool _evry_cb_desklock(Evry_Window *win, int type EINA_UNUSED, E_Event_Desklock *ev);
23 static void _evry_matches_update(Evry_Selector *sel, int async);
24 static void _evry_plugin_action(Evry_Selector *sel, int finished);
25 static void _evry_plugin_select(Evry_State *s, Evry_Plugin *p);
26 static void _evry_plugin_list_insert(Evry_State *s, Evry_Plugin *p);
27 static int _evry_backspace(Evry_Selector *sel);
28 static void _evry_update(Evry_Selector *sel, int fetch);
29 static void _evry_update_text_label(Evry_State *s);
30 static int _evry_clear(Evry_Selector *sel);
31 static Eina_Bool _evry_cb_update_timer(void *data);
32
33 static Evry_State *_evry_state_new(Evry_Selector *sel, Eina_List *plugins);
34 static void _evry_state_pop(Evry_Selector *sel, int immediate);
35 static void _evry_state_clear(Evry_Window *win);
36 static void _evry_hide_func(Evry_Window *win, int finished);
37
38 static Evry_Selector *_evry_selector_new(Evry_Window *win, int type);
39 static void _evry_selector_free(Evry_Selector *sel);
40 static void _evry_selector_activate(Evry_Selector *sel, int slide);
41 static void _evry_selector_update(Evry_Selector *sel);
42 static int _evry_selector_plugins_get(Evry_Selector *sel, Evry_Item *it, const char *plugin_name);
43 static void _evry_selector_update_actions(Evry_Selector *sel);
44 static void _evry_selector_item_update(Evry_Selector *sel);
45 static void _evry_selector_item_clear(Evry_Selector *sel);
46 static void _evry_selector_label_set(Evry_Selector *sel, const char *part, const char *label);
47 static void _evry_selector_signal_emit(Evry_Selector *sel, const char *msg);
48 static int _evry_selectors_shift(Evry_Window *win, int dir);
49 static int _evry_selectors_switch(Evry_Window *win, int dir);
50
51 static Evry_Window *_evry_window_new(E_Zone *zone, E_Zone_Edge edge);
52 static void _evry_cb_win_delete(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED);
53 static void _evry_window_free(Evry_Window *win);
54 static void _evry_list_win_show(Evry_Window *win);
55 static void _evry_list_win_hide(Evry_Window *win);
56 static void _evry_list_win_update(Evry_State *s);
57
58 static int _evry_view_create(Evry_State *s);
59 static void _evry_view_clear(Evry_State *s);
60 static int _evry_view_update(Evry_Window *win, Evry_State *s);
61 static int _evry_view_key_press(Evry_State *s, Ecore_Event_Key *ev);
62 static void _evry_view_show(Evry_Window *win, Evry_View *v, int slide);
63 static void _evry_view_hide(Evry_Window *win, Evry_View *v, int slide);
64
65 static void _evry_item_desel(Evry_State *s);
66 static void _evry_item_sel(Evry_State *s, Evry_Item *it);
67
68 static void _evry_cb_show(Evry_Window *win, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED);
69 static Eina_Bool _evry_cb_key_down(void *data, int type, void *event);
70 static Eina_Bool _evry_cb_selection_notify(void *data, int type, void *event);
71 static Eina_Bool _evry_cb_mouse(void *data, int type, void *event);
72
73 static Eina_Bool _evry_delay_hide_timer(void *data);
74 static Eina_Bool _evry_focus_out_timer(void *data);
75
76 static Eina_List *windows = NULL;
77
78 #ifdef CHECK_TIME
79 double _evry_time;
80 #endif
81
82 #ifdef CHECK_REFS
83 static int _item_cnt = 0;
84 Eina_List *_refd = NULL;
85 #endif
86
87 #define SUBJ_SEL win->selectors[0]
88 #define ACTN_SEL win->selectors[1]
89 #define OBJ_SEL win->selectors[2]
90 #define CUR_SEL win->selector
91
92 int
evry_init(void)93 evry_init(void)
94 {
95 return 1;
96 }
97
98 int
evry_shutdown(void)99 evry_shutdown(void)
100 {
101 while (windows)
102 evry_hide(windows->data, 0);
103
104 return 1;
105 }
106
107 static int
_evry_aggregator_fetch(Evry_State * s)108 _evry_aggregator_fetch(Evry_State *s)
109 {
110 Eina_List *l;
111
112 if (!s)
113 {
114 ERR("no state");
115 return 0;
116 }
117
118 if (s->aggregator->fetch(s->aggregator, s->input))
119 {
120 l = eina_list_data_find_list(s->cur_plugins, s->aggregator);
121
122 if (!l)
123 s->cur_plugins = eina_list_prepend(s->cur_plugins, s->aggregator);
124 else
125 s->cur_plugins = eina_list_promote_list(s->cur_plugins, l);
126
127 return 1;
128 }
129
130 s->cur_plugins = eina_list_remove(s->cur_plugins, s->aggregator);
131
132 return 1;
133 }
134
135 static Eina_Bool
_evry_cb_item_changed(EINA_UNUSED void * data,EINA_UNUSED int type,void * event)136 _evry_cb_item_changed(EINA_UNUSED void *data, EINA_UNUSED int type, void *event)
137 {
138 Evry_Event_Item_Changed *ev = event;
139 Evry_Selector *sel;
140 Evry_Item *it = ev->item;
141
142 if (!it || !it->plugin || !it->plugin->state)
143 return ECORE_CALLBACK_PASS_ON;
144
145 sel = it->plugin->state->selector;
146
147 if (sel->state && sel->state->cur_item == it)
148 {
149 _evry_selector_update(sel);
150 }
151
152 return ECORE_CALLBACK_PASS_ON;
153 }
154
155 static Eina_Bool
_evry_focus_out_timer(void * data)156 _evry_focus_out_timer(void *data)
157 {
158 Evry_Window *win = data;
159 E_Client *ec;
160
161 win->delay_hide_action = NULL;
162
163 ec = e_win_client_get(win->ewin);
164 if (ec && (!e_object_is_del(E_OBJECT(ec))))
165 evry_hide(win, 0);
166
167 return ECORE_CALLBACK_CANCEL;
168 }
169
170 static void
_evry_focus_out(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info EINA_UNUSED)171 _evry_focus_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
172 {
173 Evry_Window *win = data;
174
175 if (!win->grab) return;
176
177 if (win->delay_hide_action)
178 ecore_timer_del(win->delay_hide_action);
179
180 win->delay_hide_action = ecore_timer_loop_add(0.0, _evry_focus_out_timer, win);
181 }
182
183 static void
_evry_focus_in(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info EINA_UNUSED)184 _evry_focus_in(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
185 {
186 Evry_Window *win = data;
187
188 if (!win->grab) return;
189
190 E_FREE_FUNC(win->delay_hide_action, ecore_timer_del);
191 }
192
193 Evry_Window *
evry_show(E_Zone * zone,E_Zone_Edge edge,const char * params,Eina_Bool popup)194 evry_show(E_Zone *zone, E_Zone_Edge edge, const char *params, Eina_Bool popup)
195 {
196 Evry_Window *win;
197 Evry_Selector *sel;
198
199 #ifdef CHECK_TIME
200 _evry_time = ecore_time_get();
201 DBG("_____evry_show______");
202 #endif
203
204 E_OBJECT_CHECK_RETURN(zone, 0);
205 E_OBJECT_TYPE_CHECK_RETURN(zone, E_ZONE_TYPE, 0);
206
207 if (popup)
208 {
209 // only one popup please
210 Eina_List *l;
211 EINA_LIST_FOREACH(windows, l, win)
212 if (win->grab)
213 return NULL;
214 }
215
216 if (!(win = _evry_window_new(zone, edge)))
217 return NULL;
218
219 if (popup)
220 {
221 E_Client *ec;
222
223 ecore_evas_name_class_set(e_win_ee_get(win->ewin), "E", "everything");
224
225 evas_object_show(win->ewin);
226 ec = e_win_client_get(win->ewin);
227 if (ec)
228 {
229 #ifndef HAVE_WAYLAND_ONLY
230 if (e_comp->comp_type == E_PIXMAP_TYPE_X)
231 ecore_x_netwm_window_type_set(elm_win_window_id_get(win->ewin),
232 ECORE_X_WINDOW_TYPE_UTILITY);
233 #endif
234 ec->netwm.state.skip_taskbar = 1;
235 EC_CHANGED(ec);
236 evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_FOCUS_OUT, _evry_focus_out, win);
237 evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_FOCUS_IN, _evry_focus_in, win);
238 }
239
240 win->grab = 1;
241 }
242
243 evry_history_load();
244
245 if (params)
246 win->plugin_dedicated = EINA_TRUE;
247
248 win->sel_list = E_NEW(Evry_Selector *, 4);
249 win->sel_list[3] = NULL;
250 win->selectors = win->sel_list;
251 _evry_selector_new(win, EVRY_PLUGIN_SUBJECT);
252 _evry_selector_new(win, EVRY_PLUGIN_ACTION);
253 _evry_selector_new(win, EVRY_PLUGIN_OBJECT);
254
255 E_LIST_HANDLER_APPEND(win->handlers, ECORE_EVENT_KEY_DOWN, _evry_cb_key_down, win);
256 #ifndef HAVE_WAYLAND_ONLY
257 if (e_comp->comp_type == E_PIXMAP_TYPE_X)
258 E_LIST_HANDLER_APPEND(win->handlers, ECORE_X_EVENT_SELECTION_NOTIFY, _evry_cb_selection_notify, win);
259 #endif
260 evas_object_event_callback_add(e_win_client_get(win->ewin)->frame, EVAS_CALLBACK_SHOW, (Evas_Object_Event_Cb)_evry_cb_show, win);
261
262 E_LIST_HANDLER_APPEND(win->handlers, _evry_events[EVRY_EVENT_ITEM_CHANGED], _evry_cb_item_changed, win);
263
264 E_LIST_HANDLER_APPEND(win->handlers, ECORE_EVENT_MOUSE_BUTTON_DOWN, _evry_cb_mouse, win);
265
266 E_LIST_HANDLER_APPEND(win->handlers, ECORE_EVENT_MOUSE_BUTTON_UP, _evry_cb_mouse, win);
267 E_LIST_HANDLER_APPEND(win->handlers, E_EVENT_DESKLOCK, _evry_cb_desklock, win);
268 #if 0
269 E_LIST_HANDLER_APPEND(win->handlers, ECORE_EVENT_MOUSE_MOVE, _evry_cb_mouse, win);
270
271 E_LIST_HANDLER_APPEND(win->handlers, ECORE_EVENT_MOUSE_WHEEL, _evry_cb_mouse, win);
272
273 E_LIST_HANDLER_APPEND(win->handlers, ECORE_X_EVENT_MOUSE_IN, _evry_cb_mouse_in, win);
274
275 E_LIST_HANDLER_APPEND(win->handlers, ECORE_X_EVENT_MOUSE_OUT, _evry_cb_mouse_out, win);
276 #endif
277 _evry_selector_plugins_get(SUBJ_SEL, NULL, params);
278 _evry_selector_update(SUBJ_SEL);
279
280 windows = eina_list_append(windows, win);
281
282 _evry_selector_activate(SUBJ_SEL, 0);
283
284 if ((!evry_conf->hide_list) || (edge))
285 {
286 sel = CUR_SEL;
287
288 if (sel && sel->state && evry_conf->views)
289 {
290 /* if (evry_conf->first_run)
291 * {
292 * evry_view_toggle(sel->state, "?");
293 * evry_conf->first_run = EINA_FALSE;
294 * } */
295
296 edje_object_signal_emit(win->o_main, "list:e,state,list_show", "e");
297 edje_object_signal_emit(win->o_main, "list:e,state,entry_show", "e");
298 win->visible = EINA_TRUE;
299 }
300 }
301
302 win->func.hide = &_evry_hide_func;
303
304 win->delay_hide_action = ecore_timer_loop_add(0.2, _evry_delay_hide_timer, win);
305
306 return win;
307 }
308
309 static Eina_Bool
_evry_delay_hide_timer(void * data)310 _evry_delay_hide_timer(void *data)
311 {
312 Evry_Window *win = data;
313 win->delay_hide_action = NULL;
314
315 return ECORE_CALLBACK_CANCEL;
316 }
317
318 static void
_evry_hide_func(Evry_Window * win,int finished)319 _evry_hide_func(Evry_Window *win, int finished)
320 {
321 if ((finished) && (win->grab))
322 evry_hide(win, 0);
323 }
324
325 void
evry_hide(Evry_Window * win,int clear)326 evry_hide(Evry_Window *win, int clear)
327 {
328 Ecore_Event_Handler *ev;
329 int i;
330
331 if (!win) return;
332
333 evas_object_event_callback_del(win->ewin, EVAS_CALLBACK_DEL, _evry_cb_win_delete);
334 evas_object_event_callback_del(e_win_client_get(win->ewin)->frame,
335 EVAS_CALLBACK_FOCUS_OUT,
336 _evry_focus_out);
337 evas_object_hide(win->ewin);
338 _evry_state_clear(win);
339
340 if ((clear && CUR_SEL) &&
341 /* pop states */
342 ((eina_list_count((SUBJ_SEL)->states) > 1) ||
343 /* move to subject selector */
344 (CUR_SEL != SUBJ_SEL) ||
345 /* clear input */
346 (((CUR_SEL)->state) && ((CUR_SEL)->state->input[0]))))
347 {
348 int slide = 0;
349 Evry_Selector *sel;
350 Evry_State *s;
351
352 if (CUR_SEL != SUBJ_SEL)
353 {
354 if (CUR_SEL == ACTN_SEL)
355 _evry_selectors_switch(win, -1);
356 else if (CUR_SEL == OBJ_SEL)
357 _evry_selectors_switch(win, 1);
358 }
359
360 /* just to be sure */
361 CUR_SEL = SUBJ_SEL;
362
363 while ((CUR_SEL)->states->next)
364 {
365 slide = SLIDE_RIGHT;
366 _evry_state_pop(CUR_SEL, 1);
367 }
368
369 sel = CUR_SEL;
370 s = sel->state;
371 _evry_clear(sel);
372 _evry_clear(sel);
373
374 _evry_aggregator_fetch(s);
375 _evry_selector_update(sel);
376 _evry_update_text_label(s);
377 if (s->view)
378 {
379 _evry_view_show(win, s->view, slide);
380 s->view->update(s->view);
381 }
382 return;
383 }
384
385 if (_evry_selectors_shift(win, -1))
386 return;
387
388 win->visible = EINA_FALSE;
389
390 if (win->sel_list)
391 {
392 for (i = 0; win->sel_list[i]; i++)
393 _evry_selector_free(win->sel_list[i]);
394 }
395
396 E_FREE(win->sel_list);
397
398 EINA_LIST_FREE (win->handlers, ev)
399 ecore_event_handler_del(ev);
400
401 if (win->delay_hide_action)
402 ecore_timer_del(win->delay_hide_action);
403
404 if (win->grab)
405 e_grabinput_release(elm_win_window_id_get(win->ewin),
406 elm_win_window_id_get(win->ewin));
407
408 windows = eina_list_remove(windows, win);
409
410 _evry_window_free(win);
411
412 evry_history_unload();
413
414 #ifdef CHECK_REFS
415 Evry_Item *_it;
416 int _cnt = eina_list_count(_refd);
417 Eina_List *_l;
418 printf("__________________________");
419 EINA_LIST_FOREACH (_refd, _l, _it)
420 printf("%d %s\n", _it->ref, _it->label);
421 printf("sum: %d", _cnt);
422 #endif
423 }
424
425 static int
_evry_selectors_shift(Evry_Window * win,int dir)426 _evry_selectors_shift(Evry_Window *win, int dir)
427 {
428 if ((dir > 0) && (win->level == 0))
429 {
430 void *new_sel;
431 Evry_Selector *sel;
432 Evry_State *s;
433 int i;
434
435 for (i = 1; i < 3; i++)
436 _evry_selector_item_clear(win->selectors[i]);
437
438 if (!(new_sel = realloc(win->sel_list, sizeof(Evry_Selector *) * 6)))
439 return 0;
440
441 win->sel_list = new_sel;
442
443 edje_object_signal_emit(win->o_main,
444 "e,state,object_selector_hide", "e");
445
446 win->sel_list[5] = NULL;
447 win->selectors = win->sel_list + 2;
448 _evry_selector_new(win, EVRY_PLUGIN_ACTION);
449 _evry_selector_new(win, EVRY_PLUGIN_OBJECT);
450
451 CUR_SEL = SUBJ_SEL;
452 sel = CUR_SEL;
453
454 _evry_selector_signal_emit(sel, "e,state,selected");
455
456 _evry_selector_item_update(SUBJ_SEL);
457 _evry_selector_item_update(ACTN_SEL);
458 _evry_selector_item_update(OBJ_SEL);
459
460 /* was checked before. anyway */
461 if ((s = sel->state) && (s->cur_item))
462 _evry_selector_update_actions(sel);
463
464 win->level++;
465
466 return 1;
467 }
468 else if ((dir < 0) && (win->level > 0))
469 {
470 _evry_selector_item_clear(SUBJ_SEL);
471 _evry_selector_free(ACTN_SEL);
472 _evry_selector_free(OBJ_SEL);
473
474 win->selectors = win->sel_list;
475 win->sel_list[3] = NULL;
476 CUR_SEL = NULL;
477
478 edje_object_signal_emit(win->o_main,
479 "e,state,object_selector_show", "e");
480 _evry_selector_item_update(SUBJ_SEL);
481 _evry_selector_item_update(ACTN_SEL);
482 _evry_selector_item_update(OBJ_SEL);
483 _evry_selector_activate(OBJ_SEL, 0);
484
485 win->level = 0;
486
487 return 1;
488 }
489
490 return 0;
491 }
492
493 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))494 evry_item_new(Evry_Item *it, Evry_Plugin *p, const char *label,
495 Evas_Object *(*icon_get)(Evry_Item * it, Evas * e),
496 void (*cb_free)(Evry_Item *item))
497 {
498 if (!it)
499 {
500 it = E_NEW(Evry_Item, 1);
501 if (!it) return NULL;
502 }
503
504 if (p && EVRY_ITEM(p)->subtype)
505 it->type = EVRY_ITEM(p)->subtype;
506
507 it->plugin = p;
508
509 if (label) it->label = eina_stringshare_add(label);
510 it->free = cb_free;
511 it->icon_get = icon_get;
512
513 it->ref = 1;
514
515 #ifdef CHECK_REFS
516 _item_cnt++;
517 _refd = eina_list_append(_refd, it);
518 #endif
519 #ifdef PRINT_REFS
520 printf("%d, %d\t new : %s\n", it->ref, _item_cnt, it->label);
521 #endif
522 return it;
523 }
524
525 void
evry_item_free(Evry_Item * it)526 evry_item_free(Evry_Item *it)
527 {
528 if (!it) return;
529
530 it->ref--;
531
532 #ifdef PRINT_REFS
533 printf("%d, %d\t unref: %s\n", it->ref, _item_cnt, it->label);
534 #endif
535
536 if (it->ref > 0) return;
537
538 #ifdef CHECK_REFS
539 _item_cnt--;
540 _refd = eina_list_remove(_refd, it);
541 #endif
542
543 IF_RELEASE(it->label);
544 IF_RELEASE(it->id);
545 IF_RELEASE(it->context);
546 IF_RELEASE(it->detail);
547 IF_RELEASE(it->icon);
548
549 if (it->free)
550 it->free(it);
551 else
552 E_FREE(it);
553 }
554
555 void
evry_item_ref(Evry_Item * it)556 evry_item_ref(Evry_Item *it)
557 {
558 it->ref++;
559 #ifdef PRINT_REFS
560 printf("%d, %d\t ref : %s\n", it->ref, _item_cnt, it->label);
561 #endif
562 }
563
564 static int
_evry_selector_update_actions_do(Evry_Selector * sel)565 _evry_selector_update_actions_do(Evry_Selector *sel)
566 {
567 Evry_State *s;
568 Evry_Window *win = sel->win;
569
570 if (sel->action_timer)
571 {
572 ecore_timer_del(sel->action_timer);
573 sel->action_timer = NULL;
574 }
575
576 if ((s = (SUBJ_SEL)->state))
577 _evry_selector_plugins_get(sel, s->cur_item, NULL);
578
579 _evry_selector_update(sel);
580
581 return 1;
582 }
583
584 static Eina_Bool
_evry_timer_cb_actions_get(void * data)585 _evry_timer_cb_actions_get(void *data)
586 {
587 Evry_Selector *sel = data;
588 Evry_Window *win = sel->win;
589 Evry_State *s;
590
591 _evry_selector_update_actions_do(sel);
592
593 if ((CUR_SEL == sel) && (s = sel->state))
594 {
595 if (_evry_view_update(win, s))
596 _evry_view_show(win, s->view, 0);
597 }
598
599 return ECORE_CALLBACK_CANCEL;
600 }
601
602 static void
_evry_selector_update_actions(Evry_Selector * sel)603 _evry_selector_update_actions(Evry_Selector *sel)
604 {
605 if (sel->action_timer)
606 ecore_timer_del(sel->action_timer);
607
608 _evry_selector_item_clear(sel);
609 sel->action_timer = ecore_timer_loop_add(0.2, _evry_timer_cb_actions_get, sel);
610 }
611
612 void
evry_item_select(const Evry_State * state,Evry_Item * it)613 evry_item_select(const Evry_State *state, Evry_Item *it)
614 {
615 Evry_State *s = (Evry_State *)state;
616 Evry_Selector *sel;
617 Evry_Window *win;
618
619 if ((!s) || (s->delete_me))
620 return;
621
622 sel = s->selector;
623 win = sel->win;
624
625 s->plugin_auto_selected = EINA_FALSE;
626 s->item_auto_selected = EINA_FALSE;
627
628 _evry_item_sel(s, it);
629
630 if (s == sel->state)
631 {
632 _evry_selector_update(sel);
633
634 if (CUR_SEL == SUBJ_SEL)
635 _evry_selector_update_actions(ACTN_SEL);
636
637 if (CUR_SEL == ACTN_SEL)
638 {
639 while (OBJ_SEL->state)
640 _evry_state_pop(OBJ_SEL, 1);
641 }
642 }
643 }
644
645 void
evry_item_mark(const Evry_State * state,Evry_Item * it,Eina_Bool mark)646 evry_item_mark(const Evry_State *state, Evry_Item *it, Eina_Bool mark)
647 {
648 Evry_State *s = (Evry_State *)state;
649
650 if ((!s) || (s->delete_me))
651 return;
652
653 if (mark && !it->marked)
654 {
655 it->marked = EINA_TRUE;
656 s->sel_items = eina_list_append(s->sel_items, it);
657 }
658 else if (it->marked)
659 {
660 it->marked = EINA_FALSE;
661 s->sel_items = eina_list_remove(s->sel_items, it);
662 }
663 }
664
665 void
evry_plugin_update(Evry_Plugin * p,int action)666 evry_plugin_update(Evry_Plugin *p, int action)
667 {
668 Evry_State *s;
669 Evry_Selector *sel;
670 Evry_Window *win;
671
672 if (!(s = p->state) || (s->delete_me))
673 return;
674
675 if (!(sel = s->selector))
676 return;
677
678 if (!(win = sel->win))
679 return;
680
681 if (sel->state->request != p->request)
682 return;
683
684 DBG("update %d %d %s", s->request, p->request, p->name);
685
686 if (action == EVRY_UPDATE_ADD)
687 {
688 /* clear marked items */
689 if (s->sel_items)
690 {
691 eina_list_free(s->sel_items);
692 s->sel_items = NULL;
693 }
694
695 if ((!p->items) && (!s->trigger_active))
696 {
697 /* remove plugin */
698 if (!(eina_list_data_find(s->cur_plugins, p)))
699 return;
700
701 s->cur_plugins = eina_list_remove(s->cur_plugins, p);
702
703 if (p == s->plugin)
704 _evry_plugin_select(s, NULL);
705 }
706 else
707 {
708 /* add plugin to current plugins*/
709 _evry_plugin_list_insert(s, p);
710 }
711
712 if (sel->state == s)
713 {
714 _evry_aggregator_fetch(s);
715
716 /* select first plugin */
717 if ((!s->plugin) || (s->plugin_auto_selected) ||
718 !(eina_list_data_find(s->cur_plugins, s->plugin)))
719 {
720 _evry_plugin_select(s, NULL);
721 }
722
723 if ((s->plugin && (sel->state == s)) &&
724 /* plugin is current */
725 ((s->plugin == p) ||
726 /* plugin items are shown in aggregator */
727 ((s->plugin == s->aggregator) && p->config->aggregate)))
728 {
729 _evry_selector_update(sel);
730
731 if (_evry_view_update(win, s))
732 /* XXX when there is a case where view disappears
733 check this one! is swallow always visible ? */
734 _evry_view_show(win, s->view, 0);
735 }
736
737 /* switch back to subject selector when no current items */
738 if ((sel == SUBJ_SEL) &&
739 (!(s->plugin) || !(s->plugin->items)) &&
740 (CUR_SEL == ACTN_SEL))
741 {
742 _evry_selectors_switch(win, -1);
743 _evry_clear(SUBJ_SEL);
744 }
745 }
746 }
747 else if (action == EVRY_UPDATE_REFRESH)
748 {
749 _evry_view_clear(s);
750 _evry_view_update(win, s);
751 }
752 }
753
754 static void
_evry_list_win_show(Evry_Window * win)755 _evry_list_win_show(Evry_Window *win)
756 {
757 if (win->visible) return;
758
759 win->visible = EINA_TRUE;
760 _evry_list_win_update((CUR_SEL)->state);
761
762 edje_object_signal_emit(win->o_main, "list:e,state,list_show", "e");
763 edje_object_signal_emit(win->o_main, "list:e,state,entry_show", "e");
764 }
765
766 static void
_evry_list_win_hide(Evry_Window * win)767 _evry_list_win_hide(Evry_Window *win)
768 {
769 Evry_Selector *sel = CUR_SEL;
770
771 if (!win->visible)
772 return;
773
774 if (!evry_conf->hide_list)
775 return;
776
777 if (sel->state)
778 _evry_view_clear(sel->state);
779
780 win->visible = EINA_FALSE;
781 edje_object_signal_emit(win->o_main, "list:e,state,list_hide", "e");
782
783 if (evry_conf->hide_input && (!(sel->state) || (sel->state->input[0])))
784 edje_object_signal_emit(win->o_main, "list:e,state,entry_hide", "e");
785 }
786
787 static void
_evry_cb_win_delete(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info EINA_UNUSED)788 _evry_cb_win_delete(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
789 {
790 evry_hide(data, 0);
791 }
792
793 static Evry_Window *
_evry_window_new(E_Zone * zone,E_Zone_Edge edge)794 _evry_window_new(E_Zone *zone, E_Zone_Edge edge)
795 {
796 int x, y, mw, mh, h, w;
797 Evry_Window *win;
798 Evas_Object *o;
799 const char *tmp;
800 int offset_s = 0;
801
802 win = E_NEW(Evry_Window, 1);
803 win->ewin = elm_win_add(NULL, NULL, ELM_WIN_UTILITY);
804 elm_win_borderless_set(win->ewin, 1);
805 e_win_no_remember_set(win->ewin, 1);
806 e_win_placed_set(win->ewin, 1);
807 elm_win_override_set(win->ewin, 1);
808 win->evas = evas_object_evas_get(win->ewin);
809 win->zone = zone;
810 evas_object_data_set(win->ewin, "evry_win", win);
811
812 o = edje_object_add(win->evas);
813 win->o_main = o;
814 elm_win_resize_object_add(win->ewin, o);
815 E_EXPAND(o);
816 E_FILL(o);
817 e_theme_edje_object_set(o, "base/theme/modules/everything",
818 "e/modules/everything/main");
819
820 edje_object_signal_emit(o, "e,state,composited", "e");
821 edje_object_signal_emit(o, "list:e,state,composited", "e");
822 edje_object_message_signal_process(o);
823 edje_object_calc_force(o);
824
825 tmp = edje_object_data_get(o, "shadow_offset");
826 offset_s = tmp ? atoi(tmp) : 0;
827 edje_object_size_min_calc(o, &mw, &mh);
828
829 if (edge == E_ZONE_EDGE_NONE)
830 {
831 w = evry_conf->width;
832 h = evry_conf->height;
833 }
834 else
835 {
836 w = evry_conf->edge_width;
837 h = evry_conf->edge_height;
838 }
839 evas_object_size_hint_min_set(win->ewin, mw, mh);
840
841 evry_conf->min_w = mw;
842 if (w > mw) mw = w;
843
844 evry_conf->min_h = mh;
845 if (h > mh) mh = h;
846
847 if (edge == E_ZONE_EDGE_NONE)
848 {
849 mw += offset_s * 2;
850 mh += offset_s * 2;
851
852 x = (zone->x + (zone->w * evry_conf->rel_x)) - (mw / 2);
853 y = (zone->y + (zone->h * evry_conf->rel_y)) - (mh / 2);
854 }
855 else
856 {
857 int to_side = 0;
858
859 switch (edge)
860 {
861 case E_ZONE_EDGE_TOP_LEFT:
862 x = to_side - offset_s;
863 y = to_side - offset_s;
864 break;
865
866 case E_ZONE_EDGE_TOP_RIGHT:
867 x = zone->w - (mw + offset_s + to_side);
868 y = to_side - offset_s;
869 break;
870
871 case E_ZONE_EDGE_BOTTOM_RIGHT:
872 x = zone->w - (mw + offset_s + to_side);
873 y = zone->h - (mh + offset_s + to_side);
874 break;
875
876 case E_ZONE_EDGE_BOTTOM_LEFT:
877 x = to_side - offset_s;
878 y = zone->h - (mh + offset_s + to_side);
879 break;
880
881 default:
882 mw += offset_s * 2;
883 mh += offset_s * 2;
884 x = (zone->w * evry_conf->rel_x) - (mw / 2);
885 y = (zone->h * evry_conf->rel_y) - (mh / 2);
886 break;
887 }
888
889 x += zone->x;
890 y += zone->y;
891
892 mw += offset_s * 2;
893 mh += offset_s * 2;
894 }
895
896 evas_object_geometry_set(win->ewin, x, y, mw, mh);
897
898 evas_object_show(o);
899
900 evas_event_feed_mouse_in(win->evas, 0, NULL);
901 evas_event_feed_mouse_move(win->evas, -1000000, -1000000, 0, NULL);
902
903 evas_object_event_callback_add(win->ewin, EVAS_CALLBACK_DEL, _evry_cb_win_delete, win);
904
905 return win;
906 }
907
908 #if 0
909 static void
910 _evry_cb_drag_finished(E_Drag *drag, int dropped)
911 {
912 E_FREE(drag->data);
913 }
914
915 #endif
916
917 static Eina_Bool
_evry_cb_desklock(Evry_Window * win,int type EINA_UNUSED,E_Event_Desklock * ev)918 _evry_cb_desklock(Evry_Window *win, int type EINA_UNUSED, E_Event_Desklock *ev)
919 {
920 if (ev->on) evry_hide(win, 0);
921 return ECORE_CALLBACK_RENEW;
922 }
923
924 static Eina_Bool
_evry_cb_mouse(void * data,int type,void * event)925 _evry_cb_mouse(void *data, int type, void *event)
926 {
927 Ecore_Event_Mouse_Button *ev;
928 Evry_Window *win = data;
929 Evas_Object *ewin;
930 int x, y, w, h;
931
932 ev = event;
933
934 if (!win->grab)
935 return ECORE_CALLBACK_PASS_ON;
936
937 if ((ev->event_window != ecore_evas_window_get(e_comp->ee)) &&
938 (ev->event_window != elm_win_window_id_get(win->ewin)))
939 return ECORE_CALLBACK_PASS_ON;
940
941 ewin = win->ewin;
942
943 #if 0
944 if (type == ECORE_EVENT_MOUSE_MOVE)
945 {
946 Ecore_Event_Mouse_Move *ev = event;
947 Evry_State *s;
948
949 if ((win->mouse_button == 3) &&
950 (s = (CUR_SEL)->state) && (s->cur_item) &&
951 (CHECK_TYPE(s->cur_item, EVRY_TYPE_FILE)) &&
952 (!E_INSIDE(ev->x, ev->y,
953 win->zone->x,
954 win->zone->y,
955 ewin->w, ewin->h)))
956 {
957 const char *drag_types[] = { "text/uri-list" };
958 E_Drag *d;
959 Evas_Object *o;
960 const char *uri;
961 int s_len, sel_length = 0;
962 char *tmp, *sel = NULL;
963
964 GET_FILE(file, s->cur_item);
965
966 if (!(uri = evry_file_url_get(file)))
967 return ECORE_CALLBACK_PASS_ON;
968
969 s_len = strlen(uri);
970 if (!(tmp = realloc(sel, sel_length + s_len + 2 + 1)))
971 return ECORE_CALLBACK_PASS_ON;
972 sel = tmp;
973 memcpy(sel + sel_length, uri, s_len);
974 memcpy(sel + sel_length + s_len, "\r\n", 2);
975 sel_length += s_len + 2;
976
977 d = e_drag_new(e_comp),
978 ev->x, ev->y,
979 drag_types, 1, sel, sel_length, NULL,
980 _evry_cb_drag_finished);
981 e_drag_resize(d, 128, 128);
982 o = evry_util_icon_get(s->cur_item, e_drag_evas_get(d));
983 e_drag_object_set(d, o);
984 e_drag_xdnd_start(d, ev->x, ev->y);
985
986 evry_hide(win, 0);
987 return ECORE_CALLBACK_PASS_ON;
988 }
989 }
990 else if (type == ECORE_EVENT_MOUSE_WHEEL)
991 {
992 Ecore_Event_Mouse_Wheel *ev = event;
993 }
994 else
995 #endif
996 evas_object_geometry_get(ewin, &x, &y, &w, &h);
997 if (type == ECORE_EVENT_MOUSE_BUTTON_DOWN)
998 {
999 win->mouse_out = 0;
1000
1001 if (e_comp->comp_type == E_PIXMAP_TYPE_WL)
1002 {
1003 if (ev->event_window == ecore_evas_window_get(e_comp->ee))
1004 {
1005 if (!E_INSIDE(e_comp_canvas_x_root_adjust(ev->root.x),
1006 e_comp_canvas_y_root_adjust(ev->root.y), x, y, w, h))
1007 win->mouse_out = 1;
1008 }
1009 }
1010 else if (!E_INSIDE(e_comp_canvas_x_root_adjust(ev->root.x),
1011 e_comp_canvas_y_root_adjust(ev->root.y), x, y, w, h))
1012 win->mouse_out = 1;
1013 if (win->mouse_out)
1014 return ECORE_CALLBACK_PASS_ON;
1015
1016 win->mouse_button = ev->buttons;
1017 }
1018 else if (type == ECORE_EVENT_MOUSE_BUTTON_UP)
1019 {
1020 win->mouse_button = 0;
1021
1022 if (win->mouse_out)
1023 {
1024 evry_hide(win, 0);
1025 return ECORE_CALLBACK_PASS_ON;
1026 }
1027 }
1028
1029 return ECORE_CALLBACK_PASS_ON;
1030 }
1031
1032 static void
_evry_window_free(Evry_Window * win)1033 _evry_window_free(Evry_Window *win)
1034 {
1035 evas_event_freeze(win->evas);
1036 evas_object_event_callback_del(e_win_client_get(win->ewin)->frame,
1037 EVAS_CALLBACK_SHOW, (Evas_Object_Event_Cb)_evry_cb_show);
1038 evas_object_del(win->ewin);
1039 free(win);
1040 }
1041
1042 static void
_evry_selector_cb_down(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info)1043 _evry_selector_cb_down(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
1044 {
1045 Evas_Event_Mouse_Down *ev = event_info;
1046 Evry_Selector *sel = data;
1047
1048 if (ev->button == 1)
1049 {
1050 if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK)
1051 evry_plugin_action(sel->win, 1);
1052 }
1053 }
1054
1055 static void
_evry_selector_cb_wheel(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info)1056 _evry_selector_cb_wheel(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
1057 {
1058 Evas_Event_Mouse_Wheel *ev = event_info;
1059 Evry_Selector *sel = data;
1060 Evry_Window *win = sel->win;
1061
1062 if (ev->z > 0)
1063 {
1064 /* FIXME dont loose selector 2 state until state 0 changed: */
1065 if (CUR_SEL != OBJ_SEL)
1066 _evry_selectors_switch(sel->win, 1);
1067 }
1068 else if (ev->z < 0)
1069 {
1070 _evry_selectors_switch(sel->win, -1);
1071 }
1072 }
1073
1074 static void
_evry_selector_cb_up(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info)1075 _evry_selector_cb_up(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
1076 {
1077 Evas_Event_Mouse_Up *ev = event_info;
1078 Evry_Selector *sel = data;
1079 Evry_Window *win = sel->win;
1080
1081 if (sel == CUR_SEL)
1082 return;
1083
1084 if (ev->button == 3)
1085 {
1086 evry_plugin_action(win, 0);
1087 }
1088 else if (ev->button == 1)
1089 {
1090 if (sel == SUBJ_SEL)
1091 {
1092 if (CUR_SEL == ACTN_SEL)
1093 _evry_selectors_switch(win, -1);
1094 else
1095 _evry_selectors_switch(win, 1);
1096 }
1097 else if (sel == ACTN_SEL)
1098 {
1099 if (CUR_SEL == SUBJ_SEL)
1100 _evry_selectors_switch(win, 1);
1101 else
1102 _evry_selectors_switch(win, -1);
1103 }
1104 else if (sel == OBJ_SEL)
1105 {
1106 if (CUR_SEL == ACTN_SEL)
1107 _evry_selectors_switch(win, 1);
1108 }
1109 }
1110 }
1111
1112 static Evry_Selector *
_evry_selector_new(Evry_Window * win,int type)1113 _evry_selector_new(Evry_Window *win, int type)
1114 {
1115 Plugin_Config *pc;
1116 Eina_List *l, *pcs = NULL;
1117 Evry_Selector *sel = E_NEW(Evry_Selector, 1);
1118 const Evas_Object *o = NULL;
1119
1120 sel->aggregator = evry_aggregator_new(type);
1121
1122 if (type == EVRY_PLUGIN_SUBJECT)
1123 {
1124 pcs = evry_conf->conf_subjects;
1125 sel->edje_part = "subject_selector";
1126 }
1127 else if (type == EVRY_PLUGIN_ACTION)
1128 {
1129 pcs = evry_conf->conf_actions;
1130 sel->edje_part = "action_selector";
1131 }
1132 else if (type == EVRY_PLUGIN_OBJECT)
1133 {
1134 pcs = evry_conf->conf_objects;
1135 sel->edje_part = "object_selector";
1136 }
1137
1138 if ((o = edje_object_part_object_get(win->o_main, sel->edje_part)))
1139 {
1140 sel->event_object = o;
1141 evas_object_event_callback_add((Evas_Object*) o, EVAS_CALLBACK_MOUSE_DOWN,
1142 _evry_selector_cb_down, sel);
1143 evas_object_event_callback_add((Evas_Object*) o, EVAS_CALLBACK_MOUSE_UP,
1144 _evry_selector_cb_up, sel);
1145 evas_object_event_callback_add((Evas_Object*) o, EVAS_CALLBACK_MOUSE_WHEEL,
1146 _evry_selector_cb_wheel, sel);
1147 }
1148
1149 EINA_LIST_FOREACH (pcs, l, pc)
1150 {
1151 if (!pc->plugin) continue;
1152 if (pc->plugin == sel->aggregator) continue;
1153 sel->plugins = eina_list_append(sel->plugins, pc->plugin);
1154 }
1155
1156 win->selectors[type] = sel;
1157 sel->win = win;
1158
1159 return sel;
1160 }
1161
1162 static void
_evry_selector_free(Evry_Selector * sel)1163 _evry_selector_free(Evry_Selector *sel)
1164 {
1165 Evry_Window *win = sel->win;
1166
1167 if (sel->event_object)
1168 {
1169 evas_object_event_callback_del_full((Evas_Object*)sel->event_object, EVAS_CALLBACK_MOUSE_DOWN,
1170 _evry_selector_cb_down, sel);
1171 evas_object_event_callback_del_full((Evas_Object*)sel->event_object, EVAS_CALLBACK_MOUSE_UP,
1172 _evry_selector_cb_up, sel);
1173 evas_object_event_callback_del_full((Evas_Object*)sel->event_object, EVAS_CALLBACK_MOUSE_WHEEL,
1174 _evry_selector_cb_wheel, sel);
1175 }
1176
1177 _evry_selector_item_clear(sel);
1178
1179 if (win->visible && (sel == CUR_SEL))
1180 _evry_view_clear(sel->state);
1181
1182 while (sel->states)
1183 _evry_state_pop(sel, 1);
1184
1185 EVRY_PLUGIN_FREE(sel->aggregator);
1186
1187 if (sel->plugins) eina_list_free(sel->plugins);
1188
1189 if (sel->update_timer)
1190 ecore_timer_del(sel->update_timer);
1191
1192 if (sel->action_timer)
1193 ecore_timer_del(sel->action_timer);
1194
1195 E_FREE(sel);
1196 }
1197
1198 static void
_evry_selector_signal_emit(Evry_Selector * sel,const char * msg)1199 _evry_selector_signal_emit(Evry_Selector *sel, const char *msg)
1200 {
1201 Evry_Window *win = sel->win;
1202 char buf[128];
1203 snprintf(buf, sizeof(buf), "%s:%s", sel->edje_part, msg);
1204 edje_object_signal_emit(win->o_main, buf, "e");
1205 }
1206
1207 static void
_evry_selector_label_set(Evry_Selector * sel,const char * part,const char * label)1208 _evry_selector_label_set(Evry_Selector *sel, const char *part, const char *label)
1209 {
1210 Evry_Window *win = sel->win;
1211 char buf[128];
1212 snprintf(buf, sizeof(buf), "%s:%s", sel->edje_part, part);
1213 edje_object_part_text_set(win->o_main, buf, label);
1214 }
1215
1216 static void
_evry_selector_activate(Evry_Selector * sel,int slide)1217 _evry_selector_activate(Evry_Selector *sel, int slide)
1218 {
1219 Evry_Window *win;
1220 Evry_State *s;
1221
1222 if (!sel)
1223 {
1224 ERR("selector == NULL");
1225 return;
1226 }
1227
1228 win = sel->win;
1229
1230 if (CUR_SEL)
1231 {
1232 Evry_Selector *cur = CUR_SEL;
1233 _evry_selector_signal_emit(cur, "e,state,unselected");
1234
1235 if (cur->state && cur->state->view)
1236 _evry_view_hide(win, cur->state->view, slide);
1237
1238 if (!slide && evry_conf->hide_list)
1239 _evry_list_win_hide(win);
1240 }
1241
1242 CUR_SEL = sel;
1243
1244 _evry_selector_signal_emit(sel, "e,state,selected");
1245
1246 /* do delayed actions fetch now */
1247 if (sel->action_timer)
1248 _evry_selector_update_actions_do(sel);
1249
1250 if ((s = sel->state))
1251 {
1252 _evry_update_text_label(s);
1253
1254 if (s->cur_item)
1255 _evry_selector_label_set(sel, "e.text.plugin",
1256 EVRY_ITEM(s->cur_item->plugin)->label);
1257
1258 if (_evry_view_create(s))
1259 {
1260 _evry_view_show(win, s->view, slide);
1261 s->view->update(s->view);
1262 }
1263 }
1264 }
1265
1266 static void
_evry_selector_thumb_gen(void * data,Evas_Object * obj EINA_UNUSED,void * event_info EINA_UNUSED)1267 _evry_selector_thumb_gen(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
1268 {
1269 Evas_Coord w, h;
1270 Evry_Selector *sel = data;
1271 Evry_Window *win = sel->win;
1272 char buf[64];
1273
1274 if (sel->o_icon)
1275 {
1276 evas_object_del(sel->o_icon);
1277 sel->o_icon = NULL;
1278 }
1279
1280 e_icon_size_get(sel->o_thumb, &w, &h);
1281 evas_object_size_hint_aspect_set(sel->o_thumb, EVAS_ASPECT_CONTROL_BOTH, w, h);
1282
1283 snprintf(buf, sizeof(buf), "%s:e.swallow.thumb", sel->edje_part);
1284 edje_object_part_swallow(win->o_main, buf, sel->o_thumb);
1285
1286 evas_object_show(sel->o_thumb);
1287 _evry_selector_signal_emit(sel, "e,action,thumb,show");
1288 /* edje_object_signal_emit(sel->o_main, "e,action,thumb,show", "e"); */
1289 sel->do_thumb = EINA_FALSE;
1290 }
1291
1292 static int
_evry_selector_thumb(Evry_Selector * sel,const Evry_Item * it)1293 _evry_selector_thumb(Evry_Selector *sel, const Evry_Item *it)
1294 {
1295 Evry_Window *win = sel->win;
1296 char *suffix = NULL;
1297
1298 if (sel->do_thumb)
1299 e_thumb_icon_end(sel->o_thumb);
1300
1301 if (sel->o_thumb)
1302 evas_object_del(sel->o_thumb);
1303 sel->o_thumb = NULL;
1304
1305 if (it->type != EVRY_TYPE_FILE)
1306 return 0;
1307
1308 GET_FILE(file, it);
1309
1310 if (!file->mime)
1311 return 0;
1312
1313 if (!(evry_file_path_get(file)))
1314 return 0;
1315
1316 if ((!strncmp(file->mime, "image/", 6)) ||
1317 ((suffix = strrchr(file->path, '.')) && (!strncmp(suffix, ".edj", 4))))
1318 {
1319 sel->o_thumb = e_thumb_icon_add(win->evas);
1320 e_thumb_icon_size_set(sel->o_thumb, 128, 128);
1321 evas_object_smart_callback_add(sel->o_thumb, "e_thumb_gen",
1322 _evry_selector_thumb_gen, sel);
1323 if (suffix)
1324 {
1325 e_thumb_icon_file_set(sel->o_thumb, file->path, "e/desktop/background");
1326 e_thumb_icon_size_set(sel->o_thumb, 128, 80);
1327 }
1328 else
1329 e_thumb_icon_file_set(sel->o_thumb, file->path, NULL);
1330
1331 e_thumb_icon_begin(sel->o_thumb);
1332 sel->do_thumb = EINA_TRUE;
1333 return 1;
1334 }
1335
1336 return 0;
1337 }
1338
1339 static void
_evry_selector_item_clear(Evry_Selector * sel)1340 _evry_selector_item_clear(Evry_Selector *sel)
1341 {
1342 if (sel->o_icon)
1343 {
1344 evas_object_del(sel->o_icon);
1345 sel->o_icon = NULL;
1346 }
1347
1348 if (sel->o_thumb)
1349 {
1350 if (sel->do_thumb)
1351 e_thumb_icon_end(sel->o_thumb);
1352
1353 evas_object_del(sel->o_thumb);
1354 sel->o_thumb = NULL;
1355 }
1356 }
1357
1358 static void
_evry_selector_item_update(Evry_Selector * sel)1359 _evry_selector_item_update(Evry_Selector *sel)
1360 {
1361 Evry_State *s = sel->state;
1362 Evry_Item *it = NULL;
1363 Evas_Object *o = NULL;
1364 Evry_Window *win = sel->win;
1365
1366 _evry_selector_item_clear(sel);
1367
1368 if ((!s) || !(s->cur_item))
1369 {
1370 /* no items for this state - clear selector */
1371 _evry_selector_label_set(sel, "e.text.label", "");
1372
1373 if (sel == CUR_SEL && s && s->plugin)
1374 _evry_selector_label_set(sel, "e.text.plugin",
1375 EVRY_ITEM(s->plugin)->label);
1376 else
1377 _evry_selector_label_set(sel, "e.text.plugin", "");
1378
1379 if (!s) return;
1380 }
1381
1382 if ((it = s->cur_item))
1383 {
1384 _evry_selector_label_set(sel, "e.text.label", it->label);
1385 _evry_selector_label_set(sel, "e.text.plugin",
1386 EVRY_ITEM(it->plugin)->label);
1387
1388 if (!_evry_selector_thumb(sel, it))
1389 {
1390 o = evry_util_icon_get(it, win->evas);
1391
1392 if ((!o) && it->plugin)
1393 o = evry_util_icon_get(EVRY_ITEM(it->plugin), win->evas);
1394 }
1395 }
1396
1397 if ((!o) && (s->plugin && (EVRY_ITEM(s->plugin)->icon)))
1398 {
1399 o = evry_icon_theme_get(EVRY_ITEM(s->plugin)->icon, win->evas);
1400 }
1401
1402 if (o)
1403 {
1404 char buf[64];
1405 snprintf(buf, sizeof(buf), "%s:e.swallow.icons", sel->edje_part);
1406 edje_object_part_swallow(win->o_main, buf, o);
1407 evas_object_show(o);
1408 sel->o_icon = o;
1409 }
1410 }
1411
1412 static void
_evry_selector_update(Evry_Selector * sel)1413 _evry_selector_update(Evry_Selector *sel)
1414 {
1415 Evry_State *s = sel->state;
1416 Evry_Item *it = NULL;
1417 Eina_Bool item_changed = EINA_FALSE;
1418 Evry_Window *win = sel->win;
1419
1420 DBG("%p", sel);
1421
1422 if (!s)
1423 {
1424 _evry_selector_item_update(sel);
1425 return;
1426 }
1427
1428 if ((it = s->cur_item))
1429 {
1430 if (!s->plugin || !eina_list_data_find_list(s->plugin->items, it))
1431 {
1432 _evry_item_desel(s);
1433 item_changed = EINA_TRUE;
1434 }
1435 }
1436
1437 /* get first item */
1438 if (s->plugin && ((!s->cur_item) || s->item_auto_selected))
1439 {
1440 it = eina_list_data_get(s->plugin->items);
1441 s->item_auto_selected = EINA_TRUE;
1442 if (!s->cur_plugins || (it != s->cur_item))
1443 item_changed = EINA_TRUE;
1444
1445 _evry_item_sel(s, it);
1446 }
1447
1448 _evry_selector_item_update(sel);
1449
1450 if ((sel == SUBJ_SEL) && (item_changed))
1451 _evry_selector_update_actions(ACTN_SEL);
1452 }
1453
1454 static void
_evry_list_win_update(Evry_State * s)1455 _evry_list_win_update(Evry_State *s)
1456 {
1457 Evry_Window *win = s->selector->win;
1458
1459 if (s != (CUR_SEL)->state) return;
1460 if (!win->visible) return;
1461
1462 if (_evry_view_update(win, s))
1463 _evry_view_show(win, s->view, 0);
1464 }
1465
1466 static int
_evry_selector_plugins_get(Evry_Selector * sel,Evry_Item * it,const char * plugin_name)1467 _evry_selector_plugins_get(Evry_Selector *sel, Evry_Item *it, const char *plugin_name)
1468 {
1469 Eina_List *l, *plugins = NULL;
1470 Evry_Plugin *p, *pp;
1471 Evry_Window *win = sel->win;
1472 Evry_Action *act = NULL;
1473
1474 while (sel->state)
1475 _evry_state_pop(sel, 1);
1476
1477 if ((sel != SUBJ_SEL) && (!it))
1478 return 0;
1479
1480 if (it && CHECK_TYPE(it, EVRY_TYPE_ACTION))
1481 act = (Evry_Action *)it;
1482
1483 EINA_LIST_FOREACH (sel->plugins, l, p)
1484 {
1485 if (!p->config->enabled && !win->plugin_dedicated)
1486 continue;
1487
1488 if (plugin_name && strcmp(plugin_name, p->name))
1489 continue;
1490
1491 if (act && (!CHECK_SUBTYPE(p, act->it2.type)))
1492 continue;
1493
1494 if (p->begin && (pp = p->begin(p, it)))
1495 plugins = eina_list_append(plugins, pp);
1496 }
1497
1498 _evry_state_new(sel, plugins);
1499
1500 if (plugins)
1501 _evry_matches_update(sel, 1);
1502
1503 return 1;
1504 }
1505
1506 static Evry_State *
_evry_state_new(Evry_Selector * sel,Eina_List * plugins)1507 _evry_state_new(Evry_Selector *sel, Eina_List *plugins)
1508 {
1509 Evry_State *s = E_NEW(Evry_State, 1);
1510 Eina_List *l;
1511 Evry_Plugin *p;
1512
1513 if (!s) return NULL;
1514
1515 s->inp = calloc(1, INPUTLEN);
1516 s->inp[0] = 0;
1517 s->input = s->inp;
1518 s->plugins = plugins;
1519 s->selector = sel;
1520
1521 sel->states = eina_list_prepend(sel->states, s);
1522 sel->state = s;
1523
1524 p = sel->aggregator->begin(sel->aggregator, NULL);
1525 s->plugins = eina_list_append(s->plugins, p);
1526 s->aggregator = p;
1527
1528 EINA_LIST_FOREACH (s->plugins, l, p)
1529 p->state = s;
1530
1531 return s;
1532 }
1533
1534 static void
_evry_state_pop(Evry_Selector * sel,int immediate)1535 _evry_state_pop(Evry_Selector *sel, int immediate)
1536 {
1537 Evry_Plugin *p;
1538 Evry_State *prev;
1539 Evry_Window *win = sel->win;
1540 Evry_State *s = sel->state;
1541
1542 _evry_item_desel(s);
1543
1544 if (sel->update_timer)
1545 {
1546 ecore_timer_del(sel->update_timer);
1547 sel->update_timer = NULL;
1548 }
1549
1550 if (sel->action_timer)
1551 {
1552 ecore_timer_del(sel->action_timer);
1553 sel->action_timer = NULL;
1554 }
1555
1556 if (s->view)
1557 {
1558 if (immediate)
1559 {
1560 s->view->destroy(s->view);
1561 }
1562 else
1563 {
1564 _evry_view_hide(win, s->view, SLIDE_RIGHT);
1565 /* XXX delay free state? is it possible that
1566 view can receive events here? */
1567 s->delete_me = EINA_TRUE;
1568 }
1569 }
1570
1571 if (s->sel_items)
1572 eina_list_free(s->sel_items);
1573
1574 if (s->cur_plugins)
1575 eina_list_free(s->cur_plugins);
1576
1577 sel->states = eina_list_remove_list(sel->states, sel->states);
1578 prev = eina_list_data_get(sel->states);
1579
1580 EINA_LIST_FREE (s->plugins, p)
1581 {
1582 /* skip non top-level plugins */
1583 if (prev && eina_list_data_find(prev->plugins, p))
1584 {
1585 p->state = prev;
1586 continue;
1587 }
1588 EVRY_ITEM_FREE(p);
1589 }
1590
1591 if (!s->delete_me)
1592 {
1593 if (win->state_clearing == s)
1594 win->state_clearing = NULL;
1595 ecore_timer_del(s->clear_timer);
1596 E_FREE(s->inp);
1597 E_FREE(s);
1598 }
1599
1600 sel->state = prev;
1601 }
1602
1603 int
evry_state_push(Evry_Selector * sel,Eina_List * plugins)1604 evry_state_push(Evry_Selector *sel, Eina_List *plugins)
1605 {
1606 Evry_State *s, *new_state;
1607 Eina_List *l;
1608 Evry_Plugin *p;
1609 Evry_View *view = NULL;
1610 Evry_Window *win = sel->win;
1611
1612 s = sel->state;
1613
1614 if (!(new_state = _evry_state_new(sel, plugins)))
1615 {
1616 DBG("no new state");
1617 return 0;
1618 }
1619
1620 EINA_LIST_FOREACH (plugins, l, p)
1621 p->state = new_state;
1622
1623 if (s && s->view)
1624 {
1625 _evry_view_hide(win, s->view, SLIDE_LEFT);
1626 view = s->view;
1627 }
1628
1629 _evry_matches_update(sel, 1);
1630 s = new_state;
1631
1632 _evry_selector_update(sel);
1633
1634 if (view && win->visible)
1635 {
1636 s->view = view->create(view, s, win->o_main);
1637 if (s->view)
1638 {
1639 s->view->state = s;
1640 _evry_view_show(win, s->view, SLIDE_LEFT);
1641 s->view->update(s->view);
1642 }
1643 }
1644
1645 _evry_update_text_label(sel->state);
1646
1647 return 1;
1648 }
1649
1650 int
evry_browse_item(Evry_Item * it)1651 evry_browse_item(Evry_Item *it)
1652 {
1653 Evry_State *s, *new_state;
1654 Evry_Selector *sel;
1655 Eina_List *l, *plugins = NULL;
1656 Evry_Plugin *p, *pp, *pref = NULL;
1657 Evry_View *view = NULL;
1658 int browse_aggregator = 0;
1659 Evry_Window *win;
1660
1661 if (!(it) || !(it->plugin) || !(it->browseable))
1662 {
1663 DBG("no item");
1664 return 0;
1665 }
1666
1667 if (!(s = it->plugin->state))
1668 {
1669 DBG("no state");
1670 return 0;
1671 }
1672
1673 sel = s->selector;
1674 win = sel->win;
1675
1676 /* aggregator */
1677 if (CHECK_TYPE(it, EVRY_TYPE_PLUGIN))
1678 {
1679 browse_aggregator = 1;
1680 plugins = eina_list_append(plugins, it);
1681 }
1682 else
1683 {
1684 if ((it->plugin->browse) && (pp = it->plugin->browse(it->plugin, it)))
1685 {
1686 plugins = eina_list_append(plugins, pp);
1687 pref = pp;
1688 }
1689
1690 /* items of type NONE can only be browsed by their own plugin */
1691 if (!CHECK_TYPE(it, EVRY_TYPE_NONE))
1692 {
1693 EINA_LIST_FOREACH (sel->plugins, l, p)
1694 {
1695 if (!p->browse)
1696 continue;
1697
1698 if ((pref) && (!strcmp(p->name, pref->name)))
1699 continue;
1700
1701 if ((pp = p->browse(p, it)))
1702 plugins = eina_list_append(plugins, pp);
1703 }
1704 }
1705 }
1706
1707 if (!(plugins))
1708 {
1709 DBG("no plugins");
1710 return 0;
1711 }
1712
1713 if (!(new_state = _evry_state_new(sel, plugins)))
1714 {
1715 DBG("no new state");
1716 return 0;
1717 }
1718
1719 if (s->view)
1720 {
1721 _evry_view_hide(win, s->view, SLIDE_LEFT);
1722 view = s->view;
1723 }
1724
1725 if (browse_aggregator)
1726 {
1727 it->hi = NULL;
1728
1729 if (!EVRY_PLUGIN(it)->items)
1730 {
1731 evry_history_item_add(it, NULL, s->input);
1732 s = new_state;
1733 EVRY_PLUGIN(it)->state = s;
1734 _evry_matches_update(sel, 1);
1735 }
1736 else
1737 {
1738 evry_history_item_add(it, NULL, NULL);
1739 strncpy(new_state->input, s->input, INPUTLEN);
1740 s = new_state;
1741 EVRY_PLUGIN(it)->state = s;
1742 s->cur_plugins = eina_list_append(s->cur_plugins, it);
1743 }
1744
1745 _evry_plugin_select(s, EVRY_PLUGIN(it));
1746 }
1747 else
1748 {
1749 if (it->plugin->history)
1750 evry_history_item_add(it, NULL, s->input);
1751
1752 _evry_matches_update(sel, 1);
1753 s = new_state;
1754 _evry_plugin_select(s, pref);
1755 }
1756
1757 _evry_selector_update(sel);
1758
1759 if (view && win->visible)
1760 {
1761 s->view = view->create(view, s, win->o_main);
1762 if (s->view)
1763 {
1764 s->view->state = s;
1765 s->view->update(s->view);
1766 _evry_view_show(win, s->view, SLIDE_LEFT);
1767 }
1768 }
1769
1770 _evry_update_text_label(sel->state);
1771
1772 return 1;
1773 }
1774
1775 int
evry_browse_back(Evry_Selector * sel)1776 evry_browse_back(Evry_Selector *sel)
1777 {
1778 Evry_Window *win;
1779
1780 if (!sel) return 0;
1781
1782 if ((!sel) || !(win = sel->win))
1783 return 0;
1784
1785 if ((!sel->state) || (!sel->states->next))
1786 return 0;
1787
1788 _evry_state_pop(sel, 0);
1789
1790 _evry_selector_update(sel);
1791 _evry_update_text_label(sel->state);
1792
1793 if (sel == SUBJ_SEL)
1794 _evry_selector_update_actions(ACTN_SEL);
1795
1796 if (sel->state->view)
1797 {
1798 _evry_view_show(win, sel->state->view, SLIDE_RIGHT);
1799 sel->state->view->update(sel->state->view);
1800 }
1801
1802 return 1;
1803 }
1804
1805 int
evry_selectors_switch(Evry_Window * win,int dir,int slide)1806 evry_selectors_switch(Evry_Window *win, int dir, int slide)
1807 {
1808 Evry_State *s = (CUR_SEL)->state;
1809
1810 if ((CUR_SEL)->update_timer)
1811 {
1812 if ((CUR_SEL == SUBJ_SEL) || (CUR_SEL == ACTN_SEL))
1813 {
1814 _evry_matches_update(CUR_SEL, 0);
1815 _evry_selector_update(CUR_SEL);
1816 }
1817 }
1818
1819 if (CUR_SEL != SUBJ_SEL && dir == 0)
1820 {
1821 edje_object_signal_emit(win->o_main, "e,state,object_selector_hide", "e");
1822 _evry_selector_activate(SUBJ_SEL, (slide * SLIDE_RIGHT));
1823 return 1;
1824 }
1825 if (CUR_SEL == SUBJ_SEL && dir > 0)
1826 {
1827 if (s->cur_item)
1828 {
1829 _evry_selector_activate(ACTN_SEL, slide * SLIDE_LEFT);
1830 return 1;
1831 }
1832 }
1833 else if (CUR_SEL == ACTN_SEL && dir > 0)
1834 {
1835 Evry_Item *it;
1836
1837 if (!s || !(it = s->cur_item) || !(CHECK_TYPE(it, EVRY_TYPE_ACTION)))
1838 return 0;
1839
1840 GET_ACTION(act, it);
1841 if (!act->it2.type)
1842 return 0;
1843
1844 _evry_selector_plugins_get(OBJ_SEL, it, NULL);
1845 _evry_selector_update(OBJ_SEL);
1846 edje_object_signal_emit(win->o_main, "e,state,object_selector_show", "e");
1847
1848 _evry_selector_activate(OBJ_SEL, (slide * SLIDE_LEFT));
1849 return 1;
1850 }
1851 else if (CUR_SEL == ACTN_SEL && dir < 0)
1852 {
1853 _evry_selector_activate(SUBJ_SEL, (slide * SLIDE_RIGHT));
1854 edje_object_signal_emit(win->o_main, "e,state,object_selector_hide", "e");
1855 return 1;
1856 }
1857 else if (CUR_SEL == OBJ_SEL && dir < 0)
1858 {
1859 _evry_selector_activate(ACTN_SEL, (slide * SLIDE_RIGHT));
1860 return 1;
1861 }
1862 return 0;
1863 }
1864
1865 static int
_evry_selectors_switch(Evry_Window * win,int dir)1866 _evry_selectors_switch(Evry_Window *win, int dir)
1867 {
1868 return evry_selectors_switch(win, dir, 0);
1869 }
1870
1871 static int
_evry_input_complete(Evry_State * s)1872 _evry_input_complete(Evry_State *s)
1873 {
1874 int action = 0;
1875 char *input = NULL;
1876 Evry_Item *it = s->cur_item;
1877 Evry_Window *win = s->selector->win;
1878
1879 if (!it) return 0;
1880
1881 evry_item_ref(it);
1882
1883 s->item_auto_selected = EINA_FALSE;
1884
1885 if (it->plugin->complete)
1886 action = it->plugin->complete(it->plugin, it, &input);
1887 else
1888 evry_browse_item(it);
1889
1890 if (input && action == EVRY_COMPLETE_INPUT)
1891 {
1892 strncpy(s->input, input, INPUTLEN - 1);
1893 _evry_update_text_label(s);
1894 if (CUR_SEL->update_timer)
1895 {
1896 ecore_timer_del(CUR_SEL->update_timer);
1897 CUR_SEL->update_timer = NULL;
1898 }
1899 _evry_cb_update_timer(CUR_SEL);
1900 evry_item_select(s, it);
1901 }
1902
1903 evry_item_free(it);
1904 E_FREE(input);
1905
1906 return 1;
1907 }
1908
1909 static int
_evry_cheat_history(Evry_State * s,int promote,int delete)1910 _evry_cheat_history(Evry_State *s, int promote, int delete)
1911 {
1912 History_Entry *he;
1913 History_Item *hi;
1914 History_Types *ht;
1915 Eina_List *l, *ll;
1916 Evry_Item *it = s->cur_item;
1917
1918 if (!it) return 0;
1919
1920 if (!(ht = evry_history_types_get(it->type)))
1921 return 1;
1922
1923 if (!(he = eina_hash_find(ht->types, (it->id ? it->id : it->label))))
1924 return 1;
1925
1926 EINA_LIST_FOREACH_SAFE (he->items, l, ll, hi)
1927 {
1928 if (hi->plugin != it->plugin->name)
1929 continue;
1930
1931 if (delete)
1932 {
1933 if (hi->input)
1934 eina_stringshare_del(hi->input);
1935 if (hi->plugin)
1936 eina_stringshare_del(hi->plugin);
1937 if (hi->context)
1938 eina_stringshare_del(hi->context);
1939 E_FREE(hi);
1940
1941 he->items = eina_list_remove_list(he->items, l);
1942 }
1943 else if (promote)
1944 {
1945 hi->count += 5;
1946 hi->last_used = ecore_time_unix_get();
1947 }
1948 else /* demote */
1949 {
1950 hi->count -= 5;
1951 if (hi->count < 0) hi->count = 1;
1952 }
1953 }
1954 if (s->plugin == s->aggregator)
1955 _evry_aggregator_fetch(s);
1956 if (s->view)
1957 s->view->update(s->view);
1958
1959 return 1;
1960 }
1961
1962 static Eina_Bool
_evry_cb_key_down(void * data,int type EINA_UNUSED,void * event)1963 _evry_cb_key_down(void *data, int type EINA_UNUSED, void *event)
1964 {
1965 Ecore_Event_Key *ev = event;
1966 Evry_State *s;
1967 Evry_Selector *sel;
1968 Evry_Window *win = data;
1969 const char *old;
1970
1971 if ((win->grab && (ev->event_window != ecore_evas_window_get(e_comp->ee))) &&
1972 (ev->event_window != elm_win_window_id_get(win->ewin)))
1973 return ECORE_CALLBACK_PASS_ON;
1974
1975 if (!strcmp(ev->key, "Escape"))
1976 {
1977 evry_hide(win, 0);
1978 return ECORE_CALLBACK_PASS_ON;
1979 }
1980 #ifdef DRAG_OFF_WINDOW
1981 else if (win->grab && !strcmp(ev->key, "F1"))
1982 {
1983 Evas_Object *ewin = win->ewin;
1984 E_Client *ec;
1985
1986 e_grabinput_release(elm_win_window_id_get(ewin), elm_win_window_id_get(ewin));
1987
1988 ec = e_win_client_get(ewin);
1989 elm_win_borderless_set(ewin, 0);
1990 ec->override = 0;
1991 #ifndef HAVE_WAYLAND_ONLY
1992 if (e_comp->comp_type == E_PIXMAP_TYPE_X)
1993 ecore_x_netwm_window_type_set(elm_win_window_id_get(ewin),
1994 ECORE_X_WINDOW_TYPE_DIALOG);
1995 #endif
1996 evas_object_layer_set(ec->frame, E_LAYER_CLIENT_NORMAL);
1997 EC_CHANGED(ec);
1998 ec->netwm.fetch.type = 1;
1999 ec->netwm.state.skip_taskbar = 0;
2000 ec->netwm.update.state = 1;
2001 ec->internal_no_remember = 1;
2002 e_comp_object_frame_theme_set(ec->frame, E_COMP_OBJECT_FRAME_RESHADOW);
2003
2004 win->grab = 0;
2005 return ECORE_CALLBACK_PASS_ON;
2006 }
2007 #endif
2008 else if ((ev->modifiers) && (!win->delay_hide_action))
2009 {
2010 Eina_List *l;
2011 E_Config_Binding_Key *binding;
2012 E_Binding_Modifier mod;
2013
2014 EINA_LIST_FOREACH(e_bindings->key_bindings, l, binding)
2015 {
2016 if (binding->action && strcmp(binding->action, "everything")) continue;
2017
2018 mod = 0;
2019
2020 if (ev->modifiers & ECORE_EVENT_MODIFIER_SHIFT)
2021 mod |= E_BINDING_MODIFIER_SHIFT;
2022 if (ev->modifiers & ECORE_EVENT_MODIFIER_CTRL)
2023 mod |= E_BINDING_MODIFIER_CTRL;
2024 if (ev->modifiers & ECORE_EVENT_MODIFIER_ALT)
2025 mod |= E_BINDING_MODIFIER_ALT;
2026 if (ev->modifiers & ECORE_EVENT_MODIFIER_WIN)
2027 mod |= E_BINDING_MODIFIER_WIN;
2028
2029 if (!(binding->key && (!strcmp(binding->key, ev->key)) &&
2030 (((unsigned int)binding->modifiers == mod) || (binding->any_mod))))
2031 continue;
2032
2033 if (win->level > 0)
2034 return ECORE_CALLBACK_PASS_ON;
2035
2036 if (!(binding->params) && (CUR_SEL == OBJ_SEL) &&
2037 ((CUR_SEL)->state && (CUR_SEL)->state->cur_item))
2038 {
2039 _evry_selectors_shift(win, 1);
2040 return ECORE_CALLBACK_PASS_ON;
2041 }
2042
2043 evry_hide(win, 1);
2044
2045 #if 0 /* FIXME this causes segv when triggering a plugin keybinding twice */
2046 if (win && CUR_SEL && binding->params)
2047 {
2048 Eina_List *ll;
2049 Evry_Plugin *p;
2050
2051 EINA_LIST_FOREACH ((SUBJ_SEL)->plugins, ll, p)
2052 if (!strcmp(binding->params, p->name)) break;
2053
2054 if (p)
2055 {
2056 _evry_plugin_select((CUR_SEL)->state, p);
2057 _evry_selector_update(CUR_SEL);
2058 _evry_view_update(win, (CUR_SEL)->state);
2059 }
2060 }
2061 #endif
2062 return ECORE_CALLBACK_PASS_ON;
2063 }
2064 }
2065
2066 old = ev->key;
2067 win->request_selection = EINA_FALSE;
2068
2069 if (!strcmp(ev->key, "KP_Enter"))
2070 {
2071 ev->key = "Return";
2072 }
2073 else if (ev->modifiers & ECORE_EVENT_MODIFIER_ALT)
2074 {
2075 if (!strcmp(ev->key, "Tab"))
2076 {
2077 ev->key = "Down";
2078 }
2079 else if (!strcmp(ev->key, "ISO_Left_Tab") || (!strcmp(ev->key, "Tab") &&
2080 (ev->modifiers & ECORE_EVENT_MODIFIER_SHIFT)))
2081 {
2082 ev->key = "Up";
2083 ev->modifiers = 0;
2084 }
2085 else if (!strcmp(ev->key, "q"))
2086 {
2087 evry_hide(win, 0);
2088 return 1;
2089 }
2090 else if (!strcmp(ev->key, "w"))
2091 {
2092 ev->key = "Return";
2093 ev->modifiers = 0;
2094 }
2095 else if (evry_conf->quick_nav == 1)
2096 {
2097 if (!strcmp(ev->key, "k") || (!strcmp(ev->key, "K")))
2098 ev->key = "Up";
2099 else if (!strcmp(ev->key, "j") || (!strcmp(ev->key, "J")))
2100 ev->key = "Down";
2101 else if (!strcmp(ev->key, "n") || (!strcmp(ev->key, "N")))
2102 ev->key = "Next";
2103 else if (!strcmp(ev->key, "p") || (!strcmp(ev->key, "P")))
2104 ev->key = "Prior";
2105 else if (!strcmp(ev->key, "l") || (!strcmp(ev->key, "L")))
2106 ev->key = "Right";
2107 else if (!strcmp(ev->key, "h") || (!strcmp(ev->key, "H")))
2108 ev->key = "Left";
2109 else if (!strcmp(ev->key, "i") || (!strcmp(ev->key, "I")))
2110 ev->key = "Tab";
2111 else if (!strcmp(ev->key, "m") || (!strcmp(ev->key, "M")))
2112 ev->key = "Return";
2113 }
2114 else if (evry_conf->quick_nav == 3)
2115 {
2116 if (!strcmp(ev->key, "p") || (!strcmp(ev->key, "P")))
2117 ev->key = "Up";
2118 else if (!strcmp(ev->key, "n") || (!strcmp(ev->key, "N")))
2119 ev->key = "Down";
2120 else if (!strcmp(ev->key, "f") || (!strcmp(ev->key, "F")))
2121 ev->key = "Right";
2122 else if (!strcmp(ev->key, "b") || (!strcmp(ev->key, "B")))
2123 ev->key = "Left";
2124 else if (!strcmp(ev->key, "i") || (!strcmp(ev->key, "I")))
2125 ev->key = "Tab";
2126 else if (!strcmp(ev->key, "m") || (!strcmp(ev->key, "M")))
2127 ev->key = "Return";
2128 }
2129 }
2130
2131 if (!(sel = CUR_SEL))
2132 goto end;
2133
2134 if (!strcmp(ev->key, "Tab") &&
2135 !((ev->modifiers & ECORE_EVENT_MODIFIER_CTRL) ||
2136 (ev->modifiers & ECORE_EVENT_MODIFIER_SHIFT)))
2137 {
2138 if (!_evry_selectors_switch(win, 1))
2139 _evry_selectors_switch(win, 0);
2140 goto end;
2141 }
2142
2143 if (!(s = sel->state))
2144 goto end;
2145
2146 if (!win->visible && (!strcmp(ev->key, "Down")))
2147 {
2148 _evry_list_win_show(win);
2149 goto end;
2150 }
2151 else if ((!strcmp(ev->key, "ISO_Left_Tab") ||
2152 (((ev->modifiers & ECORE_EVENT_MODIFIER_CTRL) ||
2153 (ev->modifiers & ECORE_EVENT_MODIFIER_SHIFT)) &&
2154 (!strcmp(ev->key, "Tab")))))
2155 {
2156 _evry_input_complete(s);
2157 goto end;
2158 }
2159 else if ((ev->modifiers & ECORE_EVENT_MODIFIER_CTRL) &&
2160 (!strcmp(ev->key, "Delete") || !strcmp(ev->key, "Insert")))
2161 {
2162 int delete = (!strcmp(ev->key, "Delete") &&
2163 (ev->modifiers & ECORE_EVENT_MODIFIER_SHIFT));
2164 int promote = (!strcmp(ev->key, "Insert"));
2165
2166 _evry_cheat_history(s, promote, delete);
2167 goto end;
2168 }
2169 else if (ev->modifiers & ECORE_EVENT_MODIFIER_CTRL)
2170 {
2171 if (!strcmp(ev->key, "u"))
2172 {
2173 if (!_evry_clear(sel))
2174 evry_browse_back(sel);
2175 goto end;
2176 }
2177 else if (!strcmp(ev->key, "1"))
2178 evry_view_toggle(s, NULL);
2179 else if (!strcmp(ev->key, "Return"))
2180 _evry_plugin_action(sel, 0);
2181 else if (!strcmp(ev->key, "v"))
2182 {
2183 #ifndef HAVE_WAYLAND_ONLY
2184 if (e_comp->comp_type == E_PIXMAP_TYPE_X)
2185 {
2186 win->request_selection = EINA_TRUE;
2187 ecore_x_selection_primary_request
2188 (elm_win_window_id_get(win->ewin), ECORE_X_SELECTION_TARGET_UTF8_STRING);
2189 }
2190 #endif
2191 }
2192 else
2193 {
2194 _evry_view_key_press(s, ev);
2195 }
2196 goto end;
2197 }
2198 if ((s->plugin && s->plugin->cb_key_down) &&
2199 (s->plugin->cb_key_down(s->plugin, ev)))
2200 {
2201 /* let plugin intercept keypress */
2202 goto end;
2203 }
2204 else if (_evry_view_key_press(s, ev))
2205 {
2206 /* let view intercept keypress */
2207 goto end;
2208 }
2209 else if (!strcmp(ev->key, "Right"))
2210 {
2211 if (!evry_browse_item(sel->state->cur_item))
2212 evry_selectors_switch(win, 1, EINA_TRUE);
2213 }
2214 else if (!strcmp(ev->key, "Left"))
2215 {
2216 if (!evry_browse_back(sel))
2217 evry_selectors_switch(win, -1, EINA_TRUE);
2218 }
2219 else if (!strcmp(ev->key, "Return"))
2220 {
2221 if (ev->modifiers & ECORE_EVENT_MODIFIER_SHIFT)
2222 {
2223 _evry_plugin_action(sel, 0);
2224 }
2225 else if (s->cur_item && s->cur_item->browseable)
2226 {
2227 evry_browse_item(sel->state->cur_item);
2228 }
2229 else
2230 {
2231 _evry_plugin_action(sel, 1);
2232 }
2233 }
2234 else if (!strcmp(ev->key, "BackSpace"))
2235 {
2236 if (!_evry_backspace(sel))
2237 evry_browse_back(sel);
2238 }
2239 else if ((ev->compose && !(ev->modifiers & ECORE_EVENT_MODIFIER_ALT)))
2240 {
2241 unsigned int len = strlen(s->inp);
2242
2243 if (len == 0 && (evry_view_toggle(s, ev->compose)))
2244 goto end;
2245
2246 if (len < (INPUTLEN - strlen(ev->compose)))
2247 {
2248 strcat(s->inp, ev->compose);
2249
2250 _evry_update(sel, 1);
2251 }
2252 }
2253
2254 end:
2255 ev->key = old;
2256 return ECORE_CALLBACK_PASS_ON;
2257 }
2258
2259 static int
_evry_backspace(Evry_Selector * sel)2260 _evry_backspace(Evry_Selector *sel)
2261 {
2262 Evry_State *s = sel->state;
2263 int len, val, pos;
2264
2265 if (!(len = strlen(s->inp)))
2266 return 0;
2267
2268 pos = evas_string_char_prev_get(s->inp, len, &val);
2269 if ((pos < len) && (pos >= 0))
2270 {
2271 val = *(s->inp + pos);
2272
2273 s->inp[pos] = 0;
2274
2275 if (s->trigger_active && s->inp[0] != 0)
2276 s->input = s->inp + 1;
2277 else
2278 s->input = s->inp;
2279
2280 if (pos == 0)
2281 s->trigger_active = EINA_FALSE;
2282
2283 if ((pos == 0) || !isspace(val))
2284 _evry_update(sel, 1);
2285
2286 return 1;
2287 }
2288
2289 return 0;
2290 }
2291
2292 static void
_evry_update_text_label(Evry_State * s)2293 _evry_update_text_label(Evry_State *s)
2294 {
2295 Evry_Window *win = s->selector->win;
2296
2297 if (!win->visible && evry_conf->hide_input)
2298 {
2299 if (strlen(s->inp) > 0)
2300 edje_object_signal_emit(win->o_main, "list:e,state,entry_show", "e");
2301 else
2302 edje_object_signal_emit(win->o_main, "list:e,state,entry_hide", "e");
2303 }
2304
2305 edje_object_part_text_set(win->o_main, "list:e.text.label", s->inp);
2306 }
2307
2308 static void
_evry_update(Evry_Selector * sel,int fetch)2309 _evry_update(Evry_Selector *sel, int fetch)
2310 {
2311 Evry_State *s = sel->state;
2312 Evry_Window *win = sel->win;
2313
2314 _evry_update_text_label(s);
2315
2316 if (fetch)
2317 {
2318 if (sel->update_timer)
2319 ecore_timer_del(sel->update_timer);
2320
2321 sel->update_timer =
2322 ecore_timer_loop_add(MATCH_LAG, _evry_cb_update_timer, sel);
2323
2324 edje_object_signal_emit(win->o_main, "list:e,signal,update", "e");
2325 }
2326 }
2327
2328 static Eina_Bool
_evry_cb_update_timer(void * data)2329 _evry_cb_update_timer(void *data)
2330 {
2331 Evry_Selector *sel = data;
2332
2333 _evry_matches_update(sel, 1);
2334 _evry_selector_update(sel);
2335 _evry_list_win_update(sel->state);
2336 sel->update_timer = NULL;
2337
2338 return ECORE_CALLBACK_CANCEL;
2339 }
2340
2341 static int
_evry_clear(Evry_Selector * sel)2342 _evry_clear(Evry_Selector *sel)
2343 {
2344 Evry_State *s = sel->state;
2345 Evry_Window *win = sel->win;
2346
2347 if (!(s->inp) || (s->inp[0] == 0))
2348 return 0;
2349
2350 if (s->trigger_active && s->inp[1] != 0)
2351 {
2352 s->inp[1] = 0;
2353 s->input = s->inp + 1;
2354 }
2355 else
2356 {
2357 s->inp[0] = 0;
2358 s->input = s->inp;
2359 s->trigger_active = EINA_FALSE;
2360 }
2361
2362 _evry_update(sel, 1);
2363
2364 if (!win->visible && evry_conf->hide_input)
2365 edje_object_signal_emit(win->o_main, "list:e,state,entry_hide", "e");
2366
2367 return 1;
2368 }
2369
2370 static void
_evry_cb_free_action_performed(void * data EINA_UNUSED,void * event)2371 _evry_cb_free_action_performed(void *data EINA_UNUSED, void *event)
2372 {
2373 Evry_Event_Action_Performed *ev = event;
2374
2375 if (ev->it1)
2376 EVRY_ITEM_FREE(ev->it1);
2377 if (ev->it2)
2378 EVRY_ITEM_FREE(ev->it2);
2379
2380 IF_RELEASE(ev->action);
2381
2382 E_FREE(ev);
2383 }
2384
2385 static int
_evry_action_do(Evry_Action * act)2386 _evry_action_do(Evry_Action *act)
2387 {
2388 Evry_Event_Action_Performed *ev;
2389 int ret;
2390
2391 if ((ret = act->action(act)))
2392 {
2393 ev = E_NEW(Evry_Event_Action_Performed, 1);
2394 ev->action = eina_stringshare_ref(act->name);
2395 ev->it1 = act->it1.item;
2396 ev->it2 = act->it2.item;
2397
2398 if (ev->it1)
2399 EVRY_ITEM_REF(ev->it1);
2400 if (ev->it2)
2401 EVRY_ITEM_REF(ev->it2);
2402
2403 ecore_event_add(_evry_events[EVRY_EVENT_ACTION_PERFORMED], ev,
2404 _evry_cb_free_action_performed, NULL);
2405 return ret;
2406 }
2407 return 0;
2408 }
2409
2410 void
evry_plugin_action(Evry_Window * win,int finished)2411 evry_plugin_action(Evry_Window *win, int finished)
2412 {
2413 _evry_plugin_action(CUR_SEL, finished);
2414 }
2415
2416 static void
_evry_plugin_action(Evry_Selector * sel,int finished)2417 _evry_plugin_action(Evry_Selector *sel, int finished)
2418 {
2419 Evry_State *s_subj, *s_act, *s_obj = NULL;
2420 Evry_Item *it, *it_subj, *it_act, *it_obj = NULL;
2421 Evry_Window *win = sel->win;
2422 Eina_List *l;
2423 int ret = 0;
2424
2425 if ((SUBJ_SEL)->update_timer)
2426 {
2427 _evry_matches_update(SUBJ_SEL, 0);
2428 _evry_selector_update(SUBJ_SEL);
2429 }
2430
2431 /* do delayed fetch actions now */
2432 if ((ACTN_SEL)->action_timer)
2433 _evry_selector_update_actions_do(ACTN_SEL);
2434
2435 if (!(s_subj = (SUBJ_SEL)->state))
2436 return;
2437
2438 if (!(it_subj = s_subj->cur_item))
2439 return;
2440
2441 if ((CUR_SEL == SUBJ_SEL) && (ACTN_SEL)->update_timer)
2442 {
2443 /* _evry_selector_actions_get(it_subj); */
2444 _evry_selector_plugins_get(ACTN_SEL, it_subj, NULL);
2445
2446 if (!(ACTN_SEL)->state)
2447 return;
2448
2449 _evry_selector_update(ACTN_SEL);
2450 }
2451
2452 if (!(s_act = (ACTN_SEL)->state))
2453 return;
2454
2455 if (!(it_act = s_act->cur_item))
2456 return;
2457
2458 if (CHECK_TYPE(it_act, EVRY_TYPE_ACTION) ||
2459 CHECK_SUBTYPE(it_act, EVRY_TYPE_ACTION))
2460 {
2461 GET_ACTION(act, it_act);
2462
2463 if (!act->action)
2464 return;
2465
2466 /* get object item for action, when required */
2467 if (act->it2.type)
2468 {
2469 /* check if object is provided */
2470 if ((s_obj = (OBJ_SEL)->state) && (!s_obj->delete_me))
2471 {
2472 it_obj = s_obj->cur_item;
2473 }
2474
2475 if (!it_obj)
2476 {
2477 if (SUBJ_SEL == CUR_SEL)
2478 _evry_selectors_switch(win, 1);
2479 if (ACTN_SEL == CUR_SEL)
2480 _evry_selectors_switch(win, 1);
2481 return;
2482 }
2483
2484 act->it2.item = it_obj;
2485 }
2486
2487 if (s_obj && s_obj->sel_items && !(act->it2.accept_list))
2488 {
2489 if (!(act->it1.item && CHECK_TYPE(act->it1.item, EVRY_TYPE_PLUGIN)))
2490 act->it1.item = it_subj;
2491
2492 EINA_LIST_FOREACH (s_obj->sel_items, l, it)
2493 {
2494 if (it->type != act->it2.type)
2495 continue;
2496 act->it2.item = it;
2497
2498 _evry_action_do(act);
2499 }
2500 }
2501 else if (s_subj->sel_items && !(act->it1.accept_list))
2502 {
2503 EINA_LIST_FOREACH (s_subj->sel_items, l, it)
2504 {
2505 if (it->type != act->it1.type)
2506 continue;
2507 act->it1.item = it;
2508
2509 _evry_action_do(act);
2510 }
2511 }
2512 else
2513 {
2514 if (!(act->it1.item && CHECK_TYPE(act->it1.item, EVRY_TYPE_PLUGIN)))
2515 {
2516 act->it1.item = it_subj;
2517 act->it1.items = s_subj->sel_items;
2518 }
2519
2520 if (s_obj)
2521 act->it2.items = s_obj->sel_items;
2522
2523 ret = _evry_action_do(act);
2524
2525 if (ret == EVRY_ACTION_OTHER)
2526 return;
2527 }
2528 }
2529 else return;
2530
2531 if (s_subj && it_subj && it_subj->plugin->history)
2532 evry_history_item_add(it_subj, NULL, s_subj->input);
2533
2534 if (s_act && it_act && it_act->plugin->history)
2535 evry_history_item_add(it_act, it_subj->context, s_act->input);
2536
2537 if (s_obj && it_obj && it_obj->plugin->history)
2538 evry_history_item_add(it_obj, it_act->context, s_obj->input);
2539
2540 if (ret == EVRY_ACTION_CONTINUE)
2541 return;
2542
2543 if (ret == EVRY_ACTION_CLEAR)
2544 {
2545 _evry_clear(CUR_SEL);
2546 }
2547 else
2548 {
2549 win->func.hide(win, finished);
2550 }
2551 }
2552
2553 static void
_evry_view_list_swallow_set(Evas_Object * obj,const char * part,Evas_Object * swallow)2554 _evry_view_list_swallow_set(Evas_Object *obj, const char *part, Evas_Object *swallow)
2555 {
2556 Evas_Object *o;
2557
2558 o = edje_object_part_swallow_get(obj, part);
2559 if (o != swallow)
2560 {
2561 evas_object_hide(o);
2562 edje_object_part_unswallow(obj, o);
2563
2564 edje_object_part_unswallow(obj, swallow);
2565 edje_object_part_swallow(obj, part, swallow);
2566 evas_object_show(swallow);
2567 }
2568 }
2569
2570 static void
_evry_view_show(Evry_Window * win,Evry_View * v,int slide)2571 _evry_view_show(Evry_Window *win, Evry_View *v, int slide)
2572 {
2573 if (!v) return;
2574
2575 if (v->o_bar)
2576 {
2577 edje_object_part_swallow(win->o_main, "list:e.swallow.bar", v->o_bar);
2578 evas_object_show(v->o_bar);
2579 }
2580
2581 if (!v->o_list)
2582 return;
2583
2584 if (slide == SLIDE_LEFT)
2585 {
2586 _evry_view_list_swallow_set(win->o_main, "list:e.swallow.list2", v->o_list);
2587
2588 edje_object_signal_emit(win->o_main, "list:e,action,slide,left", "e");
2589 edje_object_signal_emit(v->o_list, "e,action,show,list", "e");
2590 }
2591 else if (slide == SLIDE_RIGHT)
2592 {
2593 _evry_view_list_swallow_set(win->o_main, "list:e.swallow.list", v->o_list);
2594
2595 edje_object_signal_emit(win->o_main, "list:e,action,slide,right", "e");
2596 edje_object_signal_emit(v->o_list, "e,action,show,list", "e");
2597 }
2598 else
2599 {
2600 _evry_view_list_swallow_set(win->o_main, "list:e.swallow.list", v->o_list);
2601
2602 edje_object_signal_emit(win->o_main, "list:e,action,slide,default", "e");
2603 edje_object_signal_emit(v->o_list, "e,action,show,list", "e");
2604 }
2605 }
2606
2607 static Eina_Bool
_clear_timer(void * data)2608 _clear_timer(void *data)
2609 {
2610 _evry_state_clear(data);
2611
2612 return ECORE_CALLBACK_CANCEL;
2613 }
2614
2615 static void
_evry_state_clear(Evry_Window * win)2616 _evry_state_clear(Evry_Window *win)
2617 {
2618 Evry_State *s;
2619 Evry_View *v;
2620
2621 if (!win->state_clearing)
2622 return;
2623
2624 s = win->state_clearing;
2625 win->state_clearing = NULL;
2626
2627 ecore_timer_del(s->clear_timer);
2628 s->clear_timer = NULL;
2629
2630 if (s->delete_me)
2631 {
2632 if (s->view) s->view->destroy(s->view);
2633 s->clear_timer = NULL;
2634 E_FREE(s->inp);
2635 E_FREE(s);
2636 }
2637 else if ((v = s->view))
2638 {
2639 v->clear(v);
2640
2641 if (v->o_list)
2642 {
2643 evas_object_hide(v->o_list);
2644 edje_object_part_unswallow(win->o_main, v->o_list);
2645 }
2646 }
2647
2648 /* replay mouse down to allow direct sliding back */
2649 if (win->mouse_button)
2650 evas_event_feed_mouse_down(win->evas, win->mouse_button, 0, 0, NULL);
2651 }
2652
2653 static void
_evry_view_hide(Evry_Window * win,Evry_View * v,int slide)2654 _evry_view_hide(Evry_Window *win, Evry_View *v, int slide)
2655 {
2656 _evry_state_clear(win);
2657
2658 if (!v || v->state->delete_me) return;
2659
2660 if (slide && v->o_list)
2661 {
2662 win->state_clearing = v->state;
2663
2664 if (slide == SLIDE_RIGHT)
2665 {
2666 _evry_view_list_swallow_set(win->o_main, "list:e.swallow.list2", v->o_list);
2667 }
2668 else /* if (slide == SLIDE_LEFT) */
2669 {
2670 _evry_view_list_swallow_set(win->o_main, "list:e.swallow.list", v->o_list);
2671 }
2672
2673 edje_object_signal_emit(v->o_list, "e,action,hide,list", "e");
2674
2675 /* FIXME get signal from theme when anim finished */
2676 v->state->clear_timer = ecore_timer_loop_add(1.5, _clear_timer, win);
2677
2678 if (v->o_bar)
2679 {
2680 evas_object_hide(v->o_bar);
2681 edje_object_part_unswallow(win->o_main, v->o_bar);
2682 }
2683
2684 return;
2685 }
2686
2687 v->clear(v);
2688
2689 if (v->o_list)
2690 {
2691 evas_object_hide(v->o_list);
2692 edje_object_part_unswallow(win->o_main, v->o_list);
2693 }
2694
2695 if (v->o_bar)
2696 {
2697 evas_object_hide(v->o_bar);
2698 edje_object_part_unswallow(win->o_main, v->o_bar);
2699 }
2700 }
2701
2702 static int
_evry_view_create(Evry_State * s)2703 _evry_view_create(Evry_State *s)
2704 {
2705 Evry_View *view;
2706
2707 if (s->view)
2708 return 1;
2709
2710 if (s->plugin && s->plugin->view)
2711 view = s->plugin->view;
2712 else
2713 view = eina_list_data_get(evry_conf->views);
2714
2715 s->view = view->create(view, s, s->selector->win->o_main);
2716
2717 if (s->view)
2718 {
2719 s->view->state = s;
2720 return 1;
2721 }
2722
2723 return 0;
2724 }
2725
2726 static int
_evry_view_update(Evry_Window * win,Evry_State * s)2727 _evry_view_update(Evry_Window *win, Evry_State *s)
2728 {
2729 if (!win->visible) return 0;
2730 /* TODO check this again !!!!*/
2731 if (s->view)
2732 {
2733 s->view->update(s->view);
2734 return 0;
2735 }
2736
2737 if (_evry_view_create(s))
2738 {
2739 s->view->update(s->view);
2740 return 1;
2741 }
2742
2743 return 0;
2744 }
2745
2746 static void
_evry_view_clear(Evry_State * s)2747 _evry_view_clear(Evry_State *s)
2748 {
2749 if (!s || !s->view) return;
2750
2751 s->view->clear(s->view);
2752 }
2753
2754 static int
_evry_view_key_press(Evry_State * s,Ecore_Event_Key * ev)2755 _evry_view_key_press(Evry_State *s, Ecore_Event_Key *ev)
2756 {
2757 if (!s || !s->view || !s->view->cb_key_down) return 0;
2758
2759 return s->view->cb_key_down(s->view, ev);
2760 }
2761
2762 int
evry_view_toggle(Evry_State * s,const char * trigger)2763 evry_view_toggle(Evry_State *s, const char *trigger)
2764 {
2765 Evry_View *view, *v = NULL;
2766 Eina_List *l, *ll;
2767 Eina_Bool triggered = EINA_FALSE;
2768 Evry_Window *win = s->selector->win;
2769
2770 if (trigger)
2771 {
2772 EINA_LIST_FOREACH (evry_conf->views, ll, view)
2773 {
2774 if (view->trigger && !strncmp(trigger, view->trigger, 1) &&
2775 (!s->view || (view->id != s->view->id)) &&
2776 (v = view->create(view, s, win->o_main)))
2777 {
2778 triggered = EINA_TRUE;
2779 goto found;
2780 }
2781 }
2782 }
2783 else
2784 {
2785 if (s->view)
2786 l = eina_list_data_find_list(evry_conf->views, s->view->id);
2787 else
2788 {
2789 view = evry_conf->views->data;
2790 v = view->create(view, s, win->o_main);
2791 goto found;
2792 }
2793
2794 if (l && l->next)
2795 l = l->next;
2796 else
2797 l = evry_conf->views;
2798
2799 EINA_LIST_FOREACH (l, ll, view)
2800 {
2801 if ((!view->trigger) &&
2802 ((!s->view || (view->id != s->view->id)) &&
2803 (v = view->create(view, s, win->o_main))))
2804 goto found;
2805 }
2806 }
2807
2808 found:
2809 if (!v) return 0;
2810
2811 _evry_list_win_show(win);
2812
2813 if (s->view)
2814 {
2815 _evry_view_hide(win, s->view, 0);
2816 s->view->destroy(s->view);
2817 }
2818
2819 s->view = v;
2820 s->view->state = s;
2821 _evry_view_show(win, s->view, 0);
2822 view->update(s->view);
2823
2824 return triggered;
2825 }
2826
2827 static void
_evry_matches_update(Evry_Selector * sel,int async)2828 _evry_matches_update(Evry_Selector *sel, int async)
2829 {
2830 Evry_State *s = sel->state;
2831 Evry_Plugin *p;
2832 Eina_List *l;
2833 Evry_Item *it;
2834 Evry_Window *win = sel->win;
2835 const char *input = NULL;
2836 size_t len_inp = 0;
2837
2838 s->changed = 1;
2839 s->request++;
2840
2841 #ifdef CHECK_TIME
2842 DBG("matches update %f", ecore_time_get() - _evry_time);
2843 #endif
2844
2845 if (sel->update_timer)
2846 {
2847 ecore_timer_del(sel->update_timer);
2848 sel->update_timer = NULL;
2849 }
2850
2851 if (s->sel_items)
2852 {
2853 eina_list_free(s->sel_items);
2854 s->sel_items = NULL;
2855 }
2856
2857 if (s->inp[0])
2858 {
2859 len_inp = strlen(s->inp);
2860 input = s->inp;
2861 }
2862
2863 /* use current plugins */
2864 if (s->trigger_active)
2865 {
2866 s->plugin_auto_selected = EINA_FALSE;
2867
2868 EINA_LIST_FOREACH (s->cur_plugins, l, p)
2869 {
2870 p->request = s->request;
2871 p->fetch(p, s->input);
2872 }
2873 goto found;
2874 }
2875
2876 EINA_LIST_FREE (s->cur_plugins, p) ;
2877
2878 /* check if input matches plugin trigger */
2879 if (input)
2880 {
2881 size_t len_trigger = 0;
2882
2883 EINA_LIST_FOREACH (s->plugins, l, p)
2884 {
2885 size_t len;
2886
2887 if (!p->config->trigger) continue;
2888 len = strlen(p->config->trigger);
2889
2890 if (len_trigger && len != len_trigger)
2891 continue;
2892
2893 if ((len_inp >= len) &&
2894 (!strncmp(s->inp, p->config->trigger, len)))
2895 {
2896 len_trigger = len;
2897 s->cur_plugins = eina_list_append(s->cur_plugins, p);
2898 p->request = s->request;
2899 if (len_inp == len)
2900 p->fetch(p, NULL);
2901 else
2902 p->fetch(p, s->input + len);
2903 }
2904 }
2905 if (s->cur_plugins)
2906 {
2907 s->trigger_active = EINA_TRUE;
2908 /* replace trigger with indicator */
2909 if (len_trigger > 1)
2910 {
2911 s->inp[0] = ':';
2912
2913 if (s->inp[len_trigger])
2914 strcpy(s->inp + 1, s->inp + len_trigger);
2915 else
2916 s->inp[1] = 0;
2917 }
2918 s->input = s->inp + 1;
2919 _evry_update_text_label(s);
2920
2921 goto found;
2922 }
2923 }
2924
2925 /* query all other plugins for this state */
2926 EINA_LIST_FOREACH (s->plugins, l, p)
2927 {
2928 p->request = s->request;
2929
2930 if (p == s->aggregator)
2931 goto next;
2932
2933 /* dont wait for async plugin. use their current items */
2934 if (!async && p->async_fetch && p->items)
2935 {
2936 s->cur_plugins = eina_list_append(s->cur_plugins, p);
2937 goto next;
2938 }
2939
2940 if (!((sel->states->next) ||
2941 ((CUR_SEL == SUBJ_SEL) &&
2942 (win->plugin_dedicated))))
2943 {
2944 /* skip plugins in toplevel which trigger-only */
2945 if ((sel == SUBJ_SEL) &&
2946 (p->config->top_level) &&
2947 (p->config->trigger_only))
2948 goto next;
2949
2950 /* skip non-toplevel plugins when input < min_query */
2951 if ((!p->config->top_level) &&
2952 ((size_t) p->config->min_query > len_inp))
2953 goto next;
2954 }
2955
2956 if (p->fetch(p, input))
2957 {
2958 #ifdef CHECK_TIME
2959 DBG("fetch %s %f", p->name, ecore_time_get() - _evry_time);
2960 #endif
2961 s->cur_plugins = eina_list_append(s->cur_plugins, p);
2962 continue;
2963 }
2964
2965 next:
2966 if (s->plugin == p)
2967 s->plugin = NULL;
2968 }
2969
2970 found:
2971 _evry_aggregator_fetch(s);
2972
2973 if (s->plugin_auto_selected)
2974 s->plugin = NULL;
2975
2976 _evry_plugin_select(s, s->plugin);
2977
2978 if (!s->plugin)
2979 return;
2980
2981 EINA_LIST_FOREACH (s->plugin->items, l, it)
2982 if (it->marked)
2983 s->sel_items = eina_list_append(s->sel_items, it);
2984 }
2985
2986 static void
_evry_item_desel(Evry_State * s)2987 _evry_item_desel(Evry_State *s)
2988 {
2989 Evry_Item *it = s->cur_item;
2990
2991 if (it)
2992 {
2993 it->selected = EINA_FALSE;
2994 evry_item_free(it);
2995 }
2996
2997 s->cur_item = NULL;
2998 }
2999
3000 static void
_evry_item_sel(Evry_State * s,Evry_Item * it)3001 _evry_item_sel(Evry_State *s, Evry_Item *it)
3002 {
3003 if (s->cur_item == it) return;
3004
3005 _evry_item_desel(s);
3006
3007 evry_item_ref(it);
3008 it->selected = EINA_TRUE;
3009
3010 s->cur_item = it;
3011 }
3012
3013 static void
_evry_plugin_select(Evry_State * s,Evry_Plugin * p)3014 _evry_plugin_select(Evry_State *s, Evry_Plugin *p)
3015 {
3016 if (!s) return;
3017
3018 if (p)
3019 {
3020 s->plugin_auto_selected = EINA_FALSE;
3021 }
3022 else
3023 {
3024 p = eina_list_data_get(s->cur_plugins);
3025 s->plugin_auto_selected = EINA_TRUE;
3026 }
3027
3028 s->plugin = p;
3029
3030 if ((s->view && s->plugin && s->plugin->view) &&
3031 (s->view->name != s->plugin->view->name))
3032 {
3033 s->view->destroy(s->view);
3034 s->view = NULL;
3035 if (_evry_view_create(s))
3036 {
3037 _evry_view_show(s->selector->win, s->view, 0);
3038 s->view->update(s->view);
3039 }
3040 }
3041 }
3042
3043 static void
_evry_cb_free_plugin_selected(void * data EINA_UNUSED,void * event)3044 _evry_cb_free_plugin_selected(void *data EINA_UNUSED, void *event)
3045 {
3046 Evry_Event_Item_Selected *ev = event;
3047
3048 evry_item_free(ev->item);
3049 E_FREE(ev);
3050 }
3051
3052 void
evry_plugin_select(Evry_Plugin * p)3053 evry_plugin_select(Evry_Plugin *p)
3054 {
3055 Evry_Event_Item_Selected *ev;
3056
3057 if (!p) return;
3058
3059 if (!p->state)
3060 {
3061 ERR("no state!");
3062 return;
3063 }
3064
3065 _evry_plugin_select(p->state, p);
3066 _evry_selector_update(p->state->selector);
3067
3068 ev = E_NEW(Evry_Event_Item_Selected, 1);
3069 ev->item = EVRY_ITEM(p);
3070 EVRY_ITEM_REF(p);
3071 ecore_event_add(_evry_events[EVRY_EVENT_PLUGIN_SELECTED], ev,
3072 _evry_cb_free_plugin_selected, NULL);
3073 }
3074
3075 static void
_evry_plugin_list_insert(Evry_State * s,Evry_Plugin * p)3076 _evry_plugin_list_insert(Evry_State *s, Evry_Plugin *p)
3077 {
3078 Eina_List *l;
3079 Evry_Plugin *p2;
3080
3081 EINA_LIST_FOREACH (s->cur_plugins, l, p2)
3082 {
3083 if (p == p2)
3084 return;
3085
3086 if (p->config->priority < p2->config->priority)
3087 break;
3088 }
3089
3090 if (l)
3091 s->cur_plugins = eina_list_prepend_relative_list(s->cur_plugins, p, l);
3092 else
3093 s->cur_plugins = eina_list_append(s->cur_plugins, p);
3094 }
3095
3096 static void
_evry_cb_show(Evry_Window * win,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info EINA_UNUSED)3097 _evry_cb_show(Evry_Window *win, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
3098 {
3099 if (win->grab)
3100 e_grabinput_get(elm_win_window_id_get(win->ewin), 0, elm_win_window_id_get(win->ewin));
3101 }
3102
3103 #ifndef HAVE_WAYLAND_ONLY
3104 static Eina_Bool
_evry_cb_selection_notify(void * data,int type EINA_UNUSED,void * event)3105 _evry_cb_selection_notify(void *data, int type EINA_UNUSED, void *event)
3106 {
3107 Ecore_X_Event_Selection_Notify *ev;
3108 Evry_Window *win = data;
3109 Evry_State *s = (CUR_SEL)->state;
3110
3111 if (!s || (data != win)) return ECORE_CALLBACK_PASS_ON;
3112 if (!win->request_selection) return ECORE_CALLBACK_PASS_ON;
3113
3114 win->request_selection = EINA_FALSE;
3115
3116 ev = event;
3117 if ((ev->selection == ECORE_X_SELECTION_CLIPBOARD) ||
3118 (ev->selection == ECORE_X_SELECTION_PRIMARY))
3119 {
3120 if (strcmp(ev->target, ECORE_X_SELECTION_TARGET_UTF8_STRING) == 0)
3121 {
3122 Ecore_X_Selection_Data_Text *text_data;
3123
3124 text_data = ev->data;
3125
3126 strncat(s->input, text_data->text, (INPUTLEN - strlen(s->input)) - 1);
3127 _evry_update(CUR_SEL, 1);
3128 }
3129 }
3130
3131 return ECORE_CALLBACK_PASS_ON;
3132 }
3133 #endif
3134
3135 void
evry_item_app_free(Evry_Item_App * app)3136 evry_item_app_free(Evry_Item_App *app)
3137 {
3138 efreet_desktop_free(app->desktop);
3139 eina_stringshare_del(app->file);
3140
3141 free(app);
3142 }
3143
3144 void
evry_item_file_free(Evry_Item_File * file)3145 evry_item_file_free(Evry_Item_File *file)
3146 {
3147 eina_stringshare_del(file->url);
3148 eina_stringshare_del(file->path);
3149 eina_stringshare_del(file->mime);
3150
3151 free(file);
3152 }
3153