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

-- 


Reply via email to