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,
62 static Eina_Bool _grab_mouse_dumb_cb(void *data,
66 struct _E_Config_Dialog_Data
75 const char *binding, *action, *cur;
80 Ecore_X_Window bind_win;
85 Evas_Object *o_add, *o_mod, *o_del, *o_del_all;
86 Evas_Object *o_binding_list, *o_action_list;
87 Evas_Object *o_params;
95 e_int_config_keybindings(E_Container *con,
99 E_Config_Dialog_View *v;
101 if (e_config_dialog_find("E", "keyboard_and_mouse/key_bindings")) return NULL;
102 v = E_NEW(E_Config_Dialog_View, 1);
104 v->create_cfdata = _create_data;
105 v->free_cfdata = _free_data;
106 v->basic.apply_cfdata = _basic_apply_data;
107 v->basic.create_widgets = _basic_create_widgets;
108 v->override_auto_apply = 1;
110 cfd = e_config_dialog_new(con, _("Key Bindings Settings"), "E",
111 "keyboard_and_mouse/key_bindings",
112 "preferences-desktop-keyboard-shortcuts", 0, v, NULL);
113 if ((params) && (params[0]))
115 cfd->cfdata->params = strdup(params);
116 _add_key_binding_cb(cfd->cfdata, NULL);
123 _fill_data(E_Config_Dialog_Data *cfdata)
126 E_Config_Binding_Key *bi, *bi2;
128 cfdata->locals.binding = eina_stringshare_add("");
129 cfdata->locals.action = eina_stringshare_add("");
130 cfdata->locals.params = strdup("");
131 cfdata->locals.cur = NULL;
132 cfdata->binding.key = NULL;
133 cfdata->locals.bind_win = 0;
134 cfdata->locals.handlers = NULL;
135 cfdata->locals.dia = NULL;
137 EINA_LIST_FOREACH(e_config->key_bindings, l, bi)
141 bi2 = E_NEW(E_Config_Binding_Key, 1);
142 bi2->context = bi->context;
143 bi2->key = eina_stringshare_add(bi->key);
144 bi2->modifiers = bi->modifiers;
145 bi2->any_mod = bi->any_mod;
146 bi2->action = eina_stringshare_ref(bi->action);
147 bi2->params = eina_stringshare_ref(bi->params);
149 cfdata->binding.key = eina_list_append(cfdata->binding.key, bi2);
154 _create_data(E_Config_Dialog *cfd)
156 E_Config_Dialog_Data *cfdata;
158 cfdata = E_NEW(E_Config_Dialog_Data, 1);
166 _free_data(E_Config_Dialog *cfd __UNUSED__,
167 E_Config_Dialog_Data *cfdata)
169 E_Config_Binding_Key *bi;
171 EINA_LIST_FREE(cfdata->binding.key, bi)
173 eina_stringshare_del(bi->key);
174 eina_stringshare_del(bi->action);
175 eina_stringshare_del(bi->params);
179 eina_stringshare_del(cfdata->locals.cur);
180 eina_stringshare_del(cfdata->locals.binding);
181 eina_stringshare_del(cfdata->locals.action);
183 if (cfdata->locals.params) free(cfdata->locals.params);
184 if (cfdata->params) free(cfdata->params);
189 _basic_apply_data(E_Config_Dialog *cfd __UNUSED__,
190 E_Config_Dialog_Data *cfdata)
193 E_Config_Binding_Key *bi, *bi2;
195 _auto_apply_changes(cfdata);
197 e_managers_keys_ungrab();
198 EINA_LIST_FREE(e_config->key_bindings, bi)
200 e_bindings_key_del(bi->context, bi->key, bi->modifiers, bi->any_mod,
201 bi->action, bi->params);
202 if (bi->key) eina_stringshare_del(bi->key);
203 if (bi->action) eina_stringshare_del(bi->action);
204 if (bi->params) eina_stringshare_del(bi->params);
208 EINA_LIST_FOREACH(cfdata->binding.key, l, bi2)
212 if (!bi2->key || !bi2->key[0]) continue;
214 bi = E_NEW(E_Config_Binding_Key, 1);
215 bi->context = bi2->context;
216 bi->key = eina_stringshare_add(bi2->key);
217 bi->modifiers = bi2->modifiers;
218 bi->any_mod = bi2->any_mod;
220 ((!bi2->action) || (!bi2->action[0])) ? NULL : eina_stringshare_ref(bi2->action);
222 ((!bi2->params) || (!bi2->params[0])) ? NULL : eina_stringshare_ref(bi2->params);
224 e_config->key_bindings = eina_list_append(e_config->key_bindings, bi);
225 e_bindings_key_add(bi->context, bi->key, bi->modifiers, bi->any_mod,
226 bi->action, bi->params);
228 e_managers_keys_grab();
229 e_config_save_queue();
235 _basic_create_widgets(E_Config_Dialog *cfd,
237 E_Config_Dialog_Data *cfdata)
239 Evas_Object *o, *ot, *of, *ob;
242 o = e_widget_list_add(evas, 0, 1);
244 of = e_widget_frametable_add(evas, _("Key Bindings"), 0);
245 ob = e_widget_ilist_add(evas, 32, 32, &(cfdata->locals.binding));
246 cfdata->gui.o_binding_list = ob;
247 e_widget_size_min_set(ob, 200, 200);
248 e_widget_frametable_object_append(of, ob, 0, 0, 2, 1, 1, 1, 1, 1);
249 ob = e_widget_button_add(evas, _("Add Binding"), "list-add", _add_key_binding_cb, cfdata, NULL);
250 cfdata->gui.o_add = ob;
251 e_widget_frametable_object_append(of, ob, 0, 1, 1, 1, 1, 0, 1, 0);
252 ob = e_widget_button_add(evas, _("Delete Binding"), "list-remove", _delete_key_binding_cb, cfdata, NULL);
253 cfdata->gui.o_del = ob;
254 e_widget_disabled_set(ob, 1);
255 e_widget_frametable_object_append(of, ob, 1, 1, 1, 1, 1, 0, 1, 0);
256 ob = e_widget_button_add(evas, _("Modify Binding"), NULL, _modify_key_binding_cb, cfdata, NULL);
257 cfdata->gui.o_mod = ob;
258 e_widget_disabled_set(ob, 1);
259 e_widget_frametable_object_append(of, ob, 0, 2, 1, 1, 1, 0, 1, 0);
260 ob = e_widget_button_add(evas, _("Delete All"), NULL, _delete_all_key_binding_cb, cfdata, NULL);
261 cfdata->gui.o_del_all = ob;
262 e_widget_disabled_set(ob, 1);
263 e_widget_frametable_object_append(of, ob, 1, 2, 1, 1, 1, 0, 1, 0);
264 ob = e_widget_button_add(evas, _("Restore Default Bindings"), "enlightenment", _restore_key_binding_defaults_cb, cfdata, NULL);
265 e_widget_frametable_object_append(of, ob, 0, 3, 2, 1, 1, 0, 1, 0);
266 e_widget_list_object_append(o, of, 1, 1, 0.5);
268 ot = e_widget_table_add(evas, 0);
269 of = e_widget_framelist_add(evas, _("Action"), 0);
270 ob = e_widget_ilist_add(evas, 24, 24, &(cfdata->locals.action));
271 cfdata->gui.o_action_list = ob;
272 e_widget_size_min_set(ob, 200, 280);
273 e_widget_framelist_object_append(of, ob);
274 e_widget_table_object_append(ot, of, 0, 0, 1, 1, 1, 1, 1, 1);
276 of = e_widget_framelist_add(evas, _("Action Params"), 0);
277 ob = e_widget_entry_add(evas, &(cfdata->locals.params), NULL, NULL, NULL);
278 cfdata->gui.o_params = ob;
279 e_widget_disabled_set(ob, 1);
280 e_widget_framelist_object_append(of, ob);
281 e_widget_table_object_append(ot, of, 0, 1, 1, 1, 1, 1, 1, 0);
282 e_widget_list_object_append(o, ot, 1, 1, 0.5);
284 _update_key_binding_list(cfdata, NULL);
285 _fill_actions_list(cfdata);
287 e_dialog_resizable_set(cfd->dia, 1);
292 _fill_actions_list(E_Config_Dialog_Data *cfdata)
296 E_Action_Group *actg;
297 E_Action_Description *actd;
300 evas_event_freeze(evas_object_evas_get(cfdata->gui.o_action_list));
302 e_widget_ilist_freeze(cfdata->gui.o_action_list);
304 e_widget_ilist_clear(cfdata->gui.o_action_list);
305 for (l = e_action_groups_get(), g = 0; l; l = l->next, g++)
309 if (!actg->acts) continue;
311 e_widget_ilist_header_append(cfdata->gui.o_action_list, NULL, _(actg->act_grp));
313 for (l2 = actg->acts, a = 0; l2; l2 = l2->next, a++)
317 snprintf(buf, sizeof(buf), "%d %d", g, a);
318 e_widget_ilist_append(cfdata->gui.o_action_list, NULL, _(actd->act_name),
319 _action_change_cb, cfdata, buf);
322 e_widget_ilist_go(cfdata->gui.o_action_list);
323 e_widget_ilist_thaw(cfdata->gui.o_action_list);
325 evas_event_thaw(evas_object_evas_get(cfdata->gui.o_action_list));
328 /**************** Callbacks *********/
331 _add_key_binding_cb(void *data,
332 void *data2 __UNUSED__)
334 E_Config_Dialog_Data *cfdata;
338 _auto_apply_changes(cfdata);
340 cfdata->locals.add = 1;
341 _grab_wnd_show(cfdata);
345 _modify_key_binding_cb(void *data,
346 void *data2 __UNUSED__)
348 E_Config_Dialog_Data *cfdata;
352 _auto_apply_changes(cfdata);
354 cfdata->locals.add = 0;
355 _grab_wnd_show(cfdata);
359 _binding_change_cb(void *data)
361 E_Config_Dialog_Data *cfdata;
365 _auto_apply_changes(cfdata);
366 eina_stringshare_del(cfdata->locals.cur);
367 cfdata->locals.cur = NULL;
369 if ((!cfdata->locals.binding) || (!cfdata->locals.binding[0])) return;
371 cfdata->locals.cur = eina_stringshare_add(cfdata->locals.binding);
373 _update_buttons(cfdata);
374 _update_action_list(cfdata);
378 _action_change_cb(void *data)
380 E_Config_Dialog_Data *cfdata;
383 _update_action_params(cfdata);
387 _delete_all_key_binding_cb(void *data,
388 void *data2 __UNUSED__)
390 E_Config_Binding_Key *bi;
391 E_Config_Dialog_Data *cfdata;
395 /* FIXME: need confirmation dialog */
396 EINA_LIST_FREE(cfdata->binding.key, bi)
398 eina_stringshare_del(bi->key);
399 eina_stringshare_del(bi->action);
400 eina_stringshare_del(bi->params);
404 eina_stringshare_del(cfdata->locals.cur);
405 cfdata->locals.cur = NULL;
407 e_widget_ilist_clear(cfdata->gui.o_binding_list);
408 e_widget_ilist_go(cfdata->gui.o_binding_list);
409 e_widget_ilist_unselect(cfdata->gui.o_action_list);
410 e_widget_entry_clear(cfdata->gui.o_params);
411 e_widget_disabled_set(cfdata->gui.o_params, 1);
413 _update_buttons(cfdata);
417 _delete_key_binding_cb(void *data,
418 void *data2 __UNUSED__)
423 E_Config_Dialog_Data *cfdata;
424 E_Config_Binding_Key *bi;
428 sel = e_widget_ilist_selected_get(cfdata->gui.o_binding_list);
429 if (cfdata->locals.binding[0] == 'k')
431 n = cfdata->locals.binding;
432 l = eina_list_nth_list(cfdata->binding.key, atoi(++n));
434 /* FIXME: need confirmation dialog */
437 bi = eina_list_data_get(l);
438 eina_stringshare_del(bi->key);
439 eina_stringshare_del(bi->action);
440 eina_stringshare_del(bi->params);
443 cfdata->binding.key = eina_list_remove_list(cfdata->binding.key, l);
447 _update_key_binding_list(cfdata, NULL);
449 if (sel >= e_widget_ilist_count(cfdata->gui.o_binding_list))
450 sel = e_widget_ilist_count(cfdata->gui.o_binding_list) - 1;
452 eina_stringshare_del(cfdata->locals.cur);
453 cfdata->locals.cur = NULL;
457 e_widget_ilist_unselect(cfdata->gui.o_action_list);
458 e_widget_entry_clear(cfdata->gui.o_params);
459 e_widget_disabled_set(cfdata->gui.o_params, 1);
460 _update_buttons(cfdata);
464 e_widget_ilist_selected_set(cfdata->gui.o_binding_list, sel);
465 e_widget_ilist_nth_show(cfdata->gui.o_binding_list, sel, 0);
470 _restore_key_binding_defaults_cb(void *data,
471 void *data2 __UNUSED__)
473 E_Config_Dialog_Data *cfdata;
474 E_Config_Binding_Key *bi;
478 EINA_LIST_FREE(cfdata->binding.key, bi)
480 eina_stringshare_del(bi->key);
481 eina_stringshare_del(bi->action);
482 eina_stringshare_del(bi->params);
486 #define CFG_KEYBIND_DFLT(_context, _key, _modifiers, _anymod, _action, _params) \
487 bi = E_NEW(E_Config_Binding_Key, 1); \
488 bi->context = _context; \
489 bi->key = eina_stringshare_add(_key); \
490 bi->modifiers = _modifiers; \
491 bi->any_mod = _anymod; \
492 bi->action = eina_stringshare_add(_action); \
493 bi->params = eina_stringshare_add(_params); \
494 cfdata->binding.key = eina_list_append(cfdata->binding.key, bi)
496 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "Left",
497 E_BINDING_MODIFIER_SHIFT | E_BINDING_MODIFIER_ALT, 0,
498 "desk_flip_by", "-1 0");
499 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "Right",
500 E_BINDING_MODIFIER_SHIFT | E_BINDING_MODIFIER_ALT, 0,
501 "desk_flip_by", "1 0");
502 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "Up",
503 E_BINDING_MODIFIER_SHIFT | E_BINDING_MODIFIER_ALT, 0,
504 "desk_flip_by", "0 -1");
505 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "Down",
506 E_BINDING_MODIFIER_SHIFT | E_BINDING_MODIFIER_ALT, 0,
507 "desk_flip_by", "0 1");
508 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "Up",
509 E_BINDING_MODIFIER_CTRL | E_BINDING_MODIFIER_ALT, 0,
510 "window_raise", NULL);
511 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "Down",
512 E_BINDING_MODIFIER_CTRL | E_BINDING_MODIFIER_ALT, 0,
513 "window_lower", NULL);
514 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "x",
515 E_BINDING_MODIFIER_CTRL | E_BINDING_MODIFIER_ALT, 0,
516 "window_close", NULL);
517 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "k",
518 E_BINDING_MODIFIER_CTRL | E_BINDING_MODIFIER_ALT, 0,
519 "window_kill", NULL);
520 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "w",
521 E_BINDING_MODIFIER_CTRL | E_BINDING_MODIFIER_ALT, 0,
522 "window_menu", NULL);
523 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "s",
524 E_BINDING_MODIFIER_CTRL | E_BINDING_MODIFIER_ALT, 0,
525 "window_sticky_toggle", NULL);
526 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "i",
527 E_BINDING_MODIFIER_CTRL | E_BINDING_MODIFIER_ALT, 0,
528 "window_iconic_toggle", NULL);
529 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "f",
530 E_BINDING_MODIFIER_CTRL | E_BINDING_MODIFIER_ALT, 0,
531 "window_maximized_toggle", NULL);
532 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "F10",
533 E_BINDING_MODIFIER_SHIFT, 0,
534 "window_maximized_toggle", "default vertical");
535 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "F10",
536 E_BINDING_MODIFIER_CTRL, 0,
537 "window_maximized_toggle", "default horizontal");
538 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "r",
539 E_BINDING_MODIFIER_CTRL | E_BINDING_MODIFIER_ALT, 0,
540 "window_shaded_toggle", NULL);
541 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "Left",
542 E_BINDING_MODIFIER_CTRL | E_BINDING_MODIFIER_ALT, 0,
543 "desk_linear_flip_by", "-1");
544 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "Right",
545 E_BINDING_MODIFIER_CTRL | E_BINDING_MODIFIER_ALT, 0,
546 "desk_linear_flip_by", "1");
547 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "F1",
548 E_BINDING_MODIFIER_ALT, 0,
549 "desk_linear_flip_to", "0");
550 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "F2",
551 E_BINDING_MODIFIER_ALT, 0,
552 "desk_linear_flip_to", "1");
553 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "F3",
554 E_BINDING_MODIFIER_ALT, 0,
555 "desk_linear_flip_to", "2");
556 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "F4",
557 E_BINDING_MODIFIER_ALT, 0,
558 "desk_linear_flip_to", "3");
559 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "F5",
560 E_BINDING_MODIFIER_ALT, 0,
561 "desk_linear_flip_to", "4");
562 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "F6",
563 E_BINDING_MODIFIER_ALT, 0,
564 "desk_linear_flip_to", "5");
565 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "F7",
566 E_BINDING_MODIFIER_ALT, 0,
567 "desk_linear_flip_to", "6");
568 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "F8",
569 E_BINDING_MODIFIER_ALT, 0,
570 "desk_linear_flip_to", "7");
571 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "F9",
572 E_BINDING_MODIFIER_ALT, 0,
573 "desk_linear_flip_to", "8");
574 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "F10",
575 E_BINDING_MODIFIER_ALT, 0,
576 "desk_linear_flip_to", "9");
577 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "F11",
578 E_BINDING_MODIFIER_ALT, 0,
579 "desk_linear_flip_to", "10");
580 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "F12",
581 E_BINDING_MODIFIER_ALT, 0,
582 "desk_linear_flip_to", "11");
583 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "m",
584 E_BINDING_MODIFIER_CTRL | E_BINDING_MODIFIER_ALT, 0,
585 "menu_show", "main");
586 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "a",
587 E_BINDING_MODIFIER_CTRL | E_BINDING_MODIFIER_ALT, 0,
588 "menu_show", "favorites");
589 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "Menu",
591 "menu_show", "main");
592 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "Menu",
593 E_BINDING_MODIFIER_CTRL, 0,
594 "menu_show", "clients");
595 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "Menu",
596 E_BINDING_MODIFIER_ALT, 0,
597 "menu_show", "favorites");
598 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "Insert",
599 E_BINDING_MODIFIER_CTRL | E_BINDING_MODIFIER_ALT, 0,
601 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "Tab",
602 E_BINDING_MODIFIER_ALT, 0,
604 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "Tab",
605 E_BINDING_MODIFIER_SHIFT | E_BINDING_MODIFIER_ALT, 0,
607 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "End",
608 E_BINDING_MODIFIER_CTRL | E_BINDING_MODIFIER_ALT, 0,
610 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "Delete",
611 E_BINDING_MODIFIER_CTRL | E_BINDING_MODIFIER_ALT, 0,
613 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "Escape",
614 E_BINDING_MODIFIER_ALT, 0,
616 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "l",
617 E_BINDING_MODIFIER_CTRL | E_BINDING_MODIFIER_ALT, 0,
619 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "d",
620 E_BINDING_MODIFIER_CTRL | E_BINDING_MODIFIER_ALT, 0,
621 "desk_deskshow_toggle", NULL);
622 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "Left",
623 E_BINDING_MODIFIER_CTRL | E_BINDING_MODIFIER_SHIFT, 0,
624 "screen_send_by", "-1");
625 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "Right",
626 E_BINDING_MODIFIER_CTRL | E_BINDING_MODIFIER_SHIFT, 0,
627 "screen_send_by", "1");
628 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "F1",
629 E_BINDING_MODIFIER_CTRL | E_BINDING_MODIFIER_SHIFT, 0,
630 "screen_send_to", "0");
631 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "F2",
632 E_BINDING_MODIFIER_CTRL | E_BINDING_MODIFIER_SHIFT, 0,
633 "screen_send_to", "1");
634 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "F3",
635 E_BINDING_MODIFIER_CTRL | E_BINDING_MODIFIER_SHIFT, 0,
636 "screen_send_to", "2");
637 CFG_KEYBIND_DFLT(E_BINDING_CONTEXT_ANY, "F4",
638 E_BINDING_MODIFIER_CTRL | E_BINDING_MODIFIER_SHIFT, 0,
639 "screen_send_to", "3");
641 eina_stringshare_del(cfdata->locals.cur);
642 cfdata->locals.cur = NULL;
644 _update_key_binding_list(cfdata, NULL);
645 _update_buttons(cfdata);
647 e_widget_ilist_unselect(cfdata->gui.o_action_list);
648 e_widget_entry_clear(cfdata->gui.o_params);
649 e_widget_disabled_set(cfdata->gui.o_params, 1);
652 /**************** Updates ***********/
654 _update_action_list(E_Config_Dialog_Data *cfdata)
656 E_Config_Binding_Key *bi;
657 int j = -1, i, n, cnt;
658 const char *action, *params;
660 if (!cfdata->locals.cur) return;
662 if (cfdata->locals.cur[0] == 'k')
664 sscanf(cfdata->locals.cur, "k%d", &n);
665 bi = eina_list_nth(cfdata->binding.key, n);
668 e_widget_ilist_unselect(cfdata->gui.o_action_list);
669 e_widget_entry_clear(cfdata->gui.o_params);
670 e_widget_disabled_set(cfdata->gui.o_params, 1);
679 _find_key_binding_action(action, params, NULL, NULL, &j);
683 cnt = e_widget_ilist_count(cfdata->gui.o_action_list);
684 for (i = 0; i < cnt; i++)
687 if (e_widget_ilist_nth_is_header(cfdata->gui.o_action_list, i)) j++;
693 if (j == e_widget_ilist_selected_get(cfdata->gui.o_action_list))
694 _update_action_params(cfdata);
696 e_widget_ilist_selected_set(cfdata->gui.o_action_list, j);
700 e_widget_ilist_unselect(cfdata->gui.o_action_list);
701 eina_stringshare_del(cfdata->locals.action);
702 cfdata->locals.action = eina_stringshare_add("");
703 e_widget_entry_clear(cfdata->gui.o_params);
706 /*if (cfdata->locals.cur[0] == 'k')
708 sscanf(cfdata->locals.cur, "k%d", &n);
709 bi = eina_list_nth(cfdata->binding.key, n);
712 e_widget_ilist_unselect(cfdata->gui.o_action_list);
713 e_widget_entry_clear(cfdata->gui.o_params);
714 e_widget_disabled_set(cfdata->gui.o_params, 1);
718 _find_key_binding_action(bi, NULL, NULL, &j);
721 for (i = 0; i < e_widget_ilist_count(cfdata->gui.o_action_list); i++)
724 if (e_widget_ilist_nth_is_header(cfdata->gui.o_action_list, i)) j++;
730 if (j == e_widget_ilist_selected_get(cfdata->gui.o_action_list))
731 _update_action_params(cfdata);
733 e_widget_ilist_selected_set(cfdata->gui.o_action_list, j);
737 e_widget_ilist_unselect(cfdata->gui.o_action_list);
738 if (cfdata->locals.action) free(cfdata->locals.action);
739 cfdata->locals.action = strdup("");
740 e_widget_entry_clear(cfdata->gui.o_params);
746 _update_action_params(E_Config_Dialog_Data *cfdata)
749 E_Action_Group *actg;
750 E_Action_Description *actd;
751 E_Config_Binding_Key *bi;
752 const char *action, *params;
754 #define KB_EXAMPLE_PARAMS \
755 if ((!actd->param_example) || (!actd->param_example[0])) \
756 e_widget_entry_text_set(cfdata->gui.o_params, TEXT_NO_PARAMS); \
758 e_widget_entry_text_set(cfdata->gui.o_params, actd->param_example)
760 if ((!cfdata->locals.action) || (!cfdata->locals.action[0]))
762 e_widget_disabled_set(cfdata->gui.o_params, 1);
763 e_widget_entry_clear(cfdata->gui.o_params);
766 sscanf(cfdata->locals.action, "%d %d", &g, &a);
768 actg = eina_list_nth(e_action_groups_get(), g);
770 actd = eina_list_nth(actg->acts, a);
773 if (actd->act_params)
775 e_widget_disabled_set(cfdata->gui.o_params, 1);
776 e_widget_entry_text_set(cfdata->gui.o_params, actd->act_params);
780 if ((!cfdata->locals.cur) || (!cfdata->locals.cur[0]))
782 e_widget_disabled_set(cfdata->gui.o_params, 1);
788 e_widget_disabled_set(cfdata->gui.o_params, 1);
790 e_widget_disabled_set(cfdata->gui.o_params, 0);
792 if (cfdata->locals.cur[0] == 'k')
794 sscanf(cfdata->locals.cur, "k%d", &b);
795 bi = eina_list_nth(cfdata->binding.key, b);
798 e_widget_disabled_set(cfdata->gui.o_params, 1);
807 e_widget_disabled_set(cfdata->gui.o_params, 1);
814 if (!strcmp(action, actd->act_cmd))
816 if ((!params) || (!params[0]))
819 e_widget_entry_text_set(cfdata->gui.o_params, params);
829 _update_key_binding_list(E_Config_Dialog_Data *cfdata,
830 E_Config_Binding_Key *bi_new)
835 E_Config_Binding_Key *bi;
840 evas_event_freeze(evas_object_evas_get(cfdata->gui.o_binding_list));
842 e_widget_ilist_freeze(cfdata->gui.o_binding_list);
844 e_widget_ilist_clear(cfdata->gui.o_binding_list);
845 e_widget_ilist_go(cfdata->gui.o_binding_list);
847 if (cfdata->binding.key)
849 cfdata->binding.key = eina_list_sort(cfdata->binding.key,
850 eina_list_count(cfdata->binding.key), _key_binding_sort_cb);
853 for (l = cfdata->binding.key, i = 0; l; l = l->next, i++)
856 if (bi == bi_new) ret = bi_pos;
857 if (ret < 0) bi_pos++;
859 if (modifiers != (int)bi->modifiers)
861 modifiers = bi->modifiers;
862 b = _key_binding_header_get(modifiers);
865 if (ret < 0) bi_pos++;
866 e_widget_ilist_header_append(cfdata->gui.o_binding_list, NULL, b);
871 b = _key_binding_text_get(bi);
874 snprintf(b2, sizeof(b2), "k%d", i);
875 e_widget_ilist_append(cfdata->gui.o_binding_list, NULL, b,
876 _binding_change_cb, cfdata, b2);
879 e_widget_ilist_go(cfdata->gui.o_binding_list);
881 e_widget_ilist_thaw(cfdata->gui.o_binding_list);
883 evas_event_thaw(evas_object_evas_get(cfdata->gui.o_binding_list));
885 if (eina_list_count(cfdata->binding.key))
886 e_widget_disabled_set(cfdata->gui.o_del_all, 0);
888 e_widget_disabled_set(cfdata->gui.o_del_all, 1);
894 _update_buttons(E_Config_Dialog_Data *cfdata)
896 if (e_widget_ilist_count(cfdata->gui.o_binding_list))
897 e_widget_disabled_set(cfdata->gui.o_del_all, 0);
899 e_widget_disabled_set(cfdata->gui.o_del_all, 1);
901 if (!cfdata->locals.cur)
903 e_widget_disabled_set(cfdata->gui.o_mod, 1);
904 e_widget_disabled_set(cfdata->gui.o_del, 1);
907 e_widget_disabled_set(cfdata->gui.o_mod, 0);
908 e_widget_disabled_set(cfdata->gui.o_del, 0);
911 /*************** Sorting *****************************/
913 _key_binding_sort_cb(const void *d1,
917 const E_Config_Binding_Key *bi, *bi2;
923 if (bi->modifiers & E_BINDING_MODIFIER_CTRL) i++;
924 if (bi->modifiers & E_BINDING_MODIFIER_ALT) i++;
925 if (bi->modifiers & E_BINDING_MODIFIER_SHIFT) i++;
926 if (bi->modifiers & E_BINDING_MODIFIER_WIN) i++;
928 if (bi2->modifiers & E_BINDING_MODIFIER_CTRL) j++;
929 if (bi2->modifiers & E_BINDING_MODIFIER_ALT) j++;
930 if (bi2->modifiers & E_BINDING_MODIFIER_SHIFT) j++;
931 if (bi2->modifiers & E_BINDING_MODIFIER_WIN) j++;
933 if (i < j) return -1;
937 if (bi->modifiers < bi2->modifiers) return -1;
938 else if (bi->modifiers > bi2->modifiers)
941 i = strlen(bi->key ? bi->key : "");
942 j = strlen(bi2->key ? bi2->key : "");
944 if (i < j) return -1;
948 i = e_util_strcmp(bi->key, bi2->key);
949 if (i < 0) return -1;
956 /**************** grab window *******/
958 _grab_wnd_show(E_Config_Dialog_Data *cfdata)
962 if (cfdata->locals.bind_win != 0) return;
964 man = e_manager_current_get();
966 cfdata->locals.dia = e_dialog_new(e_container_current_get(man),
967 "E", "_keybind_getkey_dialog");
968 if (!cfdata->locals.dia) return;
969 e_dialog_title_set(cfdata->locals.dia, _("Key Binding Sequence"));
970 e_dialog_icon_set(cfdata->locals.dia, "preferences-desktop-keyboard-shortcuts", 48);
971 e_dialog_text_set(cfdata->locals.dia, TEXT_PRESS_KEY_SEQUENCE);
972 e_win_centered_set(cfdata->locals.dia->win, 1);
973 e_win_borderless_set(cfdata->locals.dia->win, 1);
975 cfdata->locals.bind_win = ecore_x_window_input_new(man->root, 0, 0, 1, 1);
976 ecore_x_window_show(cfdata->locals.bind_win);
977 e_grabinput_get(cfdata->locals.bind_win, 0, cfdata->locals.bind_win);
979 cfdata->locals.handlers = eina_list_append(cfdata->locals.handlers,
980 ecore_event_handler_add(ECORE_EVENT_KEY_DOWN,
981 _grab_key_down_cb, cfdata));
983 cfdata->locals.handlers = eina_list_append(cfdata->locals.handlers,
984 ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN,
985 _grab_mouse_dumb_cb, NULL));
987 cfdata->locals.handlers = eina_list_append(cfdata->locals.handlers,
988 ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP,
989 _grab_mouse_dumb_cb, NULL));
991 cfdata->locals.handlers = eina_list_append(cfdata->locals.handlers,
992 ecore_event_handler_add(ECORE_EVENT_MOUSE_WHEEL,
993 _grab_mouse_dumb_cb, NULL));
995 e_dialog_show(cfdata->locals.dia);
996 ecore_x_icccm_transient_for_set(cfdata->locals.dia->win->evas_win, cfdata->cfd->dia->win->evas_win);
1000 _grab_wnd_hide(E_Config_Dialog_Data *cfdata)
1002 Ecore_Event_Handler *eh;
1004 EINA_LIST_FREE(cfdata->locals.handlers, eh)
1005 ecore_event_handler_del(eh);
1007 e_object_del(E_OBJECT(cfdata->locals.dia));
1008 cfdata->locals.dia = NULL;
1010 e_grabinput_release(cfdata->locals.bind_win, cfdata->locals.bind_win);
1011 ecore_x_window_free(cfdata->locals.bind_win);
1012 cfdata->locals.bind_win = 0;
1016 _grab_key_down_cb(void *data,
1017 __UNUSED__ int type,
1020 E_Config_Dialog_Data *cfdata;
1021 Ecore_Event_Key *ev;
1026 if (ev->window != cfdata->locals.bind_win) return ECORE_CALLBACK_PASS_ON;
1028 if (!strcmp(ev->keyname, "Escape") &&
1029 !(ev->modifiers & ECORE_EVENT_MODIFIER_SHIFT) &&
1030 !(ev->modifiers & ECORE_EVENT_MODIFIER_CTRL) &&
1031 !(ev->modifiers & ECORE_EVENT_MODIFIER_ALT) &&
1032 !(ev->modifiers & ECORE_EVENT_MODIFIER_WIN))
1034 _grab_wnd_hide(cfdata);
1038 if ((ev->keyname) && (ev->key) && (ev->compose))
1039 printf("'%s' '%s' '%s'\n", ev->keyname, ev->key, ev->compose);
1040 else if ((ev->keyname) && (ev->key))
1041 printf("'%s' '%s'\n", ev->keyname, ev->key);
1043 printf("unknown key!!!!\n");
1044 if (!strcmp(ev->keyname, "Control_L") || !strcmp(ev->keyname, "Control_R") ||
1045 !strcmp(ev->keyname, "Shift_L") || !strcmp(ev->keyname, "Shift_R") ||
1046 !strcmp(ev->keyname, "Alt_L") || !strcmp(ev->keyname, "Alt_R") ||
1047 !strcmp(ev->keyname, "Super_L") || !strcmp(ev->keyname, "Super_R"))
1053 E_Config_Binding_Key *bi = NULL, *bi2 = NULL;
1054 Eina_List *l = NULL;
1055 unsigned int mod = E_BINDING_MODIFIER_NONE;
1058 if (ev->modifiers & ECORE_EVENT_MODIFIER_SHIFT)
1059 mod |= E_BINDING_MODIFIER_SHIFT;
1060 if (ev->modifiers & ECORE_EVENT_MODIFIER_CTRL)
1061 mod |= E_BINDING_MODIFIER_CTRL;
1062 if (ev->modifiers & ECORE_EVENT_MODIFIER_ALT)
1063 mod |= E_BINDING_MODIFIER_ALT;
1064 if (ev->modifiers & ECORE_EVENT_MODIFIER_WIN)
1065 mod |= E_BINDING_MODIFIER_WIN;
1066 /* see comment in e_bindings on numlock
1067 if (ev->modifiers & ECORE_X_LOCK_NUM)
1068 mod |= ECORE_X_LOCK_NUM;
1070 if (cfdata->locals.add)
1073 for (l = cfdata->binding.key, n = 0; l && !found; l = l->next, n++)
1076 if (bi->modifiers == mod && !strcmp(bi->key, ev->keyname))
1080 else if (cfdata->locals.cur && cfdata->locals.cur[0])
1083 sscanf(cfdata->locals.cur, "k%d", &n);
1084 bi = eina_list_nth(cfdata->binding.key, n);
1086 for (l = cfdata->binding.key, n = 0; l && !found; l = l->next, n++)
1089 if (bi == bi2) continue;
1090 if (bi2->modifiers == mod && !strcmp(bi2->key, ev->keyname))
1097 if (cfdata->locals.add)
1099 bi = E_NEW(E_Config_Binding_Key, 1);
1101 bi->context = E_BINDING_CONTEXT_ANY;
1102 bi->modifiers = mod;
1103 bi->key = eina_stringshare_add(ev->keyname);
1108 cfdata->binding.key = eina_list_append(cfdata->binding.key, bi);
1110 n = _update_key_binding_list(cfdata, bi);
1112 e_widget_ilist_selected_set(cfdata->gui.o_binding_list, n);
1113 e_widget_ilist_unselect(cfdata->gui.o_action_list);
1114 eina_stringshare_del(cfdata->locals.action);
1115 cfdata->locals.action = eina_stringshare_add("");
1116 if ((cfdata->params) && (cfdata->params[0]))
1119 _find_key_binding_action("exec", NULL, &g, NULL, &j);
1122 e_widget_ilist_unselect(cfdata->gui.o_action_list);
1123 e_widget_ilist_selected_set(cfdata->gui.o_action_list, (j + g + 1));
1124 e_widget_entry_clear(cfdata->gui.o_params);
1125 e_widget_entry_text_set(cfdata->gui.o_params, cfdata->params);
1130 e_widget_entry_clear(cfdata->gui.o_params);
1131 e_widget_disabled_set(cfdata->gui.o_params, 1);
1134 else if (cfdata->locals.cur && cfdata->locals.cur[0])
1137 sscanf(cfdata->locals.cur, "k%d", &n);
1138 bi = eina_list_nth(cfdata->binding.key, n);
1140 bi->modifiers = mod;
1141 if (bi->key) eina_stringshare_del(bi->key);
1142 bi->key = eina_stringshare_add(ev->keyname);
1145 label = _key_binding_text_get(bi);
1146 e_widget_ilist_nth_label_set(cfdata->gui.o_binding_list, n, label);
1155 /* this advice is rather irritating as one sees that the
1156 key is bound to an action. if you want to set a
1157 keybinding you dont care about whether there is
1158 sth else set to it. */
1160 const char *label = NULL;
1161 E_Action_Group *actg = NULL;
1162 E_Action_Description *actd = NULL;
1164 if (cfdata->locals.add)
1165 _find_key_binding_action(bi->action, bi->params, &g, &a, &j);
1167 _find_key_binding_action(bi2->action, bi2->params, &g, &a, &j);
1169 actg = eina_list_nth(e_action_groups_get(), g);
1170 if (actg) actd = eina_list_nth(actg->acts, a);
1172 if (actd) label = _(actd->act_name);
1174 e_util_dialog_show(_("Binding Key Error"),
1175 _("The binding key sequence, that you choose,"
1176 " is already used by <br>"
1177 "<hilight>%s</hilight> action.<br>"
1178 "Please choose another binding key sequence."),
1179 label ? label : _("Unknown"));
1181 EINA_LIST_FOREACH(e_widget_ilist_items_get(cfdata->gui.o_binding_list), l, it)
1183 if (i++ >= n) break;
1184 if (it->header) n++;
1187 e_widget_ilist_nth_show(cfdata->gui.o_binding_list, n - 1, 1);
1188 e_widget_ilist_selected_set(cfdata->gui.o_binding_list, n - 1);
1190 _grab_wnd_hide(cfdata);
1193 return ECORE_CALLBACK_PASS_ON;
1197 _grab_mouse_dumb_cb(__UNUSED__ void *data,
1198 __UNUSED__ int type,
1199 __UNUSED__ void *event)
1201 return ECORE_CALLBACK_RENEW;
1204 /********** Helper *********************************/
1206 _auto_apply_changes(E_Config_Dialog_Data *cfdata)
1209 E_Config_Binding_Key *bi;
1210 E_Action_Group *actg;
1211 E_Action_Description *actd;
1213 if ((!cfdata->locals.cur) || (!cfdata->locals.cur[0]) ||
1214 (!cfdata->locals.action) || (!cfdata->locals.action[0])) return;
1216 sscanf(cfdata->locals.cur, "k%d", &n);
1217 sscanf(cfdata->locals.action, "%d %d", &g, &a);
1219 bi = eina_list_nth(cfdata->binding.key, n);
1222 actg = eina_list_nth(e_action_groups_get(), g);
1224 actd = eina_list_nth(actg->acts, a);
1227 eina_stringshare_del(bi->action);
1230 if (actd->act_cmd) bi->action = eina_stringshare_add(actd->act_cmd);
1232 eina_stringshare_del(bi->params);
1235 if (actd->act_params)
1236 bi->params = eina_stringshare_add(actd->act_params);
1240 if (cfdata->locals.params)
1242 if (!strcmp(cfdata->locals.params, TEXT_NO_PARAMS))
1245 if ((actd->param_example) && (!strcmp(cfdata->locals.params, actd->param_example)))
1252 bi->params = eina_stringshare_add(cfdata->locals.params);
1257 _find_key_binding_action(const char *action,
1264 int gg = -1, aa = -1, nn = -1, found;
1265 E_Action_Group *actg;
1266 E_Action_Description *actd;
1273 for (l = e_action_groups_get(), gg = 0, nn = 0; l; l = l->next, gg++)
1277 for (l2 = actg->acts, aa = 0; l2; l2 = l2->next, aa++)
1280 if (!strcmp((!action ? "" : action), (!actd->act_cmd ? "" : actd->act_cmd)))
1282 if (!params || !params[0])
1284 if ((!actd->act_params) || (!actd->act_params[0]))
1296 if ((!actd->act_params) || (!actd->act_params[0]))
1305 if (!strcmp(params, actd->act_params))
1329 _key_binding_header_get(int modifiers)
1333 if (modifiers & E_BINDING_MODIFIER_CTRL)
1334 strcat(b, _("CTRL"));
1336 if (modifiers & E_BINDING_MODIFIER_ALT)
1338 if (b[0]) strcat(b, " + ");
1339 strcat(b, _("ALT"));
1342 if (modifiers & E_BINDING_MODIFIER_SHIFT)
1344 if (b[0]) strcat(b, " + ");
1345 strcat(b, _("SHIFT"));
1348 if (modifiers & E_BINDING_MODIFIER_WIN)
1350 if (b[0]) strcat(b, " + ");
1351 strcat(b, _("WIN"));
1354 if (!b[0]) return strdup(TEXT_NO_MODIFIER_HEADER);
1359 _key_binding_text_get(E_Config_Binding_Key *bi)
1363 if (!bi) return NULL;
1365 if (bi->modifiers & E_BINDING_MODIFIER_CTRL)
1366 strcat(b, _("CTRL"));
1368 if (bi->modifiers & E_BINDING_MODIFIER_ALT)
1370 if (b[0]) strcat(b, " + ");
1371 strcat(b, _("ALT"));
1374 if (bi->modifiers & E_BINDING_MODIFIER_SHIFT)
1376 if (b[0]) strcat(b, " + ");
1377 strcat(b, _("SHIFT"));
1380 if (bi->modifiers & E_BINDING_MODIFIER_WIN)
1382 if (b[0]) strcat(b, " + ");
1383 strcat(b, _("WIN"));
1386 if (bi->key && bi->key[0])
1389 if (b[0]) strcat(b, " + ");
1391 l = strdup(bi->key);
1392 l[0] = (char)toupper(bi->key[0]);
1397 /* see comment in e_bindings on numlock
1398 if (bi->modifiers & ECORE_X_LOCK_NUM)
1400 if (b[0]) strcat(b, " ");
1401 strcat(b, _("OFF"));
1405 if (!b[0]) return strdup(TEXT_NONE_ACTION_KEY);