e_dnd: move mouse motion callback for drag to e_dnd
[platform/upstream/enlightenment.git] / src / bin / e_comp_wl.c
index 445d6cc..f00f5d7 100644 (file)
@@ -1,17 +1,58 @@
-#include "e.h"
-#include "e_foreign.h"
-#include "e_wtz_shell.h"
-#include "e_comp_wl_private.h"
-#include <tizen-extension-server-protocol.h>
 
+#include "e_comp_wl_intern.h"
+#include "e_main_intern.h"
+#include "e_foreign_intern.h"
+#include "e_wtz_shell_intern.h"
+#include "e_client_intern.h"
+#include "e_appinfo_intern.h"
+#include "e_blender_intern.h"
+#include "e_utils_intern.h"
+#include "e_scale_intern.h"
+#include "e_comp_canvas_intern.h"
+#include "e_comp_screen_intern.h"
+#include "e_comp_wl_capture_intern.h"
+#include "e_comp_wl_data_intern.h"
+#include "e_comp_wl_input_intern.h"
+#include "e_comp_wl_renderer_intern.h"
+#include "e_comp_wl_rsm_intern.h"
+#include "e_comp_wl_screenshooter_intern.h"
+#include "e_comp_wl_shell_intern.h"
+#include "e_comp_wl_subsurface_intern.h"
+#include "e_comp_wl_tbm_intern.h"
+#include "e_comp_wl_viewport_intern.h"
+#include "e_comp_intern.h"
+#include "e_input_intern.h"
+#include "e_keyrouter_intern.h"
+#include "e_error_intern.h"
+#include "e_pointer_intern.h"
+#include "e_presentation_time_intern.h"
+#include "e_grabinput_intern.h"
+#include "e_env_intern.h"
+#include "e_dnd_intern.h"
+#include "e_policy_visibility_intern.h"
+#include "e_compositor_intern.h"
+#include "e_client_video_intern.h"
+#include "e_comp_wl_video_intern.h"
+#include "e_comp_object_intern.h"
+#include "e_desk_intern.h"
+#include "e_zone_intern.h"
+#include "e_hints_intern.h"
+#include "e_comp_input_intern.h"
+#include "e_blur_intern.h"
+#include "e_input_thread_client_intern.h"
+
+#include <tizen-extension-server-protocol.h>
 #include <relative-pointer-unstable-v1-server-protocol.h>
 #include <pointer-constraints-unstable-v1-server-protocol.h>
 
 #include <wayland-tbm-server.h>
 #include <glib.h>
-
 #include <libds/log.h>
 #include <libds/single_pixel_buffer_v1.h>
+#include <Evas_GL.h>
+
+ #include <ctype.h>
+ #include <sys/resource.h>
 
 /* handle include for printing uint64_t */
 #define __STDC_FORMAT_MACROS
@@ -46,12 +87,21 @@ typedef struct _E_Comp_Wl_Key_Data
    Ecore_Device *dev;
 } E_Comp_Wl_Key_Data;
 
+struct _E_Comp_Wl_Evas_Gl
+{
+   Evas_GL *gl;
+   Evas_GL_Config *glcfg;
+   Evas_GL_Context *glctx;
+   Evas_GL_Surface *glsfc;
+   Evas_GL_API *glapi;
+};
+
 static Eina_List *handlers = NULL;
 static E_Client *cursor_timer_ec = NULL;
 static Eina_Bool need_send_released = EINA_FALSE;
 static Eina_Bool need_send_motion = EINA_TRUE;
 
-static GMutex flush_mutex;
+static GMutex connection_mutex;
 
 static int _e_comp_wl_hooks_delete = 0;
 static int _e_comp_wl_hooks_walking = 0;
@@ -220,9 +270,7 @@ _e_comp_wl_configure_send(E_Client *ec, Eina_Bool edges, Eina_Bool send_size)
         w = h = -1;
      }
 
-   ec->comp_data->shell.configure_send(ec->comp_data->shell.surface,
-                                       edges * e_comp_wl->resize.edges,
-                                       w, h);
+   e_client_shell_configure_send(ec, edges * e_comp_wl->resize.edges, w, h);
 }
 
 static void
@@ -237,17 +285,6 @@ _e_comp_wl_focus_check(void)
 }
 
 static Eina_Bool
-_e_comp_wl_cb_idle_exiter(void *data EINA_UNUSED)
-{
-   e_comp_wl->idle_exiter_timestamp = ecore_time_get() * 1000;
-
-   TRACE_DS_ASYNC_BEGIN((intptr_t)&e_comp_wl->idle_exiter_timestamp,
-                        IDLE_EXITER~CB_PREPARE);
-
-   return ECORE_CALLBACK_RENEW;
-}
-
-static Eina_Bool
 _e_comp_wl_cb_read(void *data EINA_UNUSED, Ecore_Fd_Handler *hdlr EINA_UNUSED)
 {
    /* dispatch pending wayland events */
@@ -261,19 +298,43 @@ e_comp_wl_display_flush()
 {
    if (e_comp_wl && e_comp_wl->wl.disp)
      {
-        g_mutex_lock(&flush_mutex);
+        if (e_config->key_input_ttrace_enable)
+          {
+             TRACE_INPUT_BEGIN(wl_display_flush_clients);
+             ELOGF("INPUT", "wl_display_flush_clients|B|", NULL);
+          }
+
+        g_mutex_lock(&connection_mutex);
         wl_display_flush_clients(e_comp_wl->wl.disp);
-        g_mutex_unlock(&flush_mutex);
+        g_mutex_unlock(&connection_mutex);
+
+        if (e_config->key_input_ttrace_enable)
+          {
+             TRACE_INPUT_END();
+             ELOGF("INPUT", "wl_display_flush_clients|E|", NULL);
+          }
      }
 }
 
+EINTERN void
+e_comp_wl_connection_lock()
+{
+   e_input_boost_lock(&connection_mutex);
+}
+
+EINTERN void
+e_comp_wl_connection_unlock()
+{
+   e_input_boost_unlock(&connection_mutex);
+}
+
 void
 e_comp_wl_focused_client_flush()
 {
    E_Client *focused_ec;
    if (!(e_comp_wl && e_comp_wl->wl.disp)) return;
 
-   g_mutex_lock(&flush_mutex);
+   e_input_boost_lock(&connection_mutex);
    focused_ec = e_client_focused_get();
 
    if (focused_ec)
@@ -282,7 +343,7 @@ e_comp_wl_focused_client_flush()
         struct wl_resource *surface = e_comp_wl_client_surface_get(focused_ec);
         if (!surface)
           {
-            g_mutex_unlock(&flush_mutex);
+            e_input_boost_unlock(&connection_mutex);
             return;
           }
 
@@ -290,7 +351,7 @@ e_comp_wl_focused_client_flush()
         wl_client_flush(wc);
      }
 
-   g_mutex_unlock(&flush_mutex);
+   e_input_boost_unlock(&connection_mutex);
 }
 
 static void
@@ -317,6 +378,23 @@ _e_comp_wl_cb_prepare(void *data EINA_UNUSED, Ecore_Fd_Handler *hdlr EINA_UNUSED
 
    TRACE_DS_ASYNC_END((intptr_t)&e_comp_wl->idle_exiter_timestamp,
                       IDLE_EXITER~CB_PREPARE);
+
+   // _e_comp_wl_cb_prepare() function is called before idle state in ecore_main_loop.
+   // idle state means that epoll() or select() is called in ecore_main_loop.
+   e_main_hook_call(E_MAIN_HOOK_LOOP_BEFORE_IDLE_ENTER);
+}
+
+static void
+_e_comp_wl_cb_awake(void *data)
+{
+   e_comp_wl->idle_exiter_timestamp = ecore_time_get() * 1000;
+
+   TRACE_DS_ASYNC_BEGIN((intptr_t)&e_comp_wl->idle_exiter_timestamp,
+                        IDLE_EXITER~CB_PREPARE);
+
+   // _e_comp_wl_cb_awake() function is called after idle state in ecore_main_loop.
+   // ecore_main_loop awake due to returning from epoll() or select()
+   e_main_hook_call(E_MAIN_HOOK_LOOP_AFTER_IDLE_EXIT);
 }
 
 E_API enum wl_output_transform
@@ -713,12 +791,9 @@ _e_comp_wl_evas_cb_move(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_U
         e_comp_wl_subsurface_global_coord_get(subc, &x, &y);
         evas_object_move(subc->frame, x, y);
 
-        if (subc->comp_data->scaler.viewport)
-          {
-             E_Comp_Wl_Client_Data *cdata = subc->comp_data;
-             if (cdata->viewport_transform)
-               e_comp_wl_map_apply(subc);
-          }
+        E_Comp_Wl_Client_Data *cdata = subc->comp_data;
+        if (cdata->viewport_transform)
+          e_comp_wl_map_apply(subc);
      }
 
    EINA_LIST_FOREACH(ec->comp_data->sub.below_list, l, subc)
