create/manage list of focused wl keyboard resources for reuse in kbd operations 78/52578/7
authorJengHyun Kang <jhyuni.kang@samsung.com>
Tue, 24 Nov 2015 12:13:31 +0000 (21:13 +0900)
committerSung-Jin Park <sj76.park@samsung.com>
Mon, 7 Dec 2015 02:02:56 +0000 (18:02 -0800)
this simplifies kbd code all over

Change-Id: Ie231d3be07726b935c5aea72261eadf3f63e6fbb

src/bin/e_comp_wl.c
src/bin/e_comp_wl.h
src/bin/e_comp_wl_input.c
src/bin/e_config.c
src/bin/e_config.h

index e72f246..14adc22 100644 (file)
@@ -1121,7 +1121,6 @@ static void
 _e_comp_wl_client_focus(E_Client *ec)
 {
    struct wl_resource *res;
-   struct wl_client *wc;
    uint32_t serial, *k;
    Eina_List *l;
 
@@ -1133,27 +1132,55 @@ _e_comp_wl_client_focus(E_Client *ec)
    if (!ec->comp_data->surface) return;
 
    /* send keyboard_enter to all keyboard resources */
-   wc = wl_resource_get_client(ec->comp_data->surface);
    serial = wl_display_next_serial(e_comp->wl_comp_data->wl.disp);
-   EINA_LIST_FOREACH(e_comp->wl_comp_data->kbd.resources, l, res)
+   EINA_LIST_FOREACH(e_comp->wl_comp_data->kbd.focused, l, res)
      {
-        if (wl_resource_get_client(res) != wc) continue;
         wl_keyboard_send_enter(res, serial, ec->comp_data->surface,
                                &e_comp->wl_comp_data->kbd.keys);
         ec->comp_data->focus_update = 0;
      }
 }
 
