3 #define TEXT_NONE_ACTION_KEY _("<None>")
4 #define TEXT_PRESS_KEY_SEQUENCE _("Please press key sequence,<br><br>" \
5 "or <hilight>Escape</hilight> to abort.")
7 #define TEXT_NO_PARAMS _("<None>")
8 #define TEXT_NO_MODIFIER_HEADER _("Single key")
10 static void *_create_data(E_Config_Dialog *cfd);
11 static void _free_data(E_Config_Dialog *cfd,
12 E_Config_Dialog_Data *cfdata);
13 static int _basic_apply_data(E_Config_Dialog *cfd,
14 E_Config_Dialog_Data *cfdata);
15 static Evas_Object *_basic_create_widgets(E_Config_Dialog *cfd,
17 E_Config_Dialog_Data *cfdata);
19 /********* private functions ***************/
20 static void _fill_actions_list(E_Config_Dialog_Data *cfdata);
22 /**************** Updates ***********/
23 static int _update_key_binding_list(E_Config_Dialog_Data *cfdata,
24 E_Config_Binding_Key *bi);
25 static void _update_action_list(E_Config_Dialog_Data *cfdata);
26 static void _update_action_params(E_Config_Dialog_Data *cfdata);
27 static void _update_buttons(E_Config_Dialog_Data *cfdata);
29 /**************** Callbacks *********/
30 static void _binding_change_cb(void *data);
31 static void _action_change_cb(void *data);
32 static void _delete_all_key_binding_cb(void *data,
34 static void _delete_key_binding_cb(void *data,
36 static void _restore_key_binding_defaults_cb(void *data,
38 static void _add_key_binding_cb(void *data,
40 static void _modify_key_binding_cb(void *data,
43 /********* Helper *************************/
44 static char *_key_binding_header_get(int modifiers);
45 static char *_key_binding_text_get(E_Config_Binding_Key *bi);
46 static void _auto_apply_changes(E_Config_Dialog_Data *cfdata);
47 static void _find_key_binding_action(const char *action,
53 /********* Sorting ************************/
54 static int _key_binding_sort_cb(const void *d1,
57 /**************** grab window *******/
58 static void _grab_wnd_show(E_Config_Dialog_Data *cfdata);
59 static Eina_Bool _grab_key_down_cb(void *data,
63 struct _E_Config_Dialog_Data
72 const char *binding, *action, *cur;
80 Evas_Object *o_add, *o_mod, *o_del, *o_del_all;
81 Evas_Object *o_binding_list, *o_action_list;
82 Evas_Object *o_params;
90 e_int_config_keybindings(E_Container *con,
94 E_Config_Dialog_View *v;
96 if (e_config_dialog_find("E", "keyboard_and_mouse/key_bindings")) return NULL;
97 v = E_NEW(E_Config_Dialog_View, 1);
99 v->create_cfdata = _create_data;
100 v->free_cfdata = _free_data;
101 v->basic.apply_cfdata = _basic_apply_data;
102 v->basic.create_widgets = _basic_create_widgets;
103 v->override_auto_apply = 1;
105 cfd = e_config_dialog_new(con, _("Key Bindings Settings"), "E",
106 "keyboard_and_mouse/key_bindings",
107 "preferences-desktop-keyboard-shortcuts", 0, v, NULL);
108 if ((params) && (params[0]))
110 cfd->cfdata->params = strdup(params);
111 _add_key_binding_cb(cfd->cfdata, NULL);
118 _fill_data(E_Config_Dialog_Data *cfdata)
121 E_Config_Binding_Key *bi, *bi2;
123 cfdata->locals.binding = eina_stringshare_add("");
124 cfdata->locals.action = eina_stringshare_add("");
125 cfdata->locals.params = strdup("");
126 cfdata->locals.cur = NULL;
127 cfdata->binding.key = NULL;
128 cfdata->locals.eg = NULL;
130 EINA_LIST_FOREACH(e_config->key_bindings, l, bi)
134 bi2 = E_NEW(E_Config_Binding_Key, 1);
135 bi2->context = bi->context;
136 bi2->key = eina_stringshare_add(bi->key);
137 bi2->modifiers = bi->modifiers;
138 bi2->any_mod = bi->any_mod;
139 bi2->action = eina_stringshare_ref(bi->action);
140 bi2->params = eina_stringshare_ref(bi->params);
142 cfdata->binding.key = eina_list_append(cfdata->binding.key, bi2);
147 _create_data(E_Config_Dialog *cfd)
149 E_Config_Dialog_Data *cfdata;
151 cfdata = E_NEW(E_Config_Dialog_Data, 1);
153 cfdata->locals.cur_act = -1;
160 _free_data(E_Config_Dialog *cfd __UNUSED__,
161 E_Config_Dialog_Data *cfdata)
163 E_Config_Binding_Key *bi;
165 EINA_LIST_FREE(cfdata->binding.key, bi)
167 eina_stringshare_del(bi->key);
168 eina_stringshare_del(bi->action);
169 eina_stringshare_del(bi->params);
173 eina_stringshare_del(cfdata->locals.cur);
174 eina_stringshare_del(cfdata->locals.binding);
175 eina_stringshare_del(cfdata->locals.action);
177 if (cfdata->locals.params) free(cfdata->locals.params);
178 if (cfdata->params) free(cfdata->params);
183 _basic_apply_data(E_Config_Dialog *cfd __UNUSED__,
184 E_Config_Dialog_Data *cfdata)
187 E_Config_Binding_Key *bi, *bi2;
189 _auto_apply_changes(cfdata);
191 e_managers_keys_ungrab();
192 EINA_LIST_FREE(e_config->key_bindings, bi)
194 e_bindings_key_del(bi->context, bi->key, bi->modifiers, bi->any_mod,
195 bi->action, bi->params);
196 if (bi->key) eina_stringshare_del(bi->key);
197 if (bi->action) eina_stringshare_del(bi->action);
198 if (bi->params) eina_stringshare_del(bi->params);
202 EINA_LIST_FOREACH(cfdata->binding.key, l, bi2)
206 if (!bi2->key || !bi2->key[0]) continue;
208 bi = E_NEW(E_Config_Binding_Key, 1);
209 bi->context = bi2->context;
210 bi->key = eina_stringshare_add(bi2->key);
211 bi->modifiers = bi2->modifiers;
212 bi->any_mod = bi2->any_mod;
214 ((!bi2->action) || (!bi2->action[0])) ? NULL : eina_stringshare_ref(bi2->action);
216 ((!bi2->params) || (!bi2->params[0])) ? NULL : eina_stringshare_ref(bi2->params);
218 e_config->key_bindings = eina_list_append(e_config->key_bindings, bi);
219 e_bindings_key_add(bi->context, bi->key, bi->modifiers, bi->any_mod,
220 bi->action, bi->params);
222 e_managers_keys_grab();
223 e_config_save_queue();
229 _basic_create_widgets(E_Config_Dialog *cfd,
231 E_Config_Dialog_Data *cfdata)
233 Evas_Object *o, *ot, *of, *ob;
236 o = e_widget_list_add(evas, 0, 1);
238 of = e_widget_frametable_add(evas, _("Key Bindings"), 0);
239 ob = e_widget_ilist_add(evas, 32, 32, &(cfdata->locals.binding));
240 cfdata->gui.o_binding_list = ob;
241 e_widget_size_min_set(ob, 200, 200);
242 e_widget_frametable_object_append(of, ob, 0, 0, 2, 1, 1, 1, 1, 1);
243 ob = e_widget_button_add(evas, _("Add"), "list-add", _add_key_binding_cb, cfdata, NULL);
244 cfdata->gui.o_add = ob;
245 e_widget_frametable_object_append(of, ob, 0, 1, 1, 1, 1, 0, 1, 0);
246 ob = e_widget_button_add(evas, _("Delete"), "list-remove", _delete_key_binding_cb, cfdata, NULL);
247 cfdata->gui.o_del = ob;
248 e_widget_disabled_set(ob, 1);
249 e_widget_frametable_object_append(of, ob, 1, 1, 1, 1, 1, 0, 1, 0);
250 ob = e_widget_button_add(evas, _("Modify"), NULL, _modify_key_binding_cb, cfdata, NULL);
251 cfdata->gui.o_mod = ob;
252 e_widget_disabled_set(ob, 1);
253 e_widget_frametable_object_append(of, ob, 0, 2, 1, 1, 1, 0, 1, 0);
254 ob = e_widget_button_add(evas, _("Delete All"), "edit-clear", _delete_all_key_binding_cb, cfdata, NULL);
255 cfdata->gui.o_del_all = ob;
256 e_widget_disabled_set(ob, 1);
257 e_widget_frametable_object_append(of, ob, 1, 2, 1, 1, 1, 0, 1, 0);
258 ob = e_widget_button_add(evas, _("Restore Default Bindings"), "enlightenment", _restore_key_binding_defaults_cb, cfdata, NULL);
259 e_widget_frametable_object_append(of, ob, 0, 3, 2, 1, 1, 0, 1, 0);
260 e_widget_list_object_append(o, of, 1, 1, 0.5);
262 ot = e_widget_table_add(evas, 0);
263 of = e_widget_framelist_add(evas, _("Action"), 0);
264 ob = e_widget_ilist_add(evas, 24, 24, &(cfdata->locals.action));
265 cfdata->gui.o_action_list = ob;
266 e_widget_size_min_set(ob, 200, 280);
267 e_widget_framelist_object_append(of, ob);
268 e_widget_table_object_append(ot, of, 0, 0, 1, 1, 1, 1, 1, 1);
270 of = e_widget_framelist_add(evas, _("Action Params"), 0);
271 ob = e_widget_entry_add(evas, &(cfdata->locals.params), NULL, NULL, NULL);
272 cfdata->gui.o_params = ob;
273 e_widget_disabled_set(ob, 1);
274 e_widget_framelist_object_append(of, ob);
275 e_widget_table_object_append(ot, of, 0, 1, 1, 1, 1, 1, 1, 0);
276 e_widget_list_object_append(o, ot, 1, 1, 0.5);
278 _update_key_binding_list(cfdata, NULL);
279 _fill_actions_list(cfdata);
281 e_dialog_resizable_set(cfd->dia, 1);
286 _fill_actions_list(E_Config_Dialog_Data *cfdata)
290 E_Action_Group *actg;
291 E_Action_Description *actd;
294 evas_event_freeze(evas_object_evas_get(cfdata->gui.o_action_list));
296 e_widget_ilist_freeze(cfdata->gui.o_action_list);
298 e_widget_ilist_clear(cfdata->gui.o_action_list);
299 for (l = e_action_groups_get(), g = 0; l; l = l->next, g++)
303 if (!actg->acts) continue;
305 e_widget_ilist_header_append(cfdata->gui.o_action_list, NULL, _(actg->act_grp));
307 for (l2 = actg->acts, a = 0; l2; l2 = l2->next, a++)
311 snprintf(buf, sizeof(buf), "%d %d", g, a);
312 e_widget_ilist_append(cfdata->gui.o_action_list, NULL, _(actd->act_name),
313 _action_change_cb, cfdata, buf);
316 e_widget_ilist_go(cfdata->gui.o_action_list);
317 e_widget_ilist_thaw(cfdata->gui.o_action_list);
319 evas_event_thaw(evas_object_evas_get(cfdata->gui.o_action_list));
322 /**************** Callbacks *********/
325 _add_key_binding_cb(void *data,
326 void *data2 __UNUSED__)
328 E_Config_Dialog_Data *cfdata;
332 _auto_apply_changes(cfdata);
334 cfdata->locals.add = 1;
335 _grab_wnd_show(cfdata);
339 _modify_key_binding_cb(void *data,
340 void *data2 __UNUSED__)
342 E_Config_Dialog_Data *cfdata;
346 _auto_apply_changes(cfdata);
348 cfdata->locals.add = 0;
349 _grab_wnd_show(cfdata);
353 _binding_change_cb(void *data)
355 E_Config_Dialog_Data *cfdata;
359 _auto_apply_changes(cfdata);
360 eina_stringshare_del(cfdata->locals.cur);
361 cfdata->locals.cur = NULL;
362 cfdata->locals.cur_act = -1;
364 if ((!cfdata->locals.binding) || (!cfdata->locals.binding[0])) return;
366 cfdata->locals.cur = eina_stringshare_add(cfdata->locals.binding);
368 _update_buttons(cfdata);
369 _update_action_list(cfdata);
373 _action_change_cb(void *data)
375 E_Config_Dialog_Data *cfdata;
378 _update_action_params(cfdata);
379 cfdata->locals.cur_act = e_widget_ilist_selected_get(cfdata->gui.o_action_list);
383 _delete_all_key_binding_cb(void *data,
384 void *data2 __UNUSED__)
386 E_Config_Binding_Key *bi;
387 E_Config_Dialog_Data *cfdata;
391 /* FIXME: need confirmation dialog */
392 EINA_LIST_FREE(cfdata->binding.key, bi)
394 eina_stringshare_del(bi->key);
395 eina_stringshare_del(bi->action);
396 eina_stringshare_del(bi->params);
400 eina_stringshare_del(cfdata->locals.cur);
401 cfdata->locals.cur = NULL;
403 e_widget_ilist_clear(cfdata->gui.o_binding_list);
404 e_widget_ilist_go(cfdata->gui.o_binding_list);
405 e_widget_ilist_unselect(cfdata->gui.o_action_list);
406 e_widget_entry_clear(cfdata->gui.o_params);
407 e_widget_disabled_set(cfdata->gui.o_params, 1);
409 _update_buttons(cfdata);
413 _delete_key_binding_cb(void *data,
414 void *data2 __UNUSED__)
419 E_Config_Dialog_Data *cfdata;
420 E_Config_Binding_Key *bi;
424 sel = e_widget_ilist_selected_get(cfdata->gui.o_binding_list);
425 if (cfdata->locals.binding[0] == 'k')
427 n = cfdata->locals.binding;
428 l = eina_list_nth_list(cfdata->binding.key, atoi(++n));
430 /* FIXME: need confirmation dialog */
433 bi = eina_list_data_get(l);
434 eina_stringshare_del(bi->key);
435 eina_stringshare_del(bi->action);
436 eina_stringshare_del(bi->params);
439 cfdata->binding.key = eina_list_remove_list(cfdata->binding.key, l);
443 _update_key_binding_list(cfdata, NULL);
445 if (sel >= e_widget_ilist_count(cfdata->gui.o_binding_list))
446 sel = e_widget_ilist_count(cfdata->gui.o_binding_list) - 1;
448 eina_stringshare_del(cfdata->locals.cur);
449 cfdata->locals.cur = NULL;
453 e_widget_ilist_unselect(cfdata->gui.o_action_list);
454 e_widget_entry_clear(cfdata->gui.o_params);
455 e_widget_disabled_set(cfdata->gui.o_params, 1);
456 _update_buttons(cfdata);
460 e_widget_ilist_selected_set(cfdata->gui.o_binding_list, sel);
461 e_widget_ilist_nth_show(cfdata->gui.o_binding_list, sel, 0);
466 _restore_key_binding_defaults_cb(void *data,
467 void *data2 __UNUSED__)
469 E_Config_Dialog_Data *cfdata;
470 E_Config_Binding_Key *bi;
474 EINA_LIST_FREE(cfdata->binding.key, bi)
476 eina_stringshare_del(bi->key);
477 eina_stringshare_del(bi->action);
478 eina_stringshare_del(bi->params);
482 #define CFG_KEYBIND_DFLT(_context, _key, _modifiers, _anymod, _action, _params) \
483 bi = E_NEW(E_Config_Binding_Key, 1); \
484 bi->context = _context; \
485 bi->key = eina_stringshare_add(_key); \
486 bi->modifiers = _modifiers; \
487 bi->any_mod = _anymod; \
488 bi->action = eina_stringshare_add(_action); \
489 bi->params = eina_stringshare_add(_params); \
490 cfdata->binding.key = eina_list_append(cfdata->binding.key, bi)
492 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "Left",
493 E_BINDING_MODIFIER_SHIFT | E_BINDING_MODIFIER_ALT, 0,
494 "desk_flip_by", "-1 0");
495 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "Right",
496 E_BINDING_MODIFIER_SHIFT | E_BINDING_MODIFIER_ALT, 0,
497 "desk_flip_by", "1 0");
498 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "Up",
499 E_BINDING_MODIFIER_SHIFT | E_BINDING_MODIFIER_ALT, 0,
500 "desk_flip_by", "0 -1");
501 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "Down",
502 E_BINDING_MODIFIER_SHIFT | E_BINDING_MODIFIER_ALT, 0,
503 "desk_flip_by", "0 1");
504 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "Up",
505 E_BINDING_MODIFIER_CTRL | E_BINDING_MODIFIER_ALT, 0,
506 "window_raise", NULL);
507 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "Down",
508 E_BINDING_MODIFIER_CTRL | E_BINDING_MODIFIER_ALT, 0,
509 "window_lower", NULL);
510 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "x",
511 E_BINDING_MODIFIER_CTRL | E_BINDING_MODIFIER_ALT, 0,
512 "window_close", NULL);
513 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "k",
514 E_BINDING_MODIFIER_CTRL | E_BINDING_MODIFIER_ALT, 0,
515 "window_kill", NULL);
516 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "w",
517 E_BINDING_MODIFIER_CTRL | E_BINDING_MODIFIER_ALT, 0,
518 "window_menu", NULL);
519 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "s",
520 E_BINDING_MODIFIER_CTRL | E_BINDING_MODIFIER_ALT, 0,
521 "window_sticky_toggle", NULL);
522 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "i",
523 E_BINDING_MODIFIER_CTRL | E_BINDING_MODIFIER_ALT, 0,
524 "window_iconic_toggle", NULL);
525 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "f",
526 E_BINDING_MODIFIER_CTRL | E_BINDING_MODIFIER_ALT, 0,
527 "window_maximized_toggle", NULL);
528 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "F10",
529 E_BINDING_MODIFIER_SHIFT, 0,
530 "window_maximized_toggle", "default vertical");
531 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "F10",
532 E_BINDING_MODIFIER_CTRL, 0,
533 "window_maximized_toggle", "default horizontal");
534 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "Left",
535 E_BINDING_MODIFIER_WIN, 0,
536 "window_maximized_toggle", "default left");
537 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "Right",
538 E_BINDING_MODIFIER_WIN, 0,
539 "window_maximized_toggle", "default right");
540 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "r",
541 E_BINDING_MODIFIER_CTRL | E_BINDING_MODIFIER_ALT, 0,
542 "window_shaded_toggle", NULL);
543 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "Left",
544 E_BINDING_MODIFIER_CTRL | E_BINDING_MODIFIER_ALT, 0,
545 "desk_linear_flip_by", "-1");
546 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "Right",
547 E_BINDING_MODIFIER_CTRL | E_BINDING_MODIFIER_ALT, 0,
548 "desk_linear_flip_by", "1");
549 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "F1",
550 E_BINDING_MODIFIER_ALT, 0,
551 "desk_linear_flip_to", "0");
552 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "F2",
553 E_BINDING_MODIFIER_ALT, 0,
554 "desk_linear_flip_to", "1");
555 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "F3",
556 E_BINDING_MODIFIER_ALT, 0,
557 "desk_linear_flip_to", "2");
558 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "F4",
559 E_BINDING_MODIFIER_ALT, 0,
560 "desk_linear_flip_to", "3");
561 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "F5",
562 E_BINDING_MODIFIER_ALT, 0,
563 "desk_linear_flip_to", "4");
564 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "F6",
565 E_BINDING_MODIFIER_ALT, 0,
566 "desk_linear_flip_to", "5");
567 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "F7",
568 E_BINDING_MODIFIER_ALT, 0,
569 "desk_linear_flip_to", "6");
570 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "F8",
571 E_BINDING_MODIFIER_ALT, 0,
572 "desk_linear_flip_to", "7");
573 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "F9",
574 E_BINDING_MODIFIER_ALT, 0,
575 "desk_linear_flip_to", "8");
576 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "F10",
577 E_BINDING_MODIFIER_ALT, 0,
578 "desk_linear_flip_to", "9");
579 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "F11",
580 E_BINDING_MODIFIER_ALT, 0,
581 "desk_linear_flip_to", "10");
582 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "F12",
583 E_BINDING_MODIFIER_ALT, 0,
584 "desk_linear_flip_to", "11");
585 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "m",
586 E_BINDING_MODIFIER_CTRL | E_BINDING_MODIFIER_ALT, 0,
587 "menu_show", "main");
588 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "a",
589 E_BINDING_MODIFIER_CTRL | E_BINDING_MODIFIER_ALT, 0,
590 "menu_show", "favorites");
591 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "Menu",
593 "menu_show", "main");
594 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "Menu",
595 E_BINDING_MODIFIER_CTRL, 0,
596 "menu_show", "clients");
597 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "Menu",
598 E_BINDING_MODIFIER_ALT, 0,
599 "menu_show", "favorites");
600 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "Insert",
601 E_BINDING_MODIFIER_CTRL | E_BINDING_MODIFIER_ALT, 0,
603 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "Tab",
604 E_BINDING_MODIFIER_ALT, 0,
606 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "Tab",
607 E_BINDING_MODIFIER_SHIFT | E_BINDING_MODIFIER_ALT, 0,
609 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "End",
610 E_BINDING_MODIFIER_CTRL | E_BINDING_MODIFIER_ALT, 0,
612 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "Delete",
613 E_BINDING_MODIFIER_CTRL | E_BINDING_MODIFIER_ALT, 0,
615 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "Escape",
616 E_BINDING_MODIFIER_ALT, 0,
618 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "l",
619 E_BINDING_MODIFIER_CTRL | E_BINDING_MODIFIER_ALT, 0,
621 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "d",
622 E_BINDING_MODIFIER_CTRL | E_BINDING_MODIFIER_ALT, 0,
623 "desk_deskshow_toggle", NULL);
624 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "Left",
625 E_BINDING_MODIFIER_CTRL | E_BINDING_MODIFIER_SHIFT, 0,
626 "screen_send_by", "-1");
627 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "Right",
628 E_BINDING_MODIFIER_CTRL | E_BINDING_MODIFIER_SHIFT, 0,
629 "screen_send_by", "1");
630 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "F1",
631 E_BINDING_MODIFIER_CTRL | E_BINDING_MODIFIER_SHIFT, 0,
632 "screen_send_to", "0");
633 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "F2",
634 E_BINDING_MODIFIER_CTRL | E_BINDING_MODIFIER_SHIFT, 0,
635 "screen_send_to", "1");
636 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "F3",
637 E_BINDING_MODIFIER_CTRL | E_BINDING_MODIFIER_SHIFT, 0,
638 "screen_send_to", "2");
639 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "F4",
640 E_BINDING_MODIFIER_CTRL | E_BINDING_MODIFIER_SHIFT, 0,
641 "screen_send_to", "3");
643 eina_stringshare_del(cfdata->locals.cur);
644 cfdata->locals.cur = NULL;
646 _update_key_binding_list(cfdata, NULL);
647 _update_buttons(cfdata);
649 e_widget_ilist_unselect(cfdata->gui.o_action_list);
650 e_widget_entry_clear(cfdata->gui.o_params);
651 e_widget_disabled_set(cfdata->gui.o_params, 1);
654 /**************** Updates ***********/
656 _update_action_list(E_Config_Dialog_Data *cfdata)
658 E_Config_Binding_Key *bi;
659 int j = -1, i, n, cnt;
660 const char *action, *params;
662 if (!cfdata->locals.cur) return;
664 if (cfdata->locals.cur[0] == 'k')
666 sscanf(cfdata->locals.cur, "k%d", &n);
667 bi = eina_list_nth(cfdata->binding.key, n);
670 e_widget_ilist_unselect(cfdata->gui.o_action_list);
671 e_widget_entry_clear(cfdata->gui.o_params);
672 e_widget_disabled_set(cfdata->gui.o_params, 1);
681 _find_key_binding_action(action, params, NULL, NULL, &j);
685 cnt = e_widget_ilist_count(cfdata->gui.o_action_list);
686 for (i = 0; i < cnt; i++)
689 if (e_widget_ilist_nth_is_header(cfdata->gui.o_action_list, i)) j++;
695 if (j == e_widget_ilist_selected_get(cfdata->gui.o_action_list))
696 _update_action_params(cfdata);
698 e_widget_ilist_selected_set(cfdata->gui.o_action_list, j);
702 e_widget_ilist_unselect(cfdata->gui.o_action_list);
703 eina_stringshare_del(cfdata->locals.action);
704 cfdata->locals.action = eina_stringshare_add("");
705 e_widget_entry_clear(cfdata->gui.o_params);
708 /*if (cfdata->locals.cur[0] == 'k')
710 sscanf(cfdata->locals.cur, "k%d", &n);
711 bi = eina_list_nth(cfdata->binding.key, n);
714 e_widget_ilist_unselect(cfdata->gui.o_action_list);
715 e_widget_entry_clear(cfdata->gui.o_params);
716 e_widget_disabled_set(cfdata->gui.o_params, 1);
720 _find_key_binding_action(bi, NULL, NULL, &j);
723 for (i = 0; i < e_widget_ilist_count(cfdata->gui.o_action_list); i++)
726 if (e_widget_ilist_nth_is_header(cfdata->gui.o_action_list, i)) j++;
732 if (j == e_widget_ilist_selected_get(cfdata->gui.o_action_list))
733 _update_action_params(cfdata);
735 e_widget_ilist_selected_set(cfdata->gui.o_action_list, j);
739 e_widget_ilist_unselect(cfdata->gui.o_action_list);
740 if (cfdata->locals.action) free(cfdata->locals.action);
741 cfdata->locals.action = strdup("");
742 e_widget_entry_clear(cfdata->gui.o_params);
748 _update_action_params(E_Config_Dialog_Data *cfdata)
751 E_Action_Group *actg;
752 E_Action_Description *actd;
753 E_Config_Binding_Key *bi;
754 const char *action, *params;
756 #define KB_EXAMPLE_PARAMS \
757 if ((!actd->param_example) || (!actd->param_example[0])) \
758 e_widget_entry_text_set(cfdata->gui.o_params, TEXT_NO_PARAMS); \
760 e_widget_entry_text_set(cfdata->gui.o_params, actd->param_example)
762 if ((!cfdata->locals.action) || (!cfdata->locals.action[0]))
764 e_widget_disabled_set(cfdata->gui.o_params, 1);
765 e_widget_entry_clear(cfdata->gui.o_params);
768 sscanf(cfdata->locals.action, "%d %d", &g, &a);
770 actg = eina_list_nth(e_action_groups_get(), g);
772 actd = eina_list_nth(actg->acts, a);
775 if (actd->act_params)
777 e_widget_disabled_set(cfdata->gui.o_params, 1);
778 e_widget_entry_text_set(cfdata->gui.o_params, actd->act_params);
782 if ((!cfdata->locals.cur) || (!cfdata->locals.cur[0]))
784 e_widget_disabled_set(cfdata->gui.o_params, 1);
790 e_widget_disabled_set(cfdata->gui.o_params, 1);
792 e_widget_disabled_set(cfdata->gui.o_params, 0);
794 if (cfdata->locals.cur[0] == 'k')
796 sscanf(cfdata->locals.cur, "k%d", &b);
797 bi = eina_list_nth(cfdata->binding.key, b);
800 e_widget_disabled_set(cfdata->gui.o_params, 1);
809 e_widget_disabled_set(cfdata->gui.o_params, 1);
816 if (!e_util_strcmp(action, actd->act_cmd))
818 if ((cfdata->locals.cur_act >= 0) && (cfdata->locals.cur_act != e_widget_ilist_selected_get(cfdata->gui.o_action_list)))
821 e_widget_entry_text_set(cfdata->gui.o_params, params);
831 _update_key_binding_list(E_Config_Dialog_Data *cfdata,
832 E_Config_Binding_Key *bi_new)
837 E_Config_Binding_Key *bi;
842 evas_event_freeze(evas_object_evas_get(cfdata->gui.o_binding_list));
844 e_widget_ilist_freeze(cfdata->gui.o_binding_list);
846 e_widget_ilist_clear(cfdata->gui.o_binding_list);
847 e_widget_ilist_go(cfdata->gui.o_binding_list);
849 if (cfdata->binding.key)
851 cfdata->binding.key = eina_list_sort(cfdata->binding.key,
852 eina_list_count(cfdata->binding.key), _key_binding_sort_cb);
855 for (l = cfdata->binding.key, i = 0; l; l = l->next, i++)
858 if (bi == bi_new) ret = bi_pos;
859 if (ret < 0) bi_pos++;
861 if (modifiers != (int)bi->modifiers)
863 modifiers = bi->modifiers;
864 b = _key_binding_header_get(modifiers);
867 if (ret < 0) bi_pos++;
868 e_widget_ilist_header_append(cfdata->gui.o_binding_list, NULL, b);
873 b = _key_binding_text_get(bi);
876 snprintf(b2, sizeof(b2), "k%d", i);
877 e_widget_ilist_append(cfdata->gui.o_binding_list, NULL, b,
878 _binding_change_cb, cfdata, b2);
881 e_widget_ilist_go(cfdata->gui.o_binding_list);
883 e_widget_ilist_thaw(cfdata->gui.o_binding_list);
885 evas_event_thaw(evas_object_evas_get(cfdata->gui.o_binding_list));
887 if (eina_list_count(cfdata->binding.key))
888 e_widget_disabled_set(cfdata->gui.o_del_all, 0);
890 e_widget_disabled_set(cfdata->gui.o_del_all, 1);
896 _update_buttons(E_Config_Dialog_Data *cfdata)
898 if (e_widget_ilist_count(cfdata->gui.o_binding_list))
899 e_widget_disabled_set(cfdata->gui.o_del_all, 0);
901 e_widget_disabled_set(cfdata->gui.o_del_all, 1);
903 if (!cfdata->locals.cur)
905 e_widget_disabled_set(cfdata->gui.o_mod, 1);
906 e_widget_disabled_set(cfdata->gui.o_del, 1);
909 e_widget_disabled_set(cfdata->gui.o_mod, 0);
910 e_widget_disabled_set(cfdata->gui.o_del, 0);
913 /*************** Sorting *****************************/
915 _key_binding_sort_cb(const void *d1,
919 const E_Config_Binding_Key *bi, *bi2;
925 if (bi->modifiers & E_BINDING_MODIFIER_CTRL) i++;
926 if (bi->modifiers & E_BINDING_MODIFIER_ALT) i++;
927 if (bi->modifiers & E_BINDING_MODIFIER_SHIFT) i++;
928 if (bi->modifiers & E_BINDING_MODIFIER_WIN) i++;
930 if (bi2->modifiers & E_BINDING_MODIFIER_CTRL) j++;
931 if (bi2->modifiers & E_BINDING_MODIFIER_ALT) j++;
932 if (bi2->modifiers & E_BINDING_MODIFIER_SHIFT) j++;
933 if (bi2->modifiers & E_BINDING_MODIFIER_WIN) j++;
935 if (i < j) return -1;
939 if (bi->modifiers < bi2->modifiers) return -1;
940 else if (bi->modifiers > bi2->modifiers)
943 i = strlen(bi->key ? bi->key : "");
944 j = strlen(bi2->key ? bi2->key : "");
946 if (i < j) return -1;
950 i = e_util_strcmp(bi->key, bi2->key);
951 if (i < 0) return -1;
958 /**************** grab window *******/
961 _grab_wnd_hide(void *data)
963 E_Config_Dialog_Data *cfdata;
965 cfdata = e_object_data_get(data);
966 cfdata->locals.eg = NULL;
970 _grab_wnd_show(E_Config_Dialog_Data *cfdata)
972 if (cfdata->locals.eg) return;
973 cfdata->locals.eg = e_grab_dialog_show(cfdata->cfd->dia->win, EINA_FALSE, _grab_key_down_cb, NULL, NULL, cfdata);
974 e_object_data_set(E_OBJECT(cfdata->locals.eg), cfdata);
975 e_object_del_attach_func_set(E_OBJECT(cfdata->locals.eg), _grab_wnd_hide);
979 _grab_key_down_cb(void *data,
983 E_Config_Dialog_Data *cfdata;
989 if ((ev->keyname) && (ev->key) && (ev->compose))
990 printf("'%s' '%s' '%s'\n", ev->keyname, ev->key, ev->compose);
991 else if ((ev->keyname) && (ev->key))
992 printf("'%s' '%s'\n", ev->keyname, ev->key);
994 printf("unknown key!!!!\n");
995 if (!e_util_strcmp(ev->keyname, "Control_L") || !e_util_strcmp(ev->keyname, "Control_R") ||
996 !e_util_strcmp(ev->keyname, "Shift_L") || !e_util_strcmp(ev->keyname, "Shift_R") ||
997 !e_util_strcmp(ev->keyname, "Alt_L") || !e_util_strcmp(ev->keyname, "Alt_R") ||
998 !e_util_strcmp(ev->keyname, "Super_L") || !e_util_strcmp(ev->keyname, "Super_R"))
1004 E_Config_Binding_Key *bi = NULL;
1005 const Eina_List *l = NULL;
1006 unsigned int mod = E_BINDING_MODIFIER_NONE;
1007 unsigned int n, found = 0;
1009 if (ev->modifiers & ECORE_EVENT_MODIFIER_SHIFT)
1010 mod |= E_BINDING_MODIFIER_SHIFT;
1011 if (ev->modifiers & ECORE_EVENT_MODIFIER_CTRL)
1012 mod |= E_BINDING_MODIFIER_CTRL;
1013 if (ev->modifiers & ECORE_EVENT_MODIFIER_ALT)
1014 mod |= E_BINDING_MODIFIER_ALT;
1015 if (ev->modifiers & ECORE_EVENT_MODIFIER_WIN)
1016 mod |= E_BINDING_MODIFIER_WIN;
1018 if (cfdata->locals.add)
1019 found = !!e_util_binding_match(cfdata->binding.key, ev, &n, NULL);
1020 else if (cfdata->locals.cur && cfdata->locals.cur[0])
1022 sscanf(cfdata->locals.cur, "k%d", &n);
1023 bi = eina_list_nth(cfdata->binding.key, n);
1024 found = !!e_util_binding_match(cfdata->binding.key, ev, &n, bi);
1029 if (cfdata->locals.add)
1031 bi = E_NEW(E_Config_Binding_Key, 1);
1033 bi->context = E_BINDING_CONTEXT_ANY;
1034 bi->modifiers = mod;
1035 bi->key = eina_stringshare_add(ev->keyname);
1040 cfdata->binding.key = eina_list_append(cfdata->binding.key, bi);
1042 n = _update_key_binding_list(cfdata, bi);
1044 e_widget_ilist_selected_set(cfdata->gui.o_binding_list, n);
1045 e_widget_ilist_nth_show(cfdata->gui.o_binding_list, n, 0);
1046 e_widget_ilist_unselect(cfdata->gui.o_action_list);
1047 eina_stringshare_del(cfdata->locals.action);
1048 cfdata->locals.action = eina_stringshare_add("");
1049 if ((cfdata->params) && (cfdata->params[0]))
1052 _find_key_binding_action("exec", NULL, &g, NULL, &j);
1055 e_widget_ilist_unselect(cfdata->gui.o_action_list);
1056 e_widget_ilist_selected_set(cfdata->gui.o_action_list, (j + g + 1));
1057 e_widget_entry_clear(cfdata->gui.o_params);
1058 e_widget_entry_text_set(cfdata->gui.o_params, cfdata->params);
1063 e_widget_entry_clear(cfdata->gui.o_params);
1064 e_widget_disabled_set(cfdata->gui.o_params, 1);
1067 else if (cfdata->locals.cur && cfdata->locals.cur[0])
1073 sscanf(cfdata->locals.cur, "k%d", &n);
1074 bi = eina_list_nth(cfdata->binding.key, n);
1076 bi->modifiers = mod;
1077 if (bi->key) eina_stringshare_del(bi->key);
1078 bi->key = eina_stringshare_add(ev->keyname);
1081 label = _key_binding_text_get(bi);
1083 EINA_LIST_FOREACH(e_widget_ilist_items_get(cfdata->gui.o_binding_list), l, it)
1085 if (it->header) n++;
1086 if (i++ >= n) break;
1089 e_widget_ilist_nth_label_set(cfdata->gui.o_binding_list, n, label);
1098 /* this advice is rather irritating as one sees that the
1099 key is bound to an action. if you want to set a
1100 keybinding you dont care about whether there is
1101 sth else set to it. */
1103 const char *label = NULL;
1104 E_Action_Group *actg = NULL;
1105 E_Action_Description *actd = NULL;
1107 if (cfdata->locals.add)
1108 _find_key_binding_action(bi->action, bi->params, &g, &a, &j);
1110 _find_key_binding_action(bi2->action, bi2->params, &g, &a, &j);
1112 actg = eina_list_nth(e_action_groups_get(), g);
1113 if (actg) actd = eina_list_nth(actg->acts, a);
1115 if (actd) label = _(actd->act_name);
1117 e_util_dialog_show(_("Binding Key Error"),
1118 _("The binding key sequence, that you choose,"
1119 " is already used by <br>"
1120 "<hilight>%s</hilight> action.<br>"
1121 "Please choose another binding key sequence."),
1122 label ? label : _("Unknown"));
1124 EINA_LIST_FOREACH(e_widget_ilist_items_get(cfdata->gui.o_binding_list), l, it)
1126 if (it->header) n++;
1127 if (i++ >= n) break;
1130 e_widget_ilist_nth_show(cfdata->gui.o_binding_list, n - 1, 1);
1131 e_widget_ilist_selected_set(cfdata->gui.o_binding_list, n - 1);
1133 e_object_del(E_OBJECT(cfdata->locals.eg));
1135 return ECORE_CALLBACK_PASS_ON;
1139 /********** Helper *********************************/
1141 _auto_apply_changes(E_Config_Dialog_Data *cfdata)
1144 E_Config_Binding_Key *bi;
1145 E_Action_Group *actg;
1146 E_Action_Description *actd;
1148 if ((!cfdata->locals.cur) || (!cfdata->locals.cur[0]) ||
1149 (!cfdata->locals.action) || (!cfdata->locals.action[0])) return;
1151 sscanf(cfdata->locals.cur, "k%d", &n);
1152 sscanf(cfdata->locals.action, "%d %d", &g, &a);
1154 bi = eina_list_nth(cfdata->binding.key, n);
1157 actg = eina_list_nth(e_action_groups_get(), g);
1159 actd = eina_list_nth(actg->acts, a);
1162 eina_stringshare_del(bi->action);
1165 if (actd->act_cmd) bi->action = eina_stringshare_add(actd->act_cmd);
1167 eina_stringshare_del(bi->params);
1170 if (actd->act_params)
1171 bi->params = eina_stringshare_add(actd->act_params);
1175 if (cfdata->locals.params)
1177 if (!e_util_strcmp(cfdata->locals.params, TEXT_NO_PARAMS))
1180 if ((actd->param_example) && (!e_util_strcmp(cfdata->locals.params, actd->param_example)))
1187 bi->params = eina_stringshare_add(cfdata->locals.params);
1192 _find_key_binding_action(const char *action,
1199 int gg = -1, aa = -1, nn = -1, found;
1200 E_Action_Group *actg;
1201 E_Action_Description *actd;
1208 for (l = e_action_groups_get(), gg = 0, nn = 0; l; l = l->next, gg++)
1212 for (l2 = actg->acts, aa = 0; l2; l2 = l2->next, aa++)
1215 if (!e_util_strcmp((!action ? "" : action), (!actd->act_cmd ? "" : actd->act_cmd)))
1217 if (!params || !params[0])
1219 if ((!actd->act_params) || (!actd->act_params[0]))
1231 if ((!actd->act_params) || (!actd->act_params[0]))
1240 if (!e_util_strcmp(params, actd->act_params))
1264 _key_binding_header_get(int modifiers)
1268 if (modifiers & E_BINDING_MODIFIER_CTRL)
1269 strcat(b, _("CTRL"));
1271 if (modifiers & E_BINDING_MODIFIER_ALT)
1273 if (b[0]) strcat(b, " + ");
1274 strcat(b, _("ALT"));
1277 if (modifiers & E_BINDING_MODIFIER_SHIFT)
1279 if (b[0]) strcat(b, " + ");
1280 strcat(b, _("SHIFT"));
1283 if (modifiers & E_BINDING_MODIFIER_WIN)
1285 if (b[0]) strcat(b, " + ");
1286 strcat(b, _("WIN"));
1289 if (!b[0]) return strdup(TEXT_NO_MODIFIER_HEADER);
1294 _key_binding_text_get(E_Config_Binding_Key *bi)
1298 if (!bi) return NULL;
1300 if (bi->modifiers & E_BINDING_MODIFIER_CTRL)
1301 strcat(b, _("CTRL"));
1303 if (bi->modifiers & E_BINDING_MODIFIER_ALT)
1305 if (b[0]) strcat(b, " + ");
1306 strcat(b, _("ALT"));
1309 if (bi->modifiers & E_BINDING_MODIFIER_SHIFT)
1311 if (b[0]) strcat(b, " + ");
1312 strcat(b, _("SHIFT"));
1315 if (bi->modifiers & E_BINDING_MODIFIER_WIN)
1317 if (b[0]) strcat(b, " + ");
1318 strcat(b, _("WIN"));
1321 if (bi->key && bi->key[0])
1324 if (b[0]) strcat(b, " + ");
1326 l = strdup(bi->key);
1327 l[0] = (char)toupper(bi->key[0]);
1332 /* see comment in e_bindings on numlock
1333 if (bi->modifiers & ECORE_X_LOCK_NUM)
1335 if (b[0]) strcat(b, " ");
1336 strcat(b, _("OFF"));
1340 if (!b[0]) return strdup(TEXT_NONE_ACTION_KEY);