@@ -727,12 +802,9 @@ _e_comp_wl_evas_cb_move(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_U
         e_comp_wl_subsurface_global_coord_get(subc, &x, &y);
         evas_object_move(subc->frame, x, y);
 
-        if (subc->comp_data->scaler.viewport)
-          {
-             E_Comp_Wl_Client_Data *cdata = subc->comp_data;
-             if (cdata->viewport_transform)
-               e_comp_wl_map_apply(subc);
-          }
+        E_Comp_Wl_Client_Data *cdata = subc->comp_data;
+        if (cdata->viewport_transform)
+          e_comp_wl_map_apply(subc);
      }
 
    if (ec->comp_data->sub.below_obj)
@@ -794,9 +866,7 @@ _e_comp_wl_device_last_device_get(Ecore_Device_Class dev_class)
       case ECORE_DEVICE_CLASS_MOUSE:
          return e_devicemgr->last_device_ptr;
       case ECORE_DEVICE_CLASS_KEYBOARD:
-         g_rec_mutex_lock(&e_devicemgr->last_device_kbd_mutex);
-         last_kbd = e_devicemgr->last_device_kbd;
-         g_rec_mutex_unlock(&e_devicemgr->last_device_kbd_mutex);
+         last_kbd = atomic_load(&e_devicemgr->last_device_kbd);
          return last_kbd;
       case ECORE_DEVICE_CLASS_TOUCH:
          return e_devicemgr->last_device_touch;
