yoz pushed a commit to branch master. http://git.enlightenment.org/core/enlightenment.git/commit/?id=64b9f1e58b0f6c1fc967e982392ca6531d9bcb82
commit 64b9f1e58b0f6c1fc967e982392ca6531d9bcb82 Author: Michael Bouchaud (yoz) <y...@efl.so> Date: Thu Jan 10 11:35:36 2019 +0100 xkbswitch: Change layout keyboard on double left-click Summary: We move the creation of the popup to a timer to let double left click event occur. This timer is set to the current double click time value. @fix T354 Reviewers: zmike, devilhorns Reviewed By: zmike Subscribers: cedric Tags: #enlightenment-git Maniphest Tasks: T354 Differential Revision: https://phab.enlightenment.org/D7568 --- src/modules/xkbswitch/e_mod_main.c | 277 ++++++++++++++++++------------- src/modules/xkbswitch/gadget/xkbswitch.c | 129 ++++++++------ 2 files changed, 238 insertions(+), 168 deletions(-) diff --git a/src/modules/xkbswitch/e_mod_main.c b/src/modules/xkbswitch/e_mod_main.c index 21cd4d383..4806ebc33 100644 --- a/src/modules/xkbswitch/e_mod_main.c +++ b/src/modules/xkbswitch/e_mod_main.c @@ -31,6 +31,8 @@ typedef struct _Instance Evas_Object *o_xkbswitch; Evas_Object *o_xkbflag; E_Config_XKB_Layout *layout; + unsigned int lmenu_timestamp; + Ecore_Timer *lmenu_timer; E_Menu *lmenu; } Instance; @@ -285,6 +287,139 @@ _xkb_changed_state(void *data EINA_UNUSED, int type EINA_UNUSED, void *event EIN return ECORE_CALLBACK_PASS_ON; } +static Eina_Bool +_e_xkb_cb_lmenu(void *data) +{ + Instance *inst; + + Evas_Coord x, y, w, h; + int cx, cy, dir; + E_Menu_Item *mi; + + inst = data; + inst->lmenu_timer = NULL; + + /* Coordinates and sizing */ + evas_object_geometry_get(inst->o_xkbswitch, &x, &y, &w, &h); + e_gadcon_canvas_zone_geometry_get(inst->gcc->gadcon, &cx, &cy, + NULL, NULL); + x += cx; + y += cy; + + if (!inst->lmenu) inst->lmenu = e_menu_new(); + + mi = e_menu_item_new(inst->lmenu); + + e_menu_item_label_set(mi, _("Settings")); + e_util_menu_item_theme_icon_set(mi, "preferences-system"); + e_menu_item_callback_set(mi, _e_xkb_cb_menu_configure, NULL); + + if (!e_config->xkb.dont_touch_my_damn_keyboard) + { + E_Config_XKB_Layout *cl, *cur; + Eina_List *l; + char buf[4096]; + + mi = e_menu_item_new(inst->lmenu); + e_menu_item_separator_set(mi, 1); + cur = e_xkb_layout_get(); + + /* Append all the layouts */ + EINA_LIST_FOREACH(e_config->xkb.used_layouts, l, cl) + { + const char *name = cl->name; + + mi = e_menu_item_new(inst->lmenu); + + e_menu_item_radio_set(mi, 1); + e_menu_item_radio_group_set(mi, 1); + if (e_config_xkb_layout_eq(cur, cl)) + e_menu_item_toggle_set(mi, 1); + e_xkb_flag_file_get(buf, sizeof(buf), name); + e_menu_item_icon_file_set(mi, buf); + if (cl->variant) + snprintf(buf, sizeof(buf), "%s (%s, %s)", cl->name, cl->model, cl->variant); + else + snprintf(buf, sizeof(buf), "%s (%s)", cl->name, cl->model); + e_menu_item_label_set(mi, buf); + e_menu_item_callback_set(mi, _e_xkb_cb_lmenu_set, cl); + } + } + + /* Deactivate callback */ + e_menu_post_deactivate_callback_set(inst->lmenu, + _e_xkb_cb_lmenu_post, inst); + /* Proper menu orientation */ + switch (inst->gcc->gadcon->orient) + { + case E_GADCON_ORIENT_TOP: + dir = E_MENU_POP_DIRECTION_DOWN; + break; + + case E_GADCON_ORIENT_BOTTOM: + dir = E_MENU_POP_DIRECTION_UP; + break; + + case E_GADCON_ORIENT_LEFT: + dir = E_MENU_POP_DIRECTION_RIGHT; + break; + + case E_GADCON_ORIENT_RIGHT: + dir = E_MENU_POP_DIRECTION_LEFT; + break; + + case E_GADCON_ORIENT_CORNER_TL: + dir = E_MENU_POP_DIRECTION_DOWN; + break; + + case E_GADCON_ORIENT_CORNER_TR: + dir = E_MENU_POP_DIRECTION_DOWN; + break; + + case E_GADCON_ORIENT_CORNER_BL: + dir = E_MENU_POP_DIRECTION_UP; + break; + + case E_GADCON_ORIENT_CORNER_BR: + dir = E_MENU_POP_DIRECTION_UP; + break; + + case E_GADCON_ORIENT_CORNER_LT: + dir = E_MENU_POP_DIRECTION_RIGHT; + break; + + case E_GADCON_ORIENT_CORNER_RT: + dir = E_MENU_POP_DIRECTION_LEFT; + break; + + case E_GADCON_ORIENT_CORNER_LB: + dir = E_MENU_POP_DIRECTION_RIGHT; + break; + + case E_GADCON_ORIENT_CORNER_RB: + dir = E_MENU_POP_DIRECTION_LEFT; + break; + + case E_GADCON_ORIENT_FLOAT: + case E_GADCON_ORIENT_HORIZ: + case E_GADCON_ORIENT_VERT: + default: + dir = E_MENU_POP_DIRECTION_AUTO; + break; + } + + e_gadcon_locked_set(inst->gcc->gadcon, 1); + + /* We display not relatively to the gadget, but similarly to + * the start menu - thus the need for direction etc. + */ + e_menu_activate_mouse(inst->lmenu, + e_zone_current_get(), + x, y, w, h, dir, inst->lmenu_timestamp); + + return ECORE_CALLBACK_CANCEL; +} + static void _e_xkb_cb_mouse_down(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event) { @@ -320,132 +455,34 @@ _e_xkb_cb_mouse_down(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_U evas_event_feed_mouse_up(inst->gcc->gadcon->evas, ev->button, EVAS_BUTTON_NONE, ev->timestamp, NULL); } - else if ((ev->button == 1) && (!inst->lmenu)) /* Left-click layout menu */ - { - Evas_Coord x, y, w, h; - int cx, cy, dir; - E_Menu_Item *mi; - - /* Coordinates and sizing */ - evas_object_geometry_get(inst->o_xkbswitch, &x, &y, &w, &h); - e_gadcon_canvas_zone_geometry_get(inst->gcc->gadcon, &cx, &cy, - NULL, NULL); - x += cx; - y += cy; - if (!inst->lmenu) inst->lmenu = e_menu_new(); - - mi = e_menu_item_new(inst->lmenu); - - e_menu_item_label_set(mi, _("Settings")); - e_util_menu_item_theme_icon_set(mi, "preferences-system"); - e_menu_item_callback_set(mi, _e_xkb_cb_menu_configure, NULL); - - if (!e_config->xkb.dont_touch_my_damn_keyboard) + else if ((ev->button == 2) /* Middle click */ + || + ((ev->button == 1) && (ev->flags & EVAS_BUTTON_DOUBLE_CLICK)) /* double Left-click */ + ) + { + if (inst->lmenu_timer) { - E_Config_XKB_Layout *cl, *cur; - Eina_List *l; - char buf[4096]; - - mi = e_menu_item_new(inst->lmenu); - e_menu_item_separator_set(mi, 1); - cur = e_xkb_layout_get(); - - /* Append all the layouts */ - EINA_LIST_FOREACH(e_config->xkb.used_layouts, l, cl) - { - const char *name = cl->name; - - mi = e_menu_item_new(inst->lmenu); - - e_menu_item_radio_set(mi, 1); - e_menu_item_radio_group_set(mi, 1); - if (e_config_xkb_layout_eq(cur, cl)) - e_menu_item_toggle_set(mi, 1); - e_xkb_flag_file_get(buf, sizeof(buf), name); - e_menu_item_icon_file_set(mi, buf); - if (cl->variant) - snprintf(buf, sizeof(buf), "%s (%s, %s)", cl->name, cl->model, cl->variant); - else - snprintf(buf, sizeof(buf), "%s (%s)", cl->name, cl->model); - e_menu_item_label_set(mi, buf); - e_menu_item_callback_set(mi, _e_xkb_cb_lmenu_set, cl); - } + ecore_timer_del(inst->lmenu_timer); + inst->lmenu_timer = NULL; } - - /* Deactivate callback */ - e_menu_post_deactivate_callback_set(inst->lmenu, - _e_xkb_cb_lmenu_post, inst); - /* Proper menu orientation */ - switch (inst->gcc->gadcon->orient) + e_xkb_layout_next(); + } + else if ((ev->button == 1) && (!inst->lmenu)) /* Left-click layout menu */ + { + if (!inst->lmenu_timer) { - case E_GADCON_ORIENT_TOP: - dir = E_MENU_POP_DIRECTION_DOWN; - break; - - case E_GADCON_ORIENT_BOTTOM: - dir = E_MENU_POP_DIRECTION_UP; - break; - - case E_GADCON_ORIENT_LEFT: - dir = E_MENU_POP_DIRECTION_RIGHT; - break; - - case E_GADCON_ORIENT_RIGHT: - dir = E_MENU_POP_DIRECTION_LEFT; - break; - - case E_GADCON_ORIENT_CORNER_TL: - dir = E_MENU_POP_DIRECTION_DOWN; - break; - - case E_GADCON_ORIENT_CORNER_TR: - dir = E_MENU_POP_DIRECTION_DOWN; - break; - - case E_GADCON_ORIENT_CORNER_BL: - dir = E_MENU_POP_DIRECTION_UP; - break; - - case E_GADCON_ORIENT_CORNER_BR: - dir = E_MENU_POP_DIRECTION_UP; - break; - - case E_GADCON_ORIENT_CORNER_LT: - dir = E_MENU_POP_DIRECTION_RIGHT; - break; - - case E_GADCON_ORIENT_CORNER_RT: - dir = E_MENU_POP_DIRECTION_LEFT; - break; - - case E_GADCON_ORIENT_CORNER_LB: - dir = E_MENU_POP_DIRECTION_RIGHT; - break; - - case E_GADCON_ORIENT_CORNER_RB: - dir = E_MENU_POP_DIRECTION_LEFT; - break; - - case E_GADCON_ORIENT_FLOAT: - case E_GADCON_ORIENT_HORIZ: - case E_GADCON_ORIENT_VERT: - default: - dir = E_MENU_POP_DIRECTION_AUTO; - break; - } + inst->lmenu_timestamp = ev->timestamp; +#ifdef HAVE_WAYLAND_ONLY + inst->lmenu_timer = ecore_timer_add(0.25, + _e_xkb_cb_lmenu, inst); +#else + inst->lmenu_timer = ecore_timer_add(ecore_x_double_click_time_get(), + _e_xkb_cb_lmenu, inst); +#endif - e_gadcon_locked_set(inst->gcc->gadcon, 1); - - /* We display not relatively to the gadget, but similarly to - * the start menu - thus the need for direction etc. - */ - e_menu_activate_mouse(inst->lmenu, - e_zone_current_get(), - x, y, w, h, dir, ev->timestamp); + } } - else if (ev->button == 2) /* Middle click */ - e_xkb_layout_next(); } static void diff --git a/src/modules/xkbswitch/gadget/xkbswitch.c b/src/modules/xkbswitch/gadget/xkbswitch.c index b68a2c764..f63947146 100644 --- a/src/modules/xkbswitch/gadget/xkbswitch.c +++ b/src/modules/xkbswitch/gadget/xkbswitch.c @@ -9,6 +9,8 @@ typedef struct _Instance Evas_Object *popup; E_Gadget_Site_Orient orient; E_Config_XKB_Layout *layout; + Ecore_Timer *menu_timer; + unsigned int menu_timestamp; } Instance; static Eina_List *ginstances = NULL; @@ -119,6 +121,63 @@ _xkbg_popup_deleted(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSE inst->popup = NULL; } +static Eina_Bool +_xkbg_popup_cb(void *data) +{ + Instance *inst; + E_Config_XKB_Layout *cl, *cur; + Eina_List *l; + Elm_Object_Item *mi; + char buf[4096], buf2[4096]; + + inst = data; + inst->menu_timer = NULL; + cur = e_xkb_layout_get(); + + inst->popup = elm_ctxpopup_add(e_comp->elm); + elm_object_style_set(inst->popup, "noblock"); + evas_object_smart_callback_add(inst->popup, "dismissed", _xkbg_popup_dismissed, inst); + evas_object_event_callback_add(inst->popup, EVAS_CALLBACK_DEL, _xkbg_popup_deleted, inst); + + inst->menu = elm_list_add(inst->popup); + elm_list_select_mode_set(inst->menu, ELM_OBJECT_SELECT_MODE_ALWAYS); + evas_object_data_set(inst->menu, "inst", inst); + elm_object_content_set(inst->popup, inst->menu); + E_EXPAND(inst->menu); + E_FILL(inst->menu); + + /* Append all the layouts */ + EINA_LIST_FOREACH(e_config->xkb.used_layouts, l, cl) + { + const char *name = cl->name; + Evas_Object *ic; + + e_xkb_flag_file_get(buf, sizeof(buf), name); + if (cl->variant) + snprintf(buf2, sizeof(buf2), "%s (%s, %s)", cl->name, cl->model, cl->variant); + else + snprintf(buf2, sizeof(buf2), "%s (%s)", cl->name, cl->model); + + ic = elm_icon_add(inst->menu); + E_EXPAND(ic); + E_FILL(ic); + elm_image_file_set(ic, buf, NULL); + evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1); + evas_object_show(ic); + + mi = elm_list_item_append(inst->menu, buf2, ic, NULL, _xkbg_cb_menu_set, cl); + + if (e_config_xkb_layout_eq(cur, cl)) + elm_list_item_selected_set(mi, EINA_TRUE); + } + + evas_object_show(inst->menu); + evas_object_size_hint_min_set(inst->popup, 200 * e_scale, 100 * e_scale); + e_gadget_util_ctxpopup_place(inst->o_main, inst->popup, inst->o_xkbswitch); + evas_object_show(inst->popup); + return ECORE_CALLBACK_CANCEL; +} + static void _xkbg_cb_mouse_up(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event) { @@ -132,62 +191,36 @@ _xkbg_cb_mouse_up(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUS elm_ctxpopup_dismiss(inst->popup); return; } + else if ((ev->button == 2) /* Middle click */ + || + ((ev->button == 1) && (ev->flags & EVAS_BUTTON_DOUBLE_CLICK)) /* double Left-click */ + ) + { + if (inst->menu_timer) + { + ecore_timer_del(inst->menu_timer); + inst->menu_timer = NULL; + } + e_xkb_layout_next(); + } + else if ((ev->button == 1) && (!inst->popup)) /* Left-click layout menu */ { if (!e_config->xkb.dont_touch_my_damn_keyboard) { - E_Config_XKB_Layout *cl, *cur; - Eina_List *l; - Elm_Object_Item *mi; - char buf[4096], buf2[4096]; - - cur = e_xkb_layout_get(); - - inst->popup = elm_ctxpopup_add(e_comp->elm); - elm_object_style_set(inst->popup, "noblock"); - evas_object_smart_callback_add(inst->popup, "dismissed", _xkbg_popup_dismissed, inst); - evas_object_event_callback_add(inst->popup, EVAS_CALLBACK_DEL, _xkbg_popup_deleted, inst); - - inst->menu = elm_list_add(inst->popup); - elm_list_select_mode_set(inst->menu, ELM_OBJECT_SELECT_MODE_ALWAYS); - evas_object_data_set(inst->menu, "inst", inst); - elm_object_content_set(inst->popup, inst->menu); - E_EXPAND(inst->menu); - E_FILL(inst->menu); - - /* Append all the layouts */ - EINA_LIST_FOREACH(e_config->xkb.used_layouts, l, cl) + if (!inst->menu_timer) { - const char *name = cl->name; - Evas_Object *ic; - - e_xkb_flag_file_get(buf, sizeof(buf), name); - if (cl->variant) - snprintf(buf2, sizeof(buf2), "%s (%s, %s)", cl->name, cl->model, cl->variant); - else - snprintf(buf2, sizeof(buf2), "%s (%s)", cl->name, cl->model); - - ic = elm_icon_add(inst->menu); - E_EXPAND(ic); - E_FILL(ic); - elm_image_file_set(ic, buf, NULL); - evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1); - evas_object_show(ic); - - mi = elm_list_item_append(inst->menu, buf2, ic, NULL, _xkbg_cb_menu_set, cl); - - if (e_config_xkb_layout_eq(cur, cl)) - elm_list_item_selected_set(mi, EINA_TRUE); + inst->menu_timestamp = ev->timestamp; +#ifdef HAVE_WAYLAND_ONLY + inst->menu_timer = ecore_timer_add(0.25, + _xkbg_popup_cb, inst); +#else + inst->menu_timer = ecore_timer_add(ecore_x_double_click_time_get(), + _xkbg_popup_cb, inst); +#endif } - - evas_object_show(inst->menu); - evas_object_size_hint_min_set(inst->popup, 200 * e_scale, 100 * e_scale); - e_gadget_util_ctxpopup_place(inst->o_main, inst->popup, inst->o_xkbswitch); - evas_object_show(inst->popup); } } - else if (ev->button == 2) - e_xkb_layout_next(); } static void --