+static Eina_Bool
+_e_comp_wl_evas_cb_focus_in_timer(E_Client *ec)
+{
+   E_Comp_Data *cdata;
+   uint32_t serial, *k;
+   struct wl_resource *res;
+   Eina_List *l;
+   double t;
+
+   if (e_object_is_del(E_OBJECT(ec))) return EINA_FALSE;
+
+   ec->comp_data->on_focus_timer = NULL;
+   cdata = ec->comp->wl_comp_data;
+
+   if (!cdata->kbd.focused) return EINA_FALSE;
+   serial = wl_display_next_serial(cdata->wl.disp);
+   t = ecore_time_unix_get();
+   EINA_LIST_FOREACH(cdata->kbd.focused, l, res)
+     wl_array_for_each(k, &cdata->kbd.keys)
+       wl_keyboard_send_key(res, serial, t,
+                            *k, WL_KEYBOARD_KEY_STATE_PRESSED);
+   return EINA_FALSE;
+}
+
 static void
 _e_comp_wl_evas_cb_focus_in(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
 {
    E_Client *ec, *focused;
+   E_Comp_Data *cdata;
+   struct wl_resource *res;
+   struct wl_client *wc;
+   Eina_List *l;
 
    if (!(ec = data)) return;
    if (e_object_is_del(E_OBJECT(ec))) return;
    if (ec->iconic) return;
    if (e_pixmap_type_get(ec->pixmap) != E_PIXMAP_TYPE_WL) return;
 
+   cdata = ec->comp->wl_comp_data;
+
    /* block spurious focus events */
    focused = e_client_focused_get();
    if ((focused) && (ec != focused)) return;
@@ -1161,7 +1188,16 @@ _e_comp_wl_evas_cb_focus_in(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj
    /* raise client priority */
    _e_comp_wl_client_priority_raise(ec);
 
+   wc = wl_resource_get_client(ec->comp_data->surface);
+   EINA_LIST_FOREACH(cdata->kbd.resources, l, res)
+     if (wl_resource_get_client(res) == wc)
+       cdata->kbd.focused = eina_list_append(cdata->kbd.focused, res);
+
    _e_comp_wl_client_focus(ec);
+
+   ec->comp_data->on_focus_timer =
+     ecore_timer_add(((e_config->xkb.delay_held_key_input_to_focus)/1000),
+                          (Ecore_Task_Cb)_e_comp_wl_evas_cb_focus_in_timer, ec);
 }
 
 static void
@@ -1170,14 +1206,16 @@ _e_comp_wl_evas_cb_focus_out(void *data, Evas *evas EINA_UNUSED, Evas_Object *ob
    E_Client *ec;
    E_Comp_Data *cdata;
    struct wl_resource *res;
-   struct wl_client *wc;
    uint32_t serial, *k;
-   Eina_List *l;
+   Eina_List *l, *ll;
+   double t;
 
    if (!(ec = data)) return;
    if (e_object_is_del(E_OBJECT(ec))) return;
    if (e_pixmap_type_get(ec->pixmap) != E_PIXMAP_TYPE_WL) return;
 
+   E_FREE_FUNC(ec->comp_data->on_focus_timer, ecore_timer_del);
+
    /* lower client priority */
    _e_comp_wl_client_priority_normal(ec);
 
@@ -1189,13 +1227,17 @@ _e_comp_wl_evas_cb_focus_out(void *data, Evas *evas EINA_UNUSED, Evas_Object *ob
 
    if (!ec->comp_data->surface) return;
 
-   /* send keyboard_leave to all keyboard resources */
-   wc = wl_resource_get_client(ec->comp_data->surface);
+   /* send key release and keyboard_leave to all focused resources */
    serial = wl_display_next_serial(cdata->wl.disp);
-   EINA_LIST_FOREACH(cdata->kbd.resources, l, res)
+   t = ecore_time_unix_get();
+   EINA_LIST_FOREACH_SAFE(cdata->kbd.focused, l, ll, res)
      {
-        if (wl_resource_get_client(res) != wc) continue;
+        wl_array_for_each(k, &cdata->kbd.keys)
+          wl_keyboard_send_key(res, serial, t,
+                               *k, WL_KEYBOARD_KEY_STATE_RELEASED);
         wl_keyboard_send_leave(res, serial, ec->comp_data->surface);
+        cdata->kbd.focused =
+          eina_list_remove_list(cdata->kbd.focused, l);
      }
    ec->comp_data->focus_update = 0;
 }
@@ -1531,18 +1573,13 @@ _e_comp_wl_cb_key_down(void *event)
           {
              if (ec->comp_data->surface)
                {
-                  struct wl_client *wc;
                   struct wl_resource *res;
                   Eina_List *l;
 
-                  wc = wl_resource_get_client(ec->comp_data->surface);
                   serial = wl_display_next_serial(cdata->wl.disp);
-                  EINA_LIST_FOREACH(cdata->kbd.resources, l, res)
-                    {
-                       if (wl_resource_get_client(res) != wc) continue;
-                       wl_keyboard_send_key(res, serial, ev->timestamp,
-                                            keycode, WL_KEYBOARD_KEY_STATE_PRESSED);
-                    }
+                  EINA_LIST_FOREACH(cdata->kbd.focused, l, res)
+                    wl_keyboard_send_key(res, serial, ev->timestamp,
+                                    keycode, WL_KEYBOARD_KEY_STATE_PRESSED);
 
                   /* A key only sent to clients is added to the list */
                   cdata->kbd.keys.size = (const char *)end - (const char *)cdata->kbd.keys.data;
@@ -1562,7 +1599,6 @@ _e_comp_wl_cb_key_down(void *event)
 static void
 _e_comp_wl_cb_key_up(void *event)
 {
-   E_Client *ec;
    E_Comp_Data *cdata;
    Ecore_Event_Key *ev;
    uint32_t serial, *end, *k, keycode;
@@ -1591,24 +1627,13 @@ _e_comp_wl_cb_key_up(void *event)
    /* If a key down event have been sent to clients, send a key up event to client for garantee key event sequence pair. (down/up) */
    if (delivered_key || ((!e_client_action_get()) && (!e_comp->input_key_grabs) && (!e_menu_grab_window_get())))
      {
-        if ((ec = e_client_focused_get()))
-          {
-             if (ec->comp_data->surface)
-               {
-                  struct wl_client *wc;
-                  struct wl_resource *res;
-                  Eina_List *l;
+        struct wl_resource *res;
+        Eina_List *l;
 
-                  wc = wl_resource_get_client(ec->comp_data->surface);
-                  serial = wl_display_next_serial(cdata->wl.disp);
-                  EINA_LIST_FOREACH(cdata->kbd.resources, l, res)
-                    {
-                       if (wl_resource_get_client(res) != wc) continue;
-                       wl_keyboard_send_key(res, serial, ev->timestamp,
-                                            keycode, WL_KEYBOARD_KEY_STATE_RELEASED);
-                    }
-               }
-          }
+        serial = wl_display_next_serial(cdata->wl.disp);
+        EINA_LIST_FOREACH(cdata->kbd.focused, l, res)
+          wl_keyboard_send_key(res, serial, ev->timestamp,
+                               keycode, WL_KEYBOARD_KEY_STATE_RELEASED);
      }
 
    if (cdata->kbd.mod_changed)
index 64c79f0..3a495a9 100644 (file)
@@ -172,6 +172,7 @@ struct _E_Comp_Wl_Data
    struct
      {
         Eina_List *resources;
+        Eina_List *focused;
         Eina_Bool enabled : 1;
         xkb_mod_index_t mod_shift, mod_caps;
         xkb_mod_index_t mod_ctrl, mod_alt;
@@ -289,7 +290,7 @@ struct _E_Comp_Wl_Client_Data
 {
    struct wl_resource *wl_surface;
 
-   Ecore_Timer *first_draw_tmr;
+   Ecore_Timer *on_focus_timer;
 
    struct
      {
index ba569f3..8571114 100644 (file)
@@ -186,11 +186,16 @@ static void
 _e_comp_wl_input_cb_keyboard_unbind(struct wl_resource *resource)
 {
    E_Comp_Data *cdata;
+   Eina_List *l, *ll;
+   struct wl_resource *res;
 
    /* get compositor data */
    if (!(cdata = wl_resource_get_user_data(resource))) return;
 
    cdata->kbd.resources = eina_list_remove(cdata->kbd.resources, resource);
+   EINA_LIST_FOREACH_SAFE(cdata->kbd.focused, l, ll, res)
+     if (res == resource)
+       cdata->kbd.focused = eina_list_remove_list(cdata->kbd.resources, l);
 }
 
 static void
index 427f569..41cd3b8 100644 (file)
@@ -759,6 +759,7 @@ _e_config_edd_init(Eina_Bool old)
    E_CONFIG_VAL(D, T, xkb.dont_touch_my_damn_keyboard, UCHAR);
    E_CONFIG_VAL(D, T, xkb.default_model, STR);
    E_CONFIG_VAL(D, T, xkb.use_cache, UCHAR);
+   E_CONFIG_VAL(D, T, xkb.delay_held_key_input_to_focus, UINT);
 
    E_CONFIG_VAL(D, T, keyboard.repeat_delay, INT);
    E_CONFIG_VAL(D, T, keyboard.repeat_rate, INT);
@@ -1548,6 +1549,8 @@ e_config_load(void)
    E_CONFIG_LIMIT(e_config->keyboard.repeat_delay, -1, 1000); // 1 second
    E_CONFIG_LIMIT(e_config->keyboard.repeat_rate, -1, 1000); // 1 second
 
+   E_CONFIG_LIMIT(e_config->xkb.delay_held_key_input_to_focus, 0,5000); // 1 second
+
    if (!e_config->icon_theme)
      e_config->icon_theme = eina_stringshare_add("hicolor");  // FDO default
 
index 1f65021..e461d8b 100644 (file)
@@ -430,6 +430,7 @@ struct _E_Config
       E_Config_XKB_Layout *lock_layout;
       Eina_Bool dont_touch_my_damn_keyboard;
       Eina_Bool use_cache;
+      unsigned int delay_held_key_input_to_focus;
 
       /* NO LONGER USED BECAUSE I SUCK
        * -zmike, 31 January 2013