@@ -815,9 +885,7 @@ _e_comp_wl_device_last_device_set(Ecore_Device_Class dev_class, E_Devicemgr_Inpu
          e_devicemgr->last_device_ptr = device;
          break;
       case ECORE_DEVICE_CLASS_KEYBOARD:
-         g_rec_mutex_lock(&e_devicemgr->last_device_kbd_mutex);
-         e_devicemgr->last_device_kbd = device;
-         g_rec_mutex_unlock(&e_devicemgr->last_device_kbd_mutex);
+         atomic_store(&e_devicemgr->last_device_kbd, device);
          break;
       case ECORE_DEVICE_CLASS_TOUCH:
          e_devicemgr->last_device_touch = device;
@@ -837,9 +905,7 @@ _e_comp_wl_device_client_last_device_get(E_Client *ec, Ecore_Device_Class dev_cl
       case ECORE_DEVICE_CLASS_MOUSE:
          return ec->comp_data->last_device_ptr;
       case ECORE_DEVICE_CLASS_KEYBOARD:
-         g_rec_mutex_lock(&ec->comp_data->last_device_kbd_mutex);
-         last_kbd = ec->comp_data->last_device_kbd;
-         g_rec_mutex_unlock(&ec->comp_data->last_device_kbd_mutex);
+         last_kbd = atomic_load(&ec->comp_data->last_device_kbd);
          return last_kbd;
       case ECORE_DEVICE_CLASS_TOUCH:
          return ec->comp_data->last_device_touch;
@@ -858,9 +924,7 @@ _e_comp_wl_device_client_last_device_set(E_Client *ec, Ecore_Device_Class dev_cl
          ec->comp_data->last_device_ptr = device;
          break;
       case ECORE_DEVICE_CLASS_KEYBOARD:
-         g_rec_mutex_lock(&ec->comp_data->last_device_kbd_mutex);
-         ec->comp_data->last_device_kbd = device;
-         g_rec_mutex_unlock(&ec->comp_data->last_device_kbd_mutex);
+         atomic_store(&ec->comp_data->last_device_kbd, device);
          break;
       case ECORE_DEVICE_CLASS_TOUCH:
          ec->comp_data->last_device_touch = device;
@@ -1053,6 +1117,9 @@ _e_comp_wl_cursor_timer(void *data)
 {
    E_Client *ec = data;
 
+   ELOGF("Mouse", "Cursor hide timer expired after %d sec.", ec, e_config->cursor_timer_interval);
+   if (e_comp_wl->relative_ptr.activated) return ECORE_CALLBACK_CANCEL;
+
    e_comp_wl_cursor_hide(ec);
 
    return ECORE_CALLBACK_CANCEL;
@@ -1219,6 +1286,22 @@ _e_comp_wl_check_cursor_timer_needed(E_Client *ec)
    return EINA_TRUE;
 }
 
+static Eina_Bool
+_e_comp_wl_check_block_input(E_Client *ec)
+{
+   E_Client *modal_child = e_client_modal_child_get(ec);
+   if (modal_child)
+     {
+        if (modal_child->visible && !modal_child->iconic && (modal_child->visibility.obscured == E_VISIBILITY_UNOBSCURED))
+          {
+             ELOGF("Touch", "Block touch by Modal child(ec:%p, win:0x%08zx)", ec, modal_child, e_client_util_win_get(modal_child));
+             return EINA_TRUE;
+          }
+     }
+
+   return EINA_FALSE;
+}
+
 static void
 _e_comp_wl_evas_cb_mouse_in(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj, void *event)
 {
@@ -1233,8 +1316,8 @@ _e_comp_wl_evas_cb_mouse_in(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj
 
    ev = event;
 
-   e_comp_wl->ptr.x = wl_fixed_from_int(ev->canvas.x);
-   e_comp_wl->ptr.y = wl_fixed_from_int(ev->canvas.y);
+   e_comp_wl->ptr.x = wl_fixed_from_int(ev->output.x);
+   e_comp_wl->ptr.y = wl_fixed_from_int(ev->output.y);
 
    if (!(ec = data)) return;
    if (e_object_is_del(E_OBJECT(ec))) return;
@@ -1277,8 +1360,10 @@ _e_comp_wl_evas_cb_mouse_in(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj
                               wl_fixed_from_int(ev->canvas.y - ec->client.y));
         ec->pointer_enter_sent = EINA_TRUE;
      }
-
-   wl_signal_emit(&e_comp_wl->ptr_constraints.surface_mousein_signal, ec);
+   if (ev->timestamp)
+     wl_signal_emit(&e_comp_wl->ptr_constraints.surface_mousein_signal, ec);
+   else
+     ELOGF("Mouse", "In. Event doesn't have timestamp. no need to send signal", NULL);
 }
 
 static void
@@ -1334,6 +1419,10 @@ _e_comp_wl_evas_cb_mouse_out(void *data, Evas *evas EINA_UNUSED, Evas_Object *ob
         wl_pointer_send_leave(res, serial, surface);
         ec->pointer_enter_sent = EINA_FALSE;
      }
+   if (ev->timestamp)
+     wl_signal_emit(&e_comp_wl->ptr_constraints.surface_mouseout_signal, ec);
+   else
+     ELOGF("Mouse", "Out. Event doesn't have timestamp. no need to send signal", NULL);
 }
 
 static void
@@ -1348,6 +1437,8 @@ _e_comp_wl_send_touch(E_Client *ec, int idx, int canvas_x, int canvas_y, uint32_
 
    if (!ec) return;
    if (e_object_is_del(E_OBJECT(ec))) return;
+   if (_e_comp_wl_check_block_input(ec)) return;
+
    struct wl_resource *surface = e_comp_wl_client_surface_get(ec);
    if (!surface) return;
 
@@ -1396,6 +1487,8 @@ _e_comp_wl_send_touch_move(E_Client *ec, int idx, int canvas_x, int canvas_y, ui
    if (!ec) return;
    if (ec->cur_mouse_action) return;
    if (e_object_is_del(E_OBJECT(ec))) return;
+   if (_e_comp_wl_check_block_input(ec)) return;
+
    struct wl_resource *surface = e_comp_wl_client_surface_get(ec);
    if (!surface) return;
 
@@ -1480,7 +1573,7 @@ _e_comp_wl_evas_cb_mouse_move(void *data, Evas *evas EINA_UNUSED, Evas_Object *o
    struct wl_resource *surface = e_comp_wl_client_surface_get(ec);
    if (!surface) return;
 
-   if ((!need_send_motion) && (!need_send_released) && (ec->visibility.obscured == E_VISIBILITY_FULLY_OBSCURED)) return;
+   if ((!need_send_motion) && (!need_send_released) && (e_client_visibility_get(ec) == E_VISIBILITY_FULLY_OBSCURED)) return;
 
    dev = ev->dev;
    dev_name = evas_device_description_get(dev);
@@ -1558,6 +1651,7 @@ _e_comp_wl_evas_cb_mouse_down(void *data, Evas *evas EINA_UNUSED, Evas_Object *o
 
    if (!ec) return;
    if (e_object_is_del(E_OBJECT(ec))) return;
+   if (_e_comp_wl_check_block_input(ec)) return;
 
    dev = ev->dev;
    dev_name = evas_device_description_get(dev);
@@ -1616,6 +1710,7 @@ _e_comp_wl_evas_cb_mouse_up(void *data, Evas *evas, Evas_Object *obj, void *even
    if (!ec) return;
    if (ec->cur_mouse_action) return;
    if (e_object_is_del(E_OBJECT(ec))) return;
+   if (_e_comp_wl_check_block_input(ec)) return;
 
    if (!need_send_released)
      {
@@ -1752,6 +1847,8 @@ _e_comp_wl_evas_cb_multi_down(void *data, Evas *evas EINA_UNUSED, Evas_Object *o
 
    if (!ec) return;
    if (e_object_is_del(E_OBJECT(ec))) return;
+   if (_e_comp_wl_check_block_input(ec)) return;
+
    struct wl_resource *surface = e_comp_wl_client_surface_get(ec);
    if (!surface) return;
 
@@ -1796,6 +1893,8 @@ _e_comp_wl_evas_cb_multi_up(void *data, Evas *evas, Evas_Object *obj EINA_UNUSED
 
    if (!ec) return;
    if (e_object_is_del(E_OBJECT(ec))) return;
+   if (_e_comp_wl_check_block_input(ec)) return;
+
    struct wl_resource *surface = e_comp_wl_client_surface_get(ec);
    if (!surface) return;
 
@@ -1931,8 +2030,8 @@ _e_comp_wl_client_priority_normal(E_Client *ec)
                                      EINA_FALSE, EINA_TRUE, EINA_FALSE);
 }
 
-static Eina_Bool
-_e_comp_wl_evas_cb_focus_in_timer(E_Client *ec)
+static void
+_e_comp_wl_input_thread_send_keys()
 {
    uint32_t serial;
    E_Comp_Wl_Key_Data *k;
@@ -1940,38 +2039,71 @@ _e_comp_wl_evas_cb_focus_in_timer(E_Client *ec)
    Eina_List *l;
    double t;
 
-   if (!ec) return EINA_FALSE;
-   if (e_object_is_del(E_OBJECT(ec))) return EINA_FALSE;
-   if (!ec->comp_data) return EINA_FALSE;
-
-   ec->comp_data->on_focus_timer = NULL;
-   g_mutex_lock(&e_comp_wl->kbd.focused_mutex);
-   if (!e_comp_wl->kbd.focused)
+   if (!e_comp_input_key->kbd.focused)
      {
-        g_mutex_unlock(&e_comp_wl->kbd.focused_mutex);
-        return EINA_FALSE;
+        return;
      }
-   g_mutex_unlock(&e_comp_wl->kbd.focused_mutex);
 
    serial = wl_display_next_serial(e_comp_wl->wl.disp);
    t = ecore_time_unix_get();
 
-   g_mutex_lock(&e_comp_wl->kbd.focused_mutex);
-   g_mutex_lock(&e_comp_wl->kbd.keys_mutex);
-   EINA_LIST_FOREACH(e_comp_wl->kbd.focused, l, res)
+   EINA_LIST_FOREACH(e_comp_input_key->kbd.focused, l, res)
      {
-        wl_array_for_each(k, &e_comp_wl->kbd.keys)
+        wl_array_for_each(k, &e_comp_input_key->kbd.keys)
           {
              _e_comp_wl_send_event_device(wl_resource_get_client(res), t, k->dev, serial);
              wl_keyboard_send_key(res, serial, t,
                                   k->key, WL_KEYBOARD_KEY_STATE_PRESSED);
           }
      }
-   g_mutex_unlock(&e_comp_wl->kbd.keys_mutex);
-   g_mutex_unlock(&e_comp_wl->kbd.focused_mutex);
+}
+
+static Eina_Bool
+_e_comp_wl_evas_cb_focus_in_timer(E_Client *ec)
+{
+   if (!ec) return EINA_FALSE;
+   if (e_object_is_del(E_OBJECT(ec))) return EINA_FALSE;
+   if (!ec->comp_data) return EINA_FALSE;
+
+   ec->comp_data->on_focus_timer = NULL;
+
+   e_input_thread_safe_call(_e_comp_wl_input_thread_send_keys, NULL, 0);
+
    return EINA_FALSE;
 }
 
+static void
+_e_comp_wl_input_thread_focus_in(void *data)
+{
+   struct wl_resource *surface = NULL;
+   struct wl_resource *res;
+   struct wl_client *wc;
+   Eina_List *l;
+
+   EINA_SAFETY_ON_NULL_RETURN(data);
+   surface = *(struct wl_resource **)data;
+
+   wc = wl_resource_get_client(surface);
+
+   EINA_LIST_FOREACH(e_comp_input_key->kbd.resources, l, res)
+     {
+        if (wl_resource_get_client(res) == wc)
+          {
+             if (!eina_list_data_find(e_comp_input_key->kbd.focused, res))
+               e_comp_input_key->kbd.focused = eina_list_append(e_comp_input_key->kbd.focused, res);
+          }
+     }
+
+   if (!e_comp_input_key->kbd.focused)
+     {
+        return;
+     }
+
+   e_comp_input_key->kbd.focus = surface;
+   e_comp_wl_input_keyboard_enter_send(surface);
+   e_comp_wl_data_device_keyboard_focus_set();
+}
+
 /* It is called in the following cases:
  *  When a normal ec->frame has focus.
  *  Or launching image ec is replaced to the real ec.
@@ -1980,9 +2112,6 @@ EINTERN void
 e_comp_wl_feed_focus_in(E_Client *ec)
 {
    E_Client *focused;
-   struct wl_resource *res;
-   struct wl_client *wc;
-   Eina_List *l;
 
    if (!ec) return;
    if (e_object_is_del(E_OBJECT(ec))) return;
@@ -1994,35 +2123,13 @@ e_comp_wl_feed_focus_in(E_Client *ec)
 
    /* raise client priority */
    _e_comp_wl_client_priority_raise(ec);
+
    struct wl_resource *surface = e_comp_wl_client_surface_get(ec);
    if (!surface) return;
 
-   wc = wl_resource_get_client(surface);
-
-   g_mutex_lock(&e_comp_wl->kbd.resource_mutex);
-   EINA_LIST_FOREACH(e_comp_wl->kbd.resources, l, res)
-     {
-        if (wl_resource_get_client(res) == wc)
-          {
-             g_mutex_lock(&e_comp_wl->kbd.focused_mutex);
-             if (!eina_list_data_find(e_comp_wl->kbd.focused, res))
-               e_comp_wl->kbd.focused = eina_list_append(e_comp_wl->kbd.focused, res);
-             g_mutex_unlock(&e_comp_wl->kbd.focused_mutex);
-          }
-     }
-   g_mutex_unlock(&e_comp_wl->kbd.resource_mutex);
+   INF("send focus in request to input thread. surface(%p)\n", surface);
+   e_input_thread_safe_call(_e_comp_wl_input_thread_focus_in, (void *)&surface, sizeof(struct wl_resource *));
 
-   g_mutex_lock(&e_comp_wl->kbd.focused_mutex);
-   if (!e_comp_wl->kbd.focused)
-     {
-        g_mutex_unlock(&e_comp_wl->kbd.focused_mutex);
-        return;
-     }
-   g_mutex_unlock(&e_comp_wl->kbd.focused_mutex);
-
-   e_comp_wl->kbd.focus = surface;
-   e_comp_wl_input_keyboard_enter_send(ec);
-   e_comp_wl_data_device_keyboard_focus_set();
    ec->comp_data->on_focus_timer =
       ecore_timer_add(((e_config->xkb.delay_held_key_input_to_focus)/1000.0),
                       (Ecore_Task_Cb)_e_comp_wl_evas_cb_focus_in_timer, ec);
@@ -2039,282 +2146,65 @@ _e_comp_wl_evas_cb_focus_in(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj
 }
 
 static void
-_e_comp_wl_evas_cb_focus_out(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
+_e_comp_wl_input_thread_focus_out(void *data)
 {
-   E_Client *ec;
+   struct wl_resource *surface = NULL;
    struct wl_resource *res;
    uint32_t serial;
    E_Comp_Wl_Key_Data *k;
    Eina_List *l, *ll;
    double t;
 
-   if (!(ec = data)) return;
-
-   if (!ec->comp_data) return;
-
-   E_FREE_FUNC(ec->comp_data->on_focus_timer, ecore_timer_del);
-
-   /* lower client priority */
-   if (!e_object_is_del(data))
-     _e_comp_wl_client_priority_normal(ec);
+   EINA_SAFETY_ON_NULL_RETURN(data);
 
+   surface = *(struct wl_resource **)data;
 
    /* update keyboard modifier state */
-   g_mutex_lock(&e_comp_wl->kbd.keys_mutex);
-   wl_array_for_each(k, &e_comp_wl->kbd.keys)
+   wl_array_for_each(k, &e_comp_input_key->kbd.keys)
       e_comp_wl_input_keyboard_state_update(k->key, EINA_FALSE);
 
-   g_mutex_unlock(&e_comp_wl->kbd.keys_mutex);
-
-   struct wl_resource *surface = e_comp_wl_client_surface_get(ec);
    if (!surface) return;
 
-   g_mutex_lock(&e_comp_wl->kbd.resource_mutex);
-   if (!eina_list_count(e_comp_wl->kbd.resources))
+   if (!eina_list_count(e_comp_input_key->kbd.resources))
      {
-        g_mutex_unlock(&e_comp_wl->kbd.resource_mutex);
         return;
      }
 
-   g_mutex_unlock(&e_comp_wl->kbd.resource_mutex);
-
    /* send keyboard_leave to all keyboard resources */
    serial = wl_display_next_serial(e_comp_wl->wl.disp);
    t = ecore_time_unix_get();
 
-   g_mutex_lock(&e_comp_wl->kbd.focused_mutex);
-   g_mutex_lock(&e_comp_wl->kbd.keys_mutex);
-   EINA_LIST_FOREACH_SAFE(e_comp_wl->kbd.focused, l, ll, res)
+   EINA_LIST_FOREACH_SAFE(e_comp_input_key->kbd.focused, l, ll, res)
      {
-        wl_array_for_each(k, &e_comp_wl->kbd.keys)
+        wl_array_for_each(k, &e_comp_input_key->kbd.keys)
           {
              _e_comp_wl_send_event_device(wl_resource_get_client(res), t, k->dev, serial);
               wl_keyboard_send_key(res, serial, t,
                                    k->key, WL_KEYBOARD_KEY_STATE_RELEASED);
           }
         wl_keyboard_send_leave(res, serial, surface);
-        e_comp_wl->kbd.focused =
-           eina_list_remove_list(e_comp_wl->kbd.focused, l);
+        e_comp_input_key->kbd.focused =
+           eina_list_remove_list(e_comp_input_key->kbd.focused, l);
      }
-   g_mutex_unlock(&e_comp_wl->kbd.keys_mutex);
-   g_mutex_unlock(&e_comp_wl->kbd.focused_mutex);
 }
 
 static void
-_e_comp_wl_evas_cb_resize(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
-{
-   E_Client *ec;
-
-   if (!(ec = data)) return;
-
-   if ((ec->shading) || (ec->shaded)) return;
-   if (!ec->comp_data->shell.configure_send) return;
-
-   /* TODO: calculate x, y with transfrom object */
-   if ((e_client_util_resizing_get(ec)) && (!ec->transformed) && (e_comp_wl->resize.edges))
-     {
-        int w, h;
-
-        w = ec->mouse.last_down[ec->moveinfo.down.button - 1].w;
-        h = ec->mouse.last_down[ec->moveinfo.down.button - 1].h;
-        if (e_comp_object_frame_exists(ec->frame))
-          e_comp_object_frame_wh_unadjust(ec->frame, w, h, &w, &h);
-
-        switch (ec->resize_mode)
-          {
-           case E_POINTER_RESIZE_TL:
-           case E_POINTER_RESIZE_L:
-           case E_POINTER_RESIZE_BL:
-             w += ec->mouse.last_down[ec->moveinfo.down.button - 1].mx -
-               ec->mouse.current.mx;
-             break;
-           case E_POINTER_RESIZE_TR:
-           case E_POINTER_RESIZE_R:
-           case E_POINTER_RESIZE_BR:
-             w += ec->mouse.current.mx - ec->mouse.last_down[ec->moveinfo.down.button - 1].mx;
-             break;
-           default:
-             break;;
-          }
-        switch (ec->resize_mode)
-          {
-           case E_POINTER_RESIZE_TL:
-           case E_POINTER_RESIZE_T:
-           case E_POINTER_RESIZE_TR:
-             h += ec->mouse.last_down[ec->moveinfo.down.button - 1].my -
-               ec->mouse.current.my;
-             break;
-           case E_POINTER_RESIZE_BL:
-           case E_POINTER_RESIZE_B:
-           case E_POINTER_RESIZE_BR:
-             h += ec->mouse.current.my - ec->mouse.last_down[ec->moveinfo.down.button - 1].my;
-             break;
-           default:
-             break;
-          }
-        w = E_CLAMP(w, 1, w);
-        h = E_CLAMP(h, 1, h);
-        e_client_resize_limit(ec, &w, &h);
-
-        ec->comp_data->shell.configure_send(ec->comp_data->shell.surface,
-                                            e_comp_wl->resize.edges,
-                                            w, h);
-     }
-   else if ((!ec->fullscreen) && (!ec->maximized) &&
-            (!ec->comp_data->maximize_pre))
-     {
-        int pw = 0;
-        int ph = 0;
-        e_pixmap_size_get(ec->pixmap, &pw, &ph);
-        if ((pw != ec->w) || (ph != ec->h))
-          {
-             _e_comp_wl_configure_send(ec, 1, 1);
-          }
-     }
-
-   if (ec->comp_data->sub.below_obj)
-     e_comp_wl_subsurface_bg_rectangle_map_apply(ec);
-}
-
-static void
-_e_comp_wl_evas_cb_maximize_pre(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
-{
-   E_Client *ec = data;
-
-   ec->comp_data->maximize_pre = 1;
-}
-
-static void
-_e_comp_wl_evas_cb_maximize_done(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
-{
-   E_Client *ec = data;
-   int w, h;
-
-   if (e_object_is_del(E_OBJECT(ec))) return;
-
-   if (ec->comp_data->shell.configure_send)
-     {
-        e_client_maximized_geometry_get(ec, NULL, NULL, &w, &h);
-        ec->comp_data->shell.configure_send(ec->comp_data->shell.surface, 0, w, h);
-     }
-   ec->comp_data->maximize_pre = 0;
-}
-
-static void
-_e_comp_wl_evas_cb_unmaximize_pre(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
-{
-   E_Client *ec = data;
-
-   ec->comp_data->maximize_pre = 1;
-}
-
-static void
-_e_comp_wl_evas_cb_unmaximize_done(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
-{
-   E_Client *ec = data;
-
-   if (e_object_is_del(E_OBJECT(ec))) return;
-
-   /* check for wayland pixmap */
-
-   if (ec->comp_data->shell.configure_send)
-     _e_comp_wl_configure_send(ec, 0, 0);
-
-   ec->comp_data->maximize_pre = 0;
-}
-
-static void
-_e_comp_wl_evas_cb_fullscreen(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
-{
-   E_Client *ec = data;
-
-   if (e_object_is_del(E_OBJECT(ec))) return;
-
-   /* check for wayland pixmap */
-
-   if (ec->comp_data->shell.configure_send)
-     _e_comp_wl_configure_send(ec, 0, 1);
-
-   ec->comp_data->maximize_pre = 0;
-}
-
-static void
-_e_comp_wl_evas_cb_unfullscreen(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
-{
-   E_Client *ec = data;
-
-   if (e_object_is_del(E_OBJECT(ec))) return;
-
-   /* check for wayland pixmap */
-
-   if (ec->comp_data->shell.configure_send)
-     _e_comp_wl_configure_send(ec, 0, 0);
-
-   ec->comp_data->maximize_pre = 0;
-}
-
-static void
-_e_comp_wl_evas_cb_delete_request(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
-{
-   E_Client *ec;
-
-   if (!(ec = data)) return;
-
-   e_comp_ignore_win_del(E_PIXMAP_TYPE_WL, e_pixmap_window_get(ec->pixmap));
-
-   e_object_del(E_OBJECT(ec));
-
-   _e_comp_wl_focus_check();
-
-   /* TODO: Delete request send ??
-    * NB: No such animal wrt wayland */
-}
-
-static void
-_e_comp_wl_evas_cb_kill_request(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
+_e_comp_wl_evas_cb_focus_out(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
 {
    E_Client *ec;
-
    if (!(ec = data)) return;
 
-   e_comp_ignore_win_del(E_PIXMAP_TYPE_WL, e_pixmap_window_get(ec->pixmap));
-   if (ec->comp_data)
-     {
-        if (ec->comp_data->reparented)
-          e_client_comp_hidden_set(ec, EINA_TRUE);
-     }
-
-   evas_object_pass_events_set(ec->frame, EINA_TRUE);
-   if (ec->visible) evas_object_hide(ec->frame);
-   if (!ec->internal) e_object_del(E_OBJECT(ec));
-
-   _e_comp_wl_focus_check();
-}
-
-static void
-_e_comp_wl_evas_cb_ping(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
-{
-   E_Client *ec;
-
-   if (!(ec = data)) return;
-   if (!(ec->comp_data)) return;
-   if (!(ec->comp_data->shell.ping)) return;
-   if (!(ec->comp_data->shell.surface)) return;
+   if (!ec->comp_data) return;
 
-   ec->comp_data->shell.ping(ec->comp_data->shell.surface);
-}
+   E_FREE_FUNC(ec->comp_data->on_focus_timer, ecore_timer_del);
 
-static void
-_e_comp_wl_evas_cb_color_set(void *data, Evas_Object *obj, void *event EINA_UNUSED)
-{
-   E_Client *ec;
-   int a = 0;
+   /* lower client priority */
+   if (!e_object_is_del(data))
+     _e_comp_wl_client_priority_normal(ec);
 
-   if (!(ec = data)) return;
-   evas_object_color_get(obj, NULL, NULL, NULL, &a);
-   if (ec->netwm.opacity == a) return;
-   ec->netwm.opacity = a;
-   ec->netwm.opacity_changed = EINA_TRUE;
+   struct wl_resource *surface = e_comp_wl_client_surface_get(ec);
+   INF("send focus out request to input thread. surface(%p)\n", surface);
+   e_input_thread_safe_call(_e_comp_wl_input_thread_focus_out, (void *)&surface, sizeof(struct wl_resource *));
 }
 
 static void
@@ -2383,25 +2273,6 @@ _e_comp_wl_client_evas_init(E_Client *ec)
    evas_object_event_callback_priority_add(ec->frame, EVAS_CALLBACK_FOCUS_IN,    EVAS_CALLBACK_PRIORITY_AFTER, _e_comp_wl_evas_cb_focus_in,    ec);
    evas_object_event_callback_priority_add(ec->frame, EVAS_CALLBACK_FOCUS_OUT,   EVAS_CALLBACK_PRIORITY_AFTER, _e_comp_wl_evas_cb_focus_out,   ec);
 
-   if (!ec->override)
-     {
-        evas_object_smart_callback_add(ec->frame, "client_resize",   _e_comp_wl_evas_cb_resize,          ec);
-        evas_object_smart_callback_add(ec->frame, "maximize_pre",    _e_comp_wl_evas_cb_maximize_pre,    ec);
-        evas_object_smart_callback_add(ec->frame, "maximize_done",   _e_comp_wl_evas_cb_maximize_done,   ec);
-        evas_object_smart_callback_add(ec->frame, "unmaximize_pre",  _e_comp_wl_evas_cb_unmaximize_pre,  ec);
-        evas_object_smart_callback_add(ec->frame, "unmaximize_done", _e_comp_wl_evas_cb_unmaximize_done, ec);
-        evas_object_smart_callback_add(ec->frame, "fullscreen",      _e_comp_wl_evas_cb_fullscreen,      ec);
-        evas_object_smart_callback_add(ec->frame, "unfullscreen",    _e_comp_wl_evas_cb_unfullscreen,    ec);
-     }
-
-   /* setup delete/kill callbacks */
-   evas_object_smart_callback_add(ec->frame, "delete_request", _e_comp_wl_evas_cb_delete_request, ec);
-   evas_object_smart_callback_add(ec->frame, "kill_request",   _e_comp_wl_evas_cb_kill_request,   ec);
-
-   /* setup ping callback */
-   evas_object_smart_callback_add(ec->frame, "ping",           _e_comp_wl_evas_cb_ping,           ec);
-   evas_object_smart_callback_add(ec->frame, "color_set",      _e_comp_wl_evas_cb_color_set,      ec);
-
    ec->comp_data->evas_init = EINA_TRUE;
 }
 
@@ -2429,23 +2300,6 @@ _e_comp_wl_client_evas_deinit(E_Client *ec)
    evas_object_event_callback_del(ec->frame, EVAS_CALLBACK_FOCUS_IN,  _e_comp_wl_evas_cb_focus_in);
    evas_object_event_callback_del(ec->frame, EVAS_CALLBACK_FOCUS_OUT, _e_comp_wl_evas_cb_focus_out);
 
-   if (!ec->override)
-     {
-        evas_object_smart_callback_del(ec->frame, "client_resize",   _e_comp_wl_evas_cb_resize);
-        evas_object_smart_callback_del(ec->frame, "maximize_pre",    _e_comp_wl_evas_cb_maximize_pre);
-        evas_object_smart_callback_del(ec->frame, "maximize_done",   _e_comp_wl_evas_cb_maximize_done);
-        evas_object_smart_callback_del(ec->frame, "unmaximize_pre",  _e_comp_wl_evas_cb_unmaximize_pre);
-        evas_object_smart_callback_del(ec->frame, "unmaximize_done", _e_comp_wl_evas_cb_unmaximize_done);
-        evas_object_smart_callback_del(ec->frame, "fullscreen",      _e_comp_wl_evas_cb_fullscreen);
-        evas_object_smart_callback_del(ec->frame, "unfullscreen",    _e_comp_wl_evas_cb_unfullscreen);
-     }
-
-   evas_object_smart_callback_del(ec->frame, "delete_request", _e_comp_wl_evas_cb_delete_request);
-   evas_object_smart_callback_del(ec->frame, "kill_request",   _e_comp_wl_evas_cb_kill_request);
-
-   evas_object_smart_callback_del(ec->frame, "ping",           _e_comp_wl_evas_cb_ping);
-   evas_object_smart_callback_del(ec->frame, "color_set",      _e_comp_wl_evas_cb_color_set);
-
    ec->comp_data->evas_init = EINA_FALSE;
 }
 
@@ -2523,65 +2377,9 @@ _e_comp_wl_cb_comp_object_add(void *data EINA_UNUSED, int type EINA_UNUSED, E_Ev
 static Eina_Bool
 _e_comp_wl_cb_mouse_move(void *d EINA_UNUSED, int t EINA_UNUSED, Ecore_Event_Mouse_Move *ev)
 {
-   int ec_x, ec_y;
-
    e_comp_wl->ptr.x = wl_fixed_from_int(ev->x);
    e_comp_wl->ptr.y = wl_fixed_from_int(ev->y);
 
-   if (e_comp_wl->selection.target &&
-       e_comp_wl->drag)
-     {
-        struct wl_resource *res;
-        int x, y;
-        E_Client *ec = NULL;
-        E_Client *legacy_target = e_comp_wl->selection.target;
-        int device_id = e_comp_wl_data_current_device_id_get();
-
-        if (device_id < 0)
-          {
-             e_comp_wl_data_current_device_id_set(ev->multi.device);
-          }
-        else if (device_id != ev->multi.device)
-          {
-             return ECORE_CALLBACK_RENEW;
-          }
-
-        ec = e_client_input_rect_under_pointer_get(legacy_target->desk, e_comp_wl->drag_client);
-        EINA_SAFETY_ON_NULL_RETURN_VAL(ec, ECORE_CALLBACK_RENEW);
-
-        struct wl_resource *surface = e_comp_wl_client_surface_get(ec);
-        EINA_SAFETY_ON_NULL_RETURN_VAL(surface, ECORE_CALLBACK_RENEW);
-
-        res = e_comp_wl_data_find_for_client(wl_resource_get_client(surface));
-        EINA_SAFETY_ON_NULL_RETURN_VAL(res, ECORE_CALLBACK_RENEW);
-
-        if ((e_comp_wl->drag_offer != wl_resource_get_user_data(res)) &&
-            (ec != legacy_target))
-          {
-             e_comp_wl_data_device_send_leave(legacy_target);
-             e_comp_wl_data_device_send_enter(ec);
-          }
-
-        if (e_comp_wl->drag)
-          e_drag_move(e_comp_wl->drag, ev->x, ev->y);
-
-        if (e_client_transform_core_enable_get(ec))
-          {
-             int trans_x, trans_y;
-             e_client_transform_core_input_transform(ec, ev->x, ev->y, &trans_x, &trans_y);
-             x = trans_x - ec->client.x;
-             y = trans_y - ec->client.y;
-          }
-        else
-          {
-             e_client_geometry_get(ec, &ec_x, &ec_y, NULL, NULL);
-             x = ev->x - ec_x;
-             y = ev->y - ec_y;
-          }
-
-        wl_data_device_send_motion(res, ev->timestamp, wl_fixed_from_int(x), wl_fixed_from_int(y));
-     }
-
    return ECORE_CALLBACK_RENEW;
 }
 
@@ -2941,40 +2739,16 @@ _e_comp_wl_surface_state_commit(E_Client *ec, E_Comp_Wl_Surface_State *state)
      }
 
    /* map or unmap ec */
-   if (!e_pixmap_usable_get(ec->pixmap))
+   Eina_Bool pixmap_usable = e_pixmap_usable_get(ec->pixmap);
+   Eina_Bool hide_by_request = e_client_hide_by_request_get(ec);
+   if (!pixmap_usable || hide_by_request)
      {
         /* unmap ec */
         if (cdata->mapped)
           {
-             if ((cdata->shell.surface) &&
-                 (cdata->shell.unmap))
-               {
-                  ELOGF("COMP", "Try to unmap. Call shell.unmap.", ec);
-                  if (ec->show_pending.count > 0)
-                    {
-                       ELOGF("E_CLIENT", "Reset show_pending!!! (count:%d, run:%d)", ec, ec->show_pending.count, ec->show_pending.running);
-                       ec->show_pending.count = 0;
-                       if (ec->show_pending.running)
-                         {
-                            // need to send visibility false;
-                            ec->visibility.obscured = E_VISIBILITY_UNOBSCURED;
-                            ELOGF("POL_VIS", "CLIENT VIS ON (fake).  argb:%d, opaque:%2d", ec, ec->argb, ec->visibility.opaque);
-                            EC_CHANGED(ec);
-                         }
-                       ec->show_pending.running = EINA_FALSE;
-                    }
-                  cdata->shell.unmap(cdata->shell.surface);
-               }
-             else if ((ec->internal) ||
-                      (e_comp_wl_subsurface_check(ec)) ||
-                      (ec == e_comp_wl->drag_client))
-               {
-                  ELOGF("COMP", "Try to unmap. Hide window. internal:%d, sub:%p, drag:%d",
-                        ec, ec->internal, cdata->sub.data, (ec == e_comp_wl->drag_client));
-                  ec->visible = EINA_FALSE;
-                  evas_object_hide(ec->frame);
-                  cdata->mapped = 0;
-               }
+             ELOGF("COMP", "Unmap. pixmap_usable:%d", ec, pixmap_usable);
+
+             e_client_hide(ec);
           }
 
         if ((cdata->sub.below_obj) &&
@@ -2986,27 +2760,7 @@ _e_comp_wl_surface_state_commit(E_Client *ec, E_Comp_Wl_Surface_State *state)
    else
      {
         /* map ec */
-        if (!cdata->mapped)
-          {
-             if ((cdata->shell.surface) &&
-                 (cdata->shell.map) &&
-                 (!ec->ignored))
-               {
-                  ELOGF("COMP", "Try to map. Call shell.map.", ec);
-                  cdata->shell.map(cdata->shell.surface);
-               }
-             else if ((ec->internal) ||
-                      (e_comp_wl_subsurface_can_show(ec)) ||
-                      (ec == e_comp_wl->drag_client))
-               {
-                  ELOGF("COMP", "Try to map. Show window. internal:%d, drag:%d",
-                        ec, ec->internal, (ec == e_comp_wl->drag_client));
-                  ec->visible = EINA_TRUE;
-                  ec->ignored = 0;
-                  evas_object_show(ec->frame);
-                  cdata->mapped = 1;
-               }
-          }
+        e_client_show(ec);
 
         if ((cdata->sub.below_obj) &&
             (!evas_object_visible_get(cdata->sub.below_obj)) &&
@@ -3233,6 +2987,15 @@ _e_comp_wl_surface_render_stop(E_Client *ec)
    evas_object_hide(ec->frame);
 }
 
+static void
+_e_input_thread_client_free(void *data)
+{
+   E_Input_Thread_Request_EClient_Data *ec_data = data;
+   EINA_SAFETY_ON_NULL_RETURN(ec_data);
+
+   INF("[input thread|%s] ec: %p, surface: %p\n", __func__, ec_data->ec, ec_data->wl_surface);
+}
+
 EINTERN void
 e_comp_wl_client_surface_finish(E_Client *ec)
 {
@@ -3248,19 +3011,24 @@ e_comp_wl_client_surface_finish(E_Client *ec)
    if (surface_client &&
        (ec == e_client_focused_get()))
      {
-        g_mutex_lock(&e_comp_wl->kbd.focused_mutex);
-        EINA_LIST_FOREACH_SAFE(e_comp_wl->kbd.focused, l, ll, res)
+        EINA_LIST_FOREACH_SAFE(e_comp_input_key->kbd.focused, l, ll, res)
           {
              if (wl_resource_get_client(res) ==
                  surface_client)
-               e_comp_wl->kbd.focused =
-                  eina_list_remove_list(e_comp_wl->kbd.focused, l);
+               e_comp_input_key->kbd.focused =
+                  eina_list_remove_list(e_comp_input_key->kbd.focused, l);
 
           }
-
-        g_mutex_unlock(&e_comp_wl->kbd.focused_mutex);
      }
 
+   E_Input_Thread_Request_EClient_Data ec_free_data;
+   memset(&ec_free_data, 0, sizeof(E_Input_Thread_Request_EClient_Data));
+   ec_free_data.ec = ec;
+   ec_free_data.wl_surface = ec->comp_data->wl_surface;
+
+   INF("[e_comp_wl_client_surface_finish] surface: %p\n", ec_free_data.wl_surface);
+   e_input_thread_safe_call(_e_input_thread_client_free, &ec_free_data, sizeof(E_Input_Thread_Request_EClient_Data));
+
    e_comp_wl_client_surface_set(ec, NULL);
 
    ec->comp_data->wl_surface = NULL;
@@ -3378,7 +3146,7 @@ _e_comp_wl_client_cb_focus_set(void *data EINA_UNUSED, E_Client *ec)
           _e_comp_wl_configure_send(ec, 0, 0);
      }
 
-   e_comp_wl->kbd.focus = ec->comp_data->surface;
+   e_comp_input_key->kbd.focus = ec->comp_data->surface;
 }
 
 static void
@@ -3395,8 +3163,8 @@ _e_comp_wl_client_cb_focus_unset(void *data EINA_UNUSED, E_Client *ec)
 
    _e_comp_wl_focus_check();
 
-   if (e_comp_wl->kbd.focus == ec->comp_data->surface)
-     e_comp_wl->kbd.focus = NULL;
+   if (e_comp_input_key->kbd.focus == ec->comp_data->surface)
+     e_comp_input_key->kbd.focus = NULL;
 }
 
 static void
@@ -3417,15 +3185,6 @@ _e_comp_wl_client_cb_resize_end(void *data EINA_UNUSED, E_Client *ec)
 
    e_comp_wl->resize.edges = 0;
    e_comp_wl->resize.resource = NULL;
-
-   if (ec->pending_resize)
-     {
-        ec->changes.pos = EINA_TRUE;
-        ec->changes.size = EINA_TRUE;
-        EC_CHANGED(ec);
-     }
-
-   E_FREE_LIST(ec->pending_resize, free);
 }
 
 static void
@@ -3653,45 +3412,6 @@ _e_comp_wl_gl_popup_cb_focus(void *data,
 static Eina_Bool
 _e_comp_wl_gl_idle(void *data)
 {
-   if (!e_comp->gl)
-     {
-        /* show warning window to notify failure of gl init */
-        // TODO: yigl
-#if 0
-        Evas_Object *win, *bg, *popup, *btn;
-
-        win = elm_win_add(NULL, "compositor warning", ELM_WIN_BASIC);
-        elm_win_title_set(win, "Compositor Warning");
-        elm_win_autodel_set(win, EINA_TRUE);
-        elm_win_borderless_set(win, EINA_TRUE);
-        elm_win_role_set(win, "notification-low");
-        elm_win_alpha_set(win, EINA_TRUE);
-
-        bg = evas_object_rectangle_add(evas_object_evas_get(win));
-        evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
-        elm_win_resize_object_add(win, bg);
-        evas_object_color_set(bg, 125, 125, 125, 125);
-        evas_object_show(bg);
-
-        popup = elm_popup_add(win);
-        elm_object_text_set(popup,
-                            _( "Your screen does not support OpenGL.<br>"
-                               "Falling back to software engine."));
-        elm_object_part_text_set(popup, "title,text", "Compositor Warning");
-
-        btn = elm_button_add(popup);
-        elm_object_text_set(btn, "Close");
-        elm_object_part_content_set(popup, "button1", btn);
-        evas_object_show(btn);
-
-        evas_object_smart_callback_add(win, "focus,in", _e_comp_wl_gl_popup_cb_focus, popup);
-        evas_object_smart_callback_add(btn, "unpressed", _e_comp_wl_gl_popup_cb_close, win);
-
-        evas_object_show(popup);
-        evas_object_show(win);
-#endif
-     }
-
    return ECORE_CALLBACK_CANCEL;
 }
 
@@ -3755,7 +3475,7 @@ _e_comp_wl_display_create(void)
    /* set compositor wayland data */
    e_comp_wl = e_comp->wl_comp_data = wl_cdata;
 
-   g_mutex_init(&flush_mutex);
+   g_mutex_init(&connection_mutex);
 
    /* try to create a wayland display */
    if (!(wl_cdata->wl.disp = wl_display_create()))
@@ -3834,6 +3554,9 @@ _e_comp_wl_display_create(void)
    ecore_main_fd_handler_prepare_callback_set(wl_cdata->fd_hdlr,
                                               _e_comp_wl_cb_prepare, wl_cdata);
 
+   /* add awake handler */
+   ecore_main_awake_handler_add(_e_comp_wl_cb_awake, NULL);
+
    return EINA_TRUE;
 
 input_err:
@@ -3847,7 +3570,7 @@ comp_err:
 sock_err:
    wl_display_destroy(wl_cdata->wl.disp);
 disp_err:
-   g_mutex_clear(&flush_mutex);
+   g_mutex_clear(&connection_mutex);
    free(comp);
    return EINA_FALSE;
 }
@@ -3910,6 +3633,7 @@ e_comp_wl_init(void)
    e_presentation_time_init();
    ds_single_pixel_buffer_manager_v1_create(e_comp_wl->wl.disp);
    e_blender_init();
+   e_blur_manager_init();
 
    if (!e_foreign_global_init(e_comp_wl->wl.disp))
      ELOGF("COMP", "Failed to initialize the e_foreign global", NULL);
@@ -3917,7 +3641,7 @@ e_comp_wl_init(void)
    /* add event handlers to catch E events */
    E_LIST_HANDLER_APPEND(handlers, E_EVENT_SCREEN_CHANGE,            _e_comp_wl_cb_randr_change,        NULL);
    E_LIST_HANDLER_APPEND(handlers, E_EVENT_COMP_OBJECT_ADD,         _e_comp_wl_cb_comp_object_add,     NULL);
-   E_LIST_HANDLER_APPEND(handlers, ECORE_EVENT_MOUSE_MOVE,          _e_comp_wl_cb_mouse_move,          NULL);
+   E_LIST_HANDLER_PREPEND(handlers, ECORE_EVENT_MOUSE_MOVE,          _e_comp_wl_cb_mouse_move,          NULL);
    E_LIST_HANDLER_APPEND(handlers, ECORE_EVENT_MOUSE_RELATIVE_MOVE,  _e_comp_wl_cb_mouse_relative_move, NULL);
    E_LIST_HANDLER_PREPEND(handlers, ECORE_EVENT_MOUSE_BUTTON_CANCEL, _e_comp_wl_cb_mouse_button_cancel, NULL);
    E_LIST_HANDLER_APPEND(handlers, E_EVENT_ZONE_DISPLAY_STATE_CHANGE, _e_comp_wl_cb_zone_display_state_change, NULL);
@@ -3932,8 +3656,6 @@ e_comp_wl_init(void)
    E_LIST_HOOK_APPEND(hooks, E_CLIENT_HOOK_RESIZE_END,   _e_comp_wl_client_cb_resize_end,   NULL);
    E_LIST_HOOK_APPEND(hooks, E_CLIENT_HOOK_MOVE_END,     _e_comp_wl_client_cb_move_end,     NULL);
 
-   e_comp_wl->idle_exiter = ecore_idle_exiter_add(_e_comp_wl_cb_idle_exiter, NULL);
-
    TRACE_DS_END();
    return EINA_TRUE;
 }
@@ -3950,15 +3672,12 @@ e_comp_wl_shutdown(void)
 {
    E_Comp_Data *comp = (E_Comp_Data *)e_comp_wl;
 
-   ecore_idle_exiter_del(e_comp_wl->idle_exiter);
-
    e_comp_wl_subsurfaces_shutdown();
    /* free handlers */
    E_FREE_LIST(handlers, ecore_event_handler_del);
    E_FREE_LIST(hooks, e_client_hook_del);
    _e_comp_wl_gl_shutdown();
 
-   e_blender_shutdown();
    e_presentation_time_shutdown();
    e_comp_wl_renderer_shutdown();
    e_comp_wl_capture_shutdown();
@@ -3976,6 +3695,9 @@ e_comp_wl_shutdown(void)
 
    wl_list_remove(&comp->client_created.link);
 
+   /* delete awake handler */
+   ecore_main_awake_handler_del(_e_comp_wl_cb_awake);
+
    e_comp_wl = NULL;
    e_comp->wl_comp_data = NULL;
    free(comp);
@@ -4064,55 +3786,6 @@ e_comp_wl_surface_commit(E_Client *ec)
         e_comp_wl_subsurface_restack_bg_rectangle(topmost);
      }
 
-   if (!e_pixmap_usable_get(ec->pixmap))
-     {
-        if (ec->comp_data->mapped)
-          {
-             if ((ec->comp_data->shell.surface) && (ec->comp_data->shell.unmap))
-               {
-                  ELOGF("COMP", "Try to unmap2. Call shell.unmap.", ec);
-                  ec->comp_data->shell.unmap(ec->comp_data->shell.surface);
-               }
-             else if (ec->internal || e_comp_wl_subsurface_check(ec) ||
-                      (ec == e_comp_wl->drag_client))
-               {
-                  ELOGF("COMP", "Try to unmap2. Hide window. internal:%d, sub:%p, drag:%d",
-                        ec, ec->internal, ec->comp_data->sub.data, (ec == e_comp_wl->drag_client));
-                  ec->visible = EINA_FALSE;
-                  evas_object_hide(ec->frame);
-                  ec->comp_data->mapped = 0;
-               }
-          }
-
-        if (ec->comp_data->sub.below_obj && evas_object_visible_get(ec->comp_data->sub.below_obj))
-          evas_object_hide(ec->comp_data->sub.below_obj);
-     }
-   else
-     {
-        if (!ec->comp_data->mapped)
-          {
-             if ((ec->comp_data->shell.surface) && (ec->comp_data->shell.map) &&
-                 (!ec->ignored))
-               {
-                  ELOGF("COMP", "Try to map2. Call shell.map.", ec);
-                  ec->comp_data->shell.map(ec->comp_data->shell.surface);
-               }
-             else if (ec->internal || e_comp_wl_subsurface_can_show(ec) ||
-                      (ec == e_comp_wl->drag_client))
-               {
-                  ELOGF("COMP", "Try to map2. Show window. internal:%d, drag:%d",
-                        ec, ec->internal, (ec == e_comp_wl->drag_client));
-                  ec->visible = EINA_TRUE;
-                  ec->ignored = 0;
-                  evas_object_show(ec->frame);
-                  ec->comp_data->mapped = 1;
-               }
-          }
-
-        if (ec->comp_data->sub.below_obj && !evas_object_visible_get(ec->comp_data->sub.below_obj)
-            && evas_object_visible_get(ec->frame))
-          evas_object_show(ec->comp_data->sub.below_obj);
-     }
    ec->ignored = ignored;
 
    if (ec->is_cursor && ec->visible)
@@ -4285,6 +3958,12 @@ _e_comp_wl_key_send(Ecore_Event_Key *ev, E_Device *dev, enum wl_keyboard_key_sta
           wc = wl_resource_get_client(surface);
      }
 
+   if (e_config->key_input_ttrace_enable)
+     {
+        TRACE_INPUT_BEGIN(wl_keyboard_send_key:%s:%s, (state ? "PRESS" : "RELEASE"), ev->keyname);
+        ELOGF("INPUT", "wl_keyboard_send_key:%s:%s|B|", NULL, (state ? "PRESS" : "RELEASE"), ev->keyname);
+     }
+
    EINA_LIST_FOREACH(key_list, l, res)
      {
         if (wl_resource_get_client(res) != wc) continue;
@@ -4311,6 +3990,12 @@ _e_comp_wl_key_send(Ecore_Event_Key *ev, E_Device *dev, enum wl_keyboard_key_sta
                              keycode, state);
         TRACE_INPUT_END();
      }
+
+   if (e_config->key_input_ttrace_enable)
+     {
+        TRACE_INPUT_END();
+        ELOGF("INPUT", "wl_keyboard_send_key|E|", NULL);
+     }
 }
 
 EINTERN Eina_Bool
@@ -4341,56 +4026,41 @@ e_comp_wl_key_down(Ecore_Event_Key *ev, E_Device *dev)
      }
 #endif
 
-   g_mutex_lock(&e_comp_wl->kbd.keys_mutex);
-
-   end = (E_Comp_Wl_Key_Data *)e_comp_wl->kbd.keys.data + (e_comp_wl->kbd.keys.size / sizeof(*k));
+   end = (E_Comp_Wl_Key_Data *)e_comp_input_key->kbd.keys.data + (e_comp_input_key->kbd.keys.size / sizeof(*k));
 
-   for (k = e_comp_wl->kbd.keys.data; k < end; k++)
+   for (k = e_comp_input_key->kbd.keys.data; k < end; k++)
      {
         /* ignore server-generated key repeats */
         if (k->key == keycode)
           {
-             g_mutex_unlock(&e_comp_wl->kbd.keys_mutex);
              return EINA_FALSE;
           }
      }
 
-   g_mutex_unlock(&e_comp_wl->kbd.keys_mutex);
-   g_rec_mutex_lock(&e_comp->input_key_grabs_mutex);
-
    if ((!e_client_action_get()) && (!e_comp->input_key_grabs))
      {
         ec = e_client_focused_get();
         struct wl_resource *surface = e_comp_wl_client_surface_get(ec);
         if (ec && ec->comp_data && surface)
           {
-             g_mutex_lock(&e_comp_wl->kbd.focused_mutex);
-             if (e_comp_wl->kbd.focused)
+             if (e_comp_input_key->kbd.focused)
                {
-                  _e_comp_wl_key_send(ev, dev, WL_KEYBOARD_KEY_STATE_PRESSED, e_comp_wl->kbd.focused, ec);
+                  _e_comp_wl_key_send(ev, dev, WL_KEYBOARD_KEY_STATE_PRESSED, e_comp_input_key->kbd.focused, ec);
 
                   /* A key only sent to clients is added to the list */
-                  g_mutex_lock(&e_comp_wl->kbd.keys_mutex);
-                  e_comp_wl->kbd.keys.size = (const char *)end - (const char *)e_comp_wl->kbd.keys.data;
+                  e_comp_input_key->kbd.keys.size = (const char *)end - (const char *)e_comp_input_key->kbd.keys.data;
 
-                  if (!(k = wl_array_add(&e_comp_wl->kbd.keys, sizeof(*k))))
+                  if (!(k = wl_array_add(&e_comp_input_key->kbd.keys, sizeof(*k))))
                     {
                        DBG("wl_array_add: Out of memory\n");
-                       g_mutex_unlock(&e_comp_wl->kbd.keys_mutex);
-                       g_mutex_unlock(&e_comp_wl->kbd.focused_mutex);
-                       g_rec_mutex_unlock(&e_comp->input_key_grabs_mutex);
                        return EINA_FALSE;
                     }
-                  g_mutex_unlock(&e_comp_wl->kbd.keys_mutex);
                   k->key = keycode;
                   k->dev = ev->dev;
                }
-             g_mutex_unlock(&e_comp_wl->kbd.focused_mutex);
           }
      }
 
-   g_rec_mutex_unlock(&e_comp->input_key_grabs_mutex);
-
    /* update modifier state */
    e_comp_wl_input_keyboard_state_update(keycode, EINA_TRUE);
 
@@ -4416,10 +4086,8 @@ e_comp_wl_key_up(Ecore_Event_Key *ev, E_Device *dev)
         return EINA_FALSE;
      }
 
-   g_mutex_lock(&e_comp_wl->kbd.keys_mutex);
-
-   end = (E_Comp_Wl_Key_Data *)e_comp_wl->kbd.keys.data + (e_comp_wl->kbd.keys.size / sizeof(*k));
-   for (k = e_comp_wl->kbd.keys.data; k < end; k++)
+   end = (E_Comp_Wl_Key_Data *)e_comp_input_key->kbd.keys.data + (e_comp_input_key->kbd.keys.size / sizeof(*k));
+   for (k = e_comp_input_key->kbd.keys.data; k < end; k++)
      {
         if (k->key == keycode)
           {
@@ -4428,26 +4096,20 @@ e_comp_wl_key_up(Ecore_Event_Key *ev, E_Device *dev)
           }
      }
 
-   e_comp_wl->kbd.keys.size =
-     (const char *)end - (const char *)e_comp_wl->kbd.keys.data;
-
-   g_mutex_unlock(&e_comp_wl->kbd.keys_mutex);
+   e_comp_input_key->kbd.keys.size =
+     (const char *)end - (const char *)e_comp_input_key->kbd.keys.data;
 
    /* 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) */
-   g_rec_mutex_lock(&e_comp->input_key_grabs_mutex);
    if ((delivered_key) ||
        ((!e_client_action_get()) && (!e_comp->input_key_grabs)))
      {
         ec = e_client_focused_get();
 
-        g_mutex_lock(&e_comp_wl->kbd.focused_mutex);
-        if (e_comp_wl->kbd.focused)
+        if (e_comp_input_key->kbd.focused)
           {
-             _e_comp_wl_key_send(ev, dev, WL_KEYBOARD_KEY_STATE_RELEASED, e_comp_wl->kbd.focused, ec);
+             _e_comp_wl_key_send(ev, dev, WL_KEYBOARD_KEY_STATE_RELEASED, e_comp_input_key->kbd.focused, ec);
           }
-        g_mutex_unlock(&e_comp_wl->kbd.focused_mutex);
      }
-   g_rec_mutex_unlock(&e_comp->input_key_grabs_mutex);
 
    /* update modifier state */
    e_comp_wl_input_keyboard_state_update(keycode, EINA_FALSE);
@@ -4627,7 +4289,14 @@ e_comp_wl_input_cursor_timer_enable_set(Eina_Bool enabled)
 {
    e_config->use_cursor_timer = !!enabled;
 
-   if (e_config->use_cursor_timer == EINA_FALSE)
+   if (e_config->use_cursor_timer)
+     {
+        if (!e_pointer_is_hidden(e_comp->pointer))
+          {
+             _e_comp_wl_cursor_move_timer_control(e_comp_wl->ptr.ec);
+          }
+     }
+   else
      {
         if (e_comp_wl->ptr.hide_tmr)
           {
@@ -4694,8 +4363,13 @@ e_comp_wl_key_send(E_Client *ec, int keycode, Eina_Bool pressed, void *dev, uint
    comp_conf = e_comp_config_get();
    e_keyrouter_event_surface_send(ec, keycode);
 
-   g_mutex_lock(&e_comp_wl->kbd.resource_mutex);
-   EINA_LIST_FOREACH(e_comp_wl->kbd.resources, l, res)
+   if (e_config->key_input_ttrace_enable)
+     {
+        TRACE_INPUT_BEGIN(wl_keyboard_send_key:%s:%d, (state ? "PRESS" : "RELEASE"), keycode);
+        ELOGF("INPUT", "wl_keyboard_send_key:%s:%d|B|", NULL, (state ? "PRESS" : "RELEASE"), keycode);
+     }
+
+   EINA_LIST_FOREACH(e_comp_input_key->kbd.resources, l, res)
      {
         if (wl_resource_get_client(res) != wc) continue;
         if (!e_input_thread_mode_get())
@@ -4726,7 +4400,12 @@ e_comp_wl_key_send(E_Client *ec, int keycode, Eina_Bool pressed, void *dev, uint
         wl_keyboard_send_key(res, serial, time,
                              wl_keycode, state);
      }
-   g_mutex_unlock(&e_comp_wl->kbd.resource_mutex);
+
+   if (e_config->key_input_ttrace_enable)
+     {
+        TRACE_INPUT_END();
+        ELOGF("INPUT", "wl_keyboard_send_key|E|", NULL);
+     }
 
    return EINA_TRUE;
 }
@@ -4739,11 +4418,14 @@ e_comp_wl_key_cancel(E_Client *ec, int keycode, Ecore_Device *dev, uint32_t time
    Eina_List *l;
    uint32_t serial, wl_keycode, cancel_keycode;
    E_Comp_Config *comp_conf = NULL;
+   struct xkb_keymap *keymap = NULL;
 
    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
    EINA_SAFETY_ON_NULL_RETURN_VAL(ec->comp_data, EINA_FALSE);
    EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_wl, EINA_FALSE);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_wl->xkb.keymap, EINA_FALSE);
+
+   keymap = e_comp_input_key->xkb.keymap;
+   EINA_SAFETY_ON_NULL_RETURN_VAL(keymap, EINA_FALSE);
 
    struct wl_resource *surface = e_comp_wl_client_surface_get(ec);
    EINA_SAFETY_ON_NULL_RETURN_VAL(surface, EINA_FALSE);
@@ -4754,6 +4436,9 @@ e_comp_wl_key_cancel(E_Client *ec, int keycode, Ecore_Device *dev, uint32_t time
         ELOGF("Key", "Failed to send key cancel for %d key, Cancel key is not supported\n", ec, keycode);
         return EINA_FALSE;
      }
+
+   EINA_SAFETY_ON_TRUE_RETURN_VAL(cancel_keycode < 8, EINA_FALSE);
+
    cancel_keycode = cancel_keycode - 8;
 
    wl_keycode = keycode - 8;
@@ -4766,8 +4451,7 @@ e_comp_wl_key_cancel(E_Client *ec, int keycode, Ecore_Device *dev, uint32_t time
    comp_conf = e_comp_config_get();
    e_keyrouter_event_surface_send(ec, keycode);
 
-   g_mutex_lock(&e_comp_wl->kbd.resource_mutex);
-   EINA_LIST_FOREACH(e_comp_wl->kbd.resources, l, res)
+   EINA_LIST_FOREACH(e_comp_input_key->kbd.resources, l, res)
      {
         if (wl_resource_get_client(res) != wc) continue;
         if (dev) _e_comp_wl_send_event_device(wc, time, dev, serial);
@@ -4782,7 +4466,6 @@ e_comp_wl_key_cancel(E_Client *ec, int keycode, Ecore_Device *dev, uint32_t time
         wl_keyboard_send_key(res, serial, time,
                              cancel_keycode, WL_KEYBOARD_KEY_STATE_RELEASED);
      }
-   g_mutex_unlock(&e_comp_wl->kbd.resource_mutex);
 
    return EINA_TRUE;
 }
@@ -5040,6 +4723,7 @@ e_comp_wl_mouse_out_send(E_Client *ec, Ecore_Device *dev, uint32_t time)
         wl_pointer_send_leave(res, serial, surface);
         ec->pointer_enter_sent = EINA_FALSE;
      }
+   wl_signal_emit(&e_comp_wl->ptr_constraints.surface_mouseout_signal, ec);
 
    return EINA_TRUE;
 }
@@ -5472,13 +5156,7 @@ e_comp_wl_commit_sync_configure(E_Client *ec)
    // cw interceptor(move,resize) won't work if wait_commit is TRUE
    ec->surface_sync.wait_commit = EINA_FALSE;
 
-   if ((ec->comp_data->shell.surface) &&
-       (ec->comp_data->shell.configure))
-     {
-        ec->comp_data->shell.configure(ec->comp_data->shell.surface,
-                                       ec->x, ec->y,
-                                       ec->w, ec->h);
-     }
+   e_client_shell_configure(ec, ec->x, ec->y, ec->w, ec->h);
 
    // rollback wait_commit if there are pending requests remained
    if (eina_list_count(ec->surface_sync.pending_geometry))
@@ -6130,15 +5808,12 @@ _e_comp_wl_client_subsurface_set(E_Client *ec, E_Comp_Wl_Subsurf_Data *sub)
    ec->lock_focus_in = ec->lock_focus_out = EINA_TRUE;
    ec->netwm.state.skip_taskbar = EINA_TRUE;
    ec->netwm.state.skip_pager = EINA_TRUE;
-   ec->no_shape_cut = EINA_TRUE;
    ec->border_size = 0;
    ec->lock_user_location = 0;
    ec->lock_client_location = 0;
    ec->lock_user_size = 0;
    ec->lock_client_size = 0;
    ec->lock_client_stacking = 0;
-   ec->lock_user_shade = 0;
-   ec->lock_client_shade = 0;
    ec->lock_user_maximize = 0;
    ec->lock_client_maximize = 0;
    ec->changes.need_maximize = 0;