e_comp_wl: remove "unmaximize_done" smart call
[platform/upstream/enlightenment.git] / src / bin / e_client.c
index 7d45b87..065efdf 100644 (file)
@@ -17,6 +17,7 @@
 #include "e_desk_intern.h"
 #include "e_zone_intern.h"
 #include "e_config_intern.h"
+#include "e_input_thread_client_intern.h"
 
 #define PRI(ec) ((E_Client_Private *)e_object_data_get(E_OBJECT(ec)))
 
@@ -107,6 +108,8 @@ struct _E_Client_Private
 
    Eina_Bool hide_by_request;
    Eina_Bool focus_check;
+
+   E_Client *modal;
 };
 
 static int _e_client_hooks_delete = 0;
@@ -979,10 +982,23 @@ _e_client_private_finish(E_Client *ec)
 }
 
 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\n", __func__, ec_data->ec);
+   e_input_thread_client_free(e_input_thread_client_get(ec_data->ec));
+}
+
+static void
 _e_client_free(E_Client *ec)
 {
    g_rec_mutex_lock(&e_comp->ec_list_mutex);
 
+   E_Input_Thread_Request_EClient_Data ec_data;
+   memset(&ec_data, 0, sizeof(E_Input_Thread_Request_EClient_Data));
+
    e_comp_object_redirected_set(ec->frame, 0);
    e_comp_object_render_update_del(ec->frame);
 
@@ -1027,6 +1043,10 @@ _e_client_free(E_Client *ec)
 
    e_uuid_store_entry_del(ec->uuid);
 
+   ec_data.ec = ec;
+   INF("[%s] ec: %p\n", __func__, ec);
+   e_input_thread_safe_call(_e_input_thread_client_free, &ec_data, sizeof(E_Input_Thread_Request_EClient_Data));
+
    _e_client_private_finish(ec);
    free(ec);
 
@@ -1034,10 +1054,22 @@ _e_client_free(E_Client *ec)
 }
 
 static void
+_e_input_thread_client_del(void *data)
+{
+   E_Input_Thread_Request_EClient_Data *ec_data = data;
+   EINA_SAFETY_ON_NULL_RETURN(ec_data);
+
+   INF("[input thread|%s] ec: %p\n", __func__, ec_data->ec);
+   e_input_thread_client_del(e_input_thread_client_get(ec_data->ec));
+}
+
+static void
 _e_client_del(E_Client *ec)
 {
    E_Client *child;
    E_Pixmap_Type type;
+   E_Input_Thread_Request_EClient_Data ec_data;
+   memset(&ec_data, 0, sizeof(E_Input_Thread_Request_EClient_Data));
 
    g_rec_mutex_lock(&e_comp->ec_list_mutex);
 
@@ -1075,6 +1107,8 @@ _e_client_del(E_Client *ec)
 
    if (ec->parent)
      {
+        if (e_client_modal_child_get(ec->parent) == ec)
+          e_client_modal_child_set(ec->parent, NULL);
         ec->parent->transients = eina_list_remove(ec->parent->transients, ec);
         ec->parent = NULL;
      }
@@ -1112,6 +1146,10 @@ _e_client_del(E_Client *ec)
 
    e_comp_visibility_calculation_set(EINA_TRUE);
 
+   ec_data.ec = ec;
+   INF("[%s] ec: %p\n", __func__, ec);
+   e_input_thread_safe_call(_e_input_thread_client_del, &ec_data, sizeof(E_Input_Thread_Request_EClient_Data));
+
    g_rec_mutex_unlock(&e_comp->ec_list_mutex);
 }
 
@@ -1149,7 +1187,6 @@ _e_client_cb_ping_poller(void *data)
         if (ec->hung)
           {
              ec->hung = 0;
-             evas_object_smart_callback_call(ec->frame, "unhung", NULL);
              E_FREE_FUNC(ec->kill_timer, ecore_timer_del);
           }
      }
@@ -1164,7 +1201,6 @@ _e_client_cb_ping_poller(void *data)
              if (!ec->hung)
                {
                   ec->hung = 1;
-                  evas_object_smart_callback_call(ec->frame, "hung", NULL);
                   /* FIXME: if below dialog is up - hide it now */
                }
              if (ec->delete_requested)
@@ -1219,7 +1255,7 @@ _e_client_move_begin(E_Client *ec)
    ec->moving = 1;
    ecmove = ec;
 
-   wl_signal_emit_mutable(&PRI(ec)->events.move_begin, NULL);
+   wl_signal_emit(&PRI(ec)->events.move_begin, NULL);
    _e_client_hook_call(E_CLIENT_HOOK_MOVE_BEGIN, ec);
    if (!ec->moving)
      {
@@ -1245,7 +1281,7 @@ _e_client_move_end(E_Client *ec)
    ec->moving = 0;
    _e_client_action_input_win_del();
 
-   wl_signal_emit_mutable(&PRI(ec)->events.move_end, NULL);
+   wl_signal_emit(&PRI(ec)->events.move_end, NULL);
    _e_client_hook_call(E_CLIENT_HOOK_MOVE_END, ec);
 
    if (ec->transformed)
@@ -1652,7 +1688,7 @@ _e_client_resize_end(E_Client *ec)
    ec->resize_mode = E_POINTER_RESIZE_NONE;
    _e_client_action_input_win_del();
 
-   wl_signal_emit_mutable(&PRI(ec)->events.move_resize_end, NULL);
+   wl_signal_emit(&PRI(ec)->events.move_resize_end, NULL);
    _e_client_hook_call(E_CLIENT_HOOK_RESIZE_END, ec);
 
    if (ec->transformed)
@@ -2055,7 +2091,7 @@ _e_client_cb_evas_move(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UN
      }
    if (ec->moving || (ecmove == ec))
      {
-        wl_signal_emit_mutable(&PRI(ec)->events.move_resize_update, NULL);
+        wl_signal_emit(&PRI(ec)->events.move_resize_update, NULL);
         _e_client_hook_call(E_CLIENT_HOOK_MOVE_UPDATE, ec);
      }
 
@@ -2068,7 +2104,7 @@ _e_client_cb_evas_move(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UN
 
    ec->pre_cb.x = x; ec->pre_cb.y = y;
 
-   wl_signal_emit_mutable(&PRI(ec)->events.move, NULL);
+   wl_signal_emit(&PRI(ec)->events.move, NULL);
 
    e_comp_visibility_calculation_set(EINA_TRUE);
 }
@@ -2110,7 +2146,7 @@ _e_client_cb_evas_resize(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_
 
    if (e_client_util_resizing_get(ec) || (ecresize == ec))
      {
-         wl_signal_emit_mutable(&PRI(ec)->events.move_resize_update, NULL);
+         wl_signal_emit(&PRI(ec)->events.move_resize_update, NULL);
         _e_client_hook_call(E_CLIENT_HOOK_RESIZE_UPDATE, ec);
      }
    ec->pre_cb.w = w; ec->pre_cb.h = h;
@@ -2204,7 +2240,7 @@ _e_client_aux_hint_eval(E_Client *ec)
 
    if (cdata && cdata->aux_hint.changed)
      {
-        wl_signal_emit_mutable(&PRI(ec)->events.aux_hint_change, NULL);
+        wl_signal_emit(&PRI(ec)->events.aux_hint_change, NULL);
         _e_client_hook_call(E_CLIENT_HOOK_AUX_HINT_CHANGE, ec);
 
         EINA_LIST_FOREACH_SAFE(cdata->aux_hint.hints, l, ll, hint)
@@ -2239,7 +2275,7 @@ _e_client_eval(E_Client *ec)
 
    TRACE_DS_BEGIN(CLIENT:EVAL);
 
-   wl_signal_emit_mutable(&PRI(ec)->events.eval_pre_new_client, NULL);
+   wl_signal_emit(&PRI(ec)->events.eval_pre_new_client, NULL);
    if (!_e_client_hook_call(E_CLIENT_HOOK_EVAL_PRE_NEW_CLIENT, ec))
      {
         TRACE_DS_END();
@@ -2248,7 +2284,7 @@ _e_client_eval(E_Client *ec)
 
    if ((ec->new_client) && (!e_client_util_ignored_get(ec)))
      {
-        wl_signal_emit_mutable(&PRI(ec)->events.eval_post_new_client, NULL);
+        wl_signal_emit(&PRI(ec)->events.eval_post_new_client, NULL);
         if (!_e_client_hook_call(E_CLIENT_HOOK_EVAL_POST_NEW_CLIENT, ec))
           {
              TRACE_DS_END();
@@ -2383,7 +2419,7 @@ _e_client_eval(E_Client *ec)
 
    e_client_transform_core_update(ec);
 
-   wl_signal_emit_mutable(&PRI(ec)->events.eval_end, NULL);
+   wl_signal_emit(&PRI(ec)->events.eval_end, NULL);
    _e_client_hook_call(E_CLIENT_HOOK_EVAL_END, ec);
 
    TRACE_DS_END();
@@ -2632,7 +2668,7 @@ e_client_visibility_change_notify(E_Client *ec)
    if (ec->visibility.changed)
      _e_client_event_simple(ec, E_EVENT_CLIENT_VISIBILITY_CHANGE);
 
-   wl_signal_emit_mutable(&PRI(ec)->events.eval_visibility, NULL);
+   wl_signal_emit(&PRI(ec)->events.eval_visibility, NULL);
    _e_client_hook_call(E_CLIENT_HOOK_EVAL_VISIBILITY, ec);
 }
 
@@ -2654,14 +2690,33 @@ e_client_visibility_get(E_Client *ec)
    return ec->visibility.obscured;
 }
 
+static void
+_e_input_thread_client_visibility_set(void *data)
+{
+   E_Input_Thread_Request_EClient_Data *ec_data = data;
+   EINA_SAFETY_ON_NULL_RETURN(ec_data);
+
+   INF("[input thread|%s] ec(%p), visibility(%d)\n", __func__, ec_data->ec, ec_data->visibility);
+   e_input_thread_client_visibility_set(e_input_thread_client_get(ec_data->ec), ec_data->visibility);
+}
+
 EINTERN void
 e_client_visibility_set(E_Client *ec, E_Visibility visibility)
 {
+   E_Input_Thread_Request_EClient_Data ec_data;
+   memset(&ec_data, 0, sizeof(E_Input_Thread_Request_EClient_Data));
+
    EINA_SAFETY_ON_NULL_RETURN(ec);
 
    if (e_client_visibility_get(ec) == visibility) return;
 
    ec->visibility.obscured = visibility;
+
+   ec_data.ec = ec;
+   ec_data.visibility = ec->visibility.obscured;
+
+   INF("[%s] ec(%p), visibility(%d)\n", __func__, ec, ec->visibility.obscured);
+   e_input_thread_safe_call(_e_input_thread_client_visibility_set, &ec_data, sizeof(E_Input_Thread_Request_EClient_Data));
 }
 
 static Eina_Bool
@@ -2993,6 +3048,49 @@ e_client_mapped_set(E_Client *ec, Eina_Bool set)
    cdata->mapped = set;
 }
 
+EINTERN void
+e_client_modal_child_set(E_Client *ec, E_Client *modal)
+{
+   API_ENTRY;
+
+   E_Client *old_modal = priv->modal;
+   if (old_modal == modal) return;
+
+   ELOGF("E_CLIENT", "SET modal. new(ec:%p, win:0x%08zx), old(ec:%p, win:0x%08zx)", ec,
+         modal, e_client_util_win_get(modal), old_modal, e_client_util_win_get(old_modal));
+
+   // TODO: if ec has a modal window already, then how does we do?
+   priv->modal = modal;
+}
+
+EINTERN E_Client *
+e_client_modal_child_get(E_Client *ec)
+{
+   API_ENTRY_VAL(NULL);
+   return priv->modal;
+}
+
+EINTERN void
+e_client_modal_state_set(E_Client *ec, Eina_Bool modal)
+{
+   if (!ec) return;
+   ec->netwm.state.modal = modal;
+
+   if (ec->parent)
+     {
+        if (ec->netwm.state.modal)
+          e_client_modal_child_set(ec->parent, ec);
+        else
+          e_client_modal_child_set(ec->parent, NULL);
+     }
+}
+
+EINTERN Eina_Bool
+e_client_is_modal_state(E_Client *ec)
+{
+   if (!ec) return EINA_FALSE;
+   return ec->netwm.state.modal;
+}
 
 ////////////////////////////////////////////////
 EINTERN Eina_Bool
@@ -3027,12 +3125,12 @@ e_client_idler_before(Eina_Bool *check_focus)
         // call hooks to decide what to do - maybe move/resize
         if (ec->ignored || (!ec->changed)) continue;
 
-        wl_signal_emit_mutable(&PRI(ec)->events.eval_pre_fetch, NULL);
+        wl_signal_emit(&PRI(ec)->events.eval_pre_fetch, NULL);
         if (!_e_client_hook_call(E_CLIENT_HOOK_EVAL_PRE_FETCH, ec)) continue;
 
 
         /* FETCH is hooked by the compositor to get client hints */
-        wl_signal_emit_mutable(&PRI(ec)->events.eval_fetch, NULL);
+        wl_signal_emit(&PRI(ec)->events.eval_fetch, NULL);
         if (!_e_client_hook_call(E_CLIENT_HOOK_EVAL_FETCH, ec)) continue;
 
         if (ec->new_client)
@@ -3041,14 +3139,14 @@ e_client_idler_before(Eina_Bool *check_focus)
           }
 
         /* PRE_POST_FETCH calls e_remember apply for new client */
-        wl_signal_emit_mutable(&PRI(ec)->events.eval_pre_post_fetch, NULL);
+        wl_signal_emit(&PRI(ec)->events.eval_pre_post_fetch, NULL);
         if (!_e_client_hook_call(E_CLIENT_HOOK_EVAL_PRE_POST_FETCH, ec)) continue;
-        wl_signal_emit_mutable(&PRI(ec)->events.eval_post_fetch, NULL);
+        wl_signal_emit(&PRI(ec)->events.eval_post_fetch, NULL);
         if (!_e_client_hook_call(E_CLIENT_HOOK_EVAL_POST_FETCH, ec)) continue;
-        wl_signal_emit_mutable(&PRI(ec)->events.eval_pre_frame_assign, NULL);
+        wl_signal_emit(&PRI(ec)->events.eval_pre_frame_assign, NULL);
         if (!_e_client_hook_call(E_CLIENT_HOOK_EVAL_PRE_FRAME_ASSIGN, ec)) continue;
 
-        wl_signal_emit_mutable(&PRI(ec)->events.eval_post_frame_assign, NULL);
+        wl_signal_emit(&PRI(ec)->events.eval_post_frame_assign, NULL);
         _e_client_hook_call(E_CLIENT_HOOK_EVAL_POST_FRAME_ASSIGN, ec);
      }
    // pass 2 - show and hide windows needing hide and eval (main eval)
@@ -3214,6 +3312,16 @@ _e_client_convert_fullscreen_layer(int layer)
      return E_LAYER_CLIENT_FULLSCREEN;
 }
 
+static void
+_e_input_thread_client_new(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);
+   e_input_thread_client_new(ec_data->ec, ec_data->wl_surface);
+}
+
 E_API E_Client *
 e_client_new(E_Pixmap *cp, int first_map, int internal)
 {
@@ -3277,7 +3385,7 @@ e_client_new(E_Pixmap *cp, int first_map, int internal)
 
    e_client_iconified_type_set(ec, E_ICONIFIED_TYPE_NONE);
 
-   wl_signal_emit_mutable(&PRI(ec)->events.new_client, NULL);
+   wl_signal_emit(&PRI(ec)->events.new_client, NULL);
    if (!_e_client_hook_call(E_CLIENT_HOOK_NEW_CLIENT, ec))
      {
         /* delete the above allocated object */
@@ -3338,7 +3446,7 @@ e_client_new(E_Pixmap *cp, int first_map, int internal)
         evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_RESTACK, _e_client_cb_evas_restack, ec);
      }
 
-   wl_signal_emit_mutable(&PRI(ec)->events.new_client_post, NULL);
+   wl_signal_emit(&PRI(ec)->events.new_client_post, NULL);
 
 #ifdef _F_E_CLIENT_NEW_CLIENT_POST_HOOK_
    _e_client_hook_call(E_CLIENT_HOOK_NEW_CLIENT_POST, ec);
@@ -3353,6 +3461,14 @@ e_client_new(E_Pixmap *cp, int first_map, int internal)
 
    ec->visibility.ignore_geometry = e_config->calc_vis_ignore_geometry;
 
+   E_Input_Thread_Request_EClient_Data ec_new_data;
+   memset(&ec_new_data, 0, sizeof(E_Input_Thread_Request_EClient_Data));
+
+   ec_new_data.ec = ec;
+   ec_new_data.wl_surface = ec->comp_data ? ec->comp_data->wl_surface : NULL;
+   INF("[%s] ec(%p), surface(%p)\n", __func__, ec, ec_new_data.wl_surface);
+   e_input_thread_safe_call(_e_input_thread_client_new, &ec_new_data, sizeof(E_Input_Thread_Request_EClient_Data));
+
    return ec;
 }
 
@@ -3404,7 +3520,7 @@ e_client_mouse_in(E_Client *ec, int x, int y)
    ec->mouse.current.my = y;
    ec->mouse.in = 1;
 
-   wl_signal_emit_mutable(&PRI(ec)->events.mouse_in, NULL);
+   wl_signal_emit(&PRI(ec)->events.mouse_in, NULL);
 }
 
 EINTERN void
@@ -3422,7 +3538,7 @@ e_client_mouse_out(E_Client *ec, int x, int y)
    ec->mouse.current.my = y;
    ec->mouse.in = 0;
 
-   wl_signal_emit_mutable(&PRI(ec)->events.mouse_out, NULL);
+   wl_signal_emit(&PRI(ec)->events.mouse_out, NULL);
 }
 
 EINTERN void
@@ -3477,7 +3593,7 @@ e_client_mouse_down(E_Client *ec, int button, Evas_Point *output, E_Binding_Even
    ec->mouse.current.mx = output->x;
    ec->mouse.current.my = output->y;
 
-   wl_signal_emit_mutable(&PRI(ec)->events.mouse_down, NULL);
+   wl_signal_emit(&PRI(ec)->events.mouse_down, NULL);
 }
 
 EINTERN void
@@ -3750,7 +3866,7 @@ e_client_above_get(const E_Client *ec)
 
    data.above_ec = NULL;
 
-   wl_signal_emit_mutable(&priv->events.get_above, &data);
+   wl_signal_emit(&priv->events.get_above, &data);
 
    return data.above_ec;
 #else
@@ -3810,7 +3926,7 @@ e_client_below_get(const E_Client *ec)
 
    data.below_ec = NULL;
 
-   wl_signal_emit_mutable(&priv->events.get_below, &data);
+   wl_signal_emit(&priv->events.get_below, &data);
 
    return data.below_ec;
 #else
@@ -3897,7 +4013,7 @@ e_client_visible_above_get(E_Client *ec)
 
    data.above_ec = NULL;
 
-   wl_signal_emit_mutable(&priv->events.get_visible_above, &data);
+   wl_signal_emit(&priv->events.get_visible_above, &data);
 
    return data.above_ec;
 #else
@@ -3950,7 +4066,7 @@ e_client_visible_below_get(E_Client *ec)
 
    data.below_ec = NULL;
 
-   wl_signal_emit_mutable(&priv->events.get_visible_below, &data);
+   wl_signal_emit(&priv->events.get_visible_below, &data);
 
    return data.below_ec;
 #else
@@ -4168,7 +4284,7 @@ e_client_focus_latest_set(E_Client *ec)
 {
    EINA_SAFETY_ON_NULL_RETURN(ec);
 
-   wl_signal_emit_mutable(&PRI(ec)->events.focus_latest_set, NULL);
+   wl_signal_emit(&PRI(ec)->events.focus_latest_set, NULL);
 }
 
 E_API void
@@ -4176,7 +4292,7 @@ e_client_focus_defer_set(E_Client *ec)
 {
    EINA_SAFETY_ON_NULL_RETURN(ec);
 
-   wl_signal_emit_mutable(&PRI(ec)->events.focus_defer_set, NULL);
+   wl_signal_emit(&PRI(ec)->events.focus_defer_set, NULL);
 }
 
 EINTERN void
@@ -4202,7 +4318,7 @@ e_client_focused_set(E_Client *ec)
          {
             // FIXME: Remove focus_unset event of client.
             //        Instead, make zone focus_unset event and use it.
-            wl_signal_emit_mutable(&PRI(focused_ec)->events.focus_unset, NULL);
+            wl_signal_emit(&PRI(focused_ec)->events.focus_unset, NULL);
             _e_client_hook_call(E_CLIENT_HOOK_FOCUS_UNSET, focused_ec);
 
             if (e_object_ref_get(E_OBJECT(focused_ec)) > 0)
@@ -4224,7 +4340,7 @@ e_client_focused_set(E_Client *ec)
    // FIXME: Remove focus_set event of client.
    //        Instead, make zone focus_set event and use it.
    // set the new current focused_ec
-   wl_signal_emit_mutable(&PRI(ec)->events.focus_set, NULL);
+   wl_signal_emit(&PRI(ec)->events.focus_set, NULL);
    _e_client_hook_call(E_CLIENT_HOOK_FOCUS_SET, ec);
 
    // send the client_focuse_in event
@@ -4255,7 +4371,7 @@ e_client_activate(E_Client *ec)
    ec->exp_iconify.by_client = 0;
    e_client_iconified_type_set(ec, E_ICONIFIED_TYPE_NONE);
 
-   wl_signal_emit_mutable(&PRI(ec)->events.activate_done, NULL);
+   wl_signal_emit(&PRI(ec)->events.activate_done, NULL);
    _e_client_hook_call(E_CLIENT_HOOK_ACTIVATE_DONE, ec);
 
    TRACE_DS_END();
@@ -4362,13 +4478,11 @@ e_client_maximize(E_Client *ec, E_Maximize max)
    if (!ec->fullscreen)
      {
         // call the maximize hook of a client
-        wl_signal_emit_mutable(&PRI(ec)->events.maximize, &max);
+        wl_signal_emit(&PRI(ec)->events.maximize, &max);
 
         // store the E_Maximize value
         ec->maximized = max;
         ec->changes.need_unmaximize = 0;
-
-        evas_object_smart_callback_call(ec->frame, "maximize_done", NULL);
      }
    else
      {
@@ -4403,12 +4517,8 @@ e_client_unmaximize(E_Client *ec, E_Maximize max)
 
    if (!ec->fullscreen)
      {
-        evas_object_smart_callback_call(ec->frame, "unmaximize_pre", NULL);
-
         // call the unmaximize hook of a client
-        wl_signal_emit_mutable(&PRI(ec)->events.unmaximize, &max);
-
-        evas_object_smart_callback_call(ec->frame, "unmaximize_done", NULL);
+        wl_signal_emit(&PRI(ec)->events.unmaximize, &max);
      }
 
    ec->maximized = E_MAXIMIZE_NONE;
@@ -4424,7 +4534,7 @@ e_client_fullscreen(E_Client *ec, E_Fullscreen policy)
    if (ec->fullscreen) return;
 
    // call the fullscreen_pre hook of a client
-   wl_signal_emit_mutable(&PRI(ec)->events.fullscreen_pre, NULL);
+   wl_signal_emit(&PRI(ec)->events.fullscreen_pre, NULL);
    _e_client_hook_call(E_CLIENT_HOOK_FULLSCREEN_PRE, ec);
 
    if (ec->skip_fullscreen) return;
@@ -4440,7 +4550,7 @@ e_client_fullscreen(E_Client *ec, E_Fullscreen policy)
    ec->fullscreen = 1;
 
    // call the fullscreen hook of a client
-   wl_signal_emit_mutable(&PRI(ec)->events.fullscreen, &policy);
+   wl_signal_emit(&PRI(ec)->events.fullscreen, &policy);
 
    ec->fullscreen_policy = policy;
 
@@ -4462,7 +4572,7 @@ e_client_unfullscreen(E_Client *ec)
    E_Fullscreen policy = ec->fullscreen_policy;
 
    // call the unfullscreen hook of a client
-   wl_signal_emit_mutable(&PRI(ec)->events.unfullscreen, &policy);
+   wl_signal_emit(&PRI(ec)->events.unfullscreen, &policy);
 
    e_client_layer_set(ec, ec->saved.layer);
 
@@ -4516,7 +4626,7 @@ e_client_iconify(E_Client *ec)
 
    TRACE_DS_BEGIN(CLIENT:ICONIFY);
 
-   wl_signal_emit_mutable(&PRI(ec)->events.iconify, NULL);
+   wl_signal_emit(&PRI(ec)->events.iconify, NULL);
    _e_client_hook_call(E_CLIENT_HOOK_ICONIFY, ec);
 
    TRACE_DS_END();
@@ -4542,7 +4652,7 @@ e_client_uniconify(E_Client *ec)
    TRACE_DS_BEGIN(CLIENT:UNICONIFY);
 
     // call the uniconify hook of a client
-   wl_signal_emit_mutable(&PRI(ec)->events.uniconify, NULL);
+   wl_signal_emit(&PRI(ec)->events.uniconify, NULL);
    _e_client_hook_call(E_CLIENT_HOOK_UNICONIFY, ec);
 
    TRACE_DS_END();
@@ -4620,7 +4730,7 @@ e_client_stick(E_Client *ec)
    if (ec->sticky) return;
 
    // call the stick hook of a client
-   wl_signal_emit_mutable(&PRI(ec)->events.stick, NULL);
+   wl_signal_emit(&PRI(ec)->events.stick, NULL);
 
    // send the sticky property event of a client
    _e_client_event_property(ec, E_CLIENT_PROPERTY_STICKY);
@@ -4635,7 +4745,7 @@ e_client_unstick(E_Client *ec)
    if (!ec->sticky) return;
 
    // call the unstick hook of a client
-   wl_signal_emit_mutable(&PRI(ec)->events.unstick, NULL);
+   wl_signal_emit(&PRI(ec)->events.unstick, NULL);
 
   // send the sticky property event of a client
    _e_client_event_property(ec, E_CLIENT_PROPERTY_STICKY);
@@ -4686,7 +4796,7 @@ e_client_act_move_keyboard(E_Client *ec)
    _e_client_action_init(ec);
    _e_client_action_move_timeout_add();
 
-   wl_signal_emit_mutable(&PRI(ec)->events.move_update, NULL);
+   wl_signal_emit(&PRI(ec)->events.move_update, NULL);
    if (!_e_client_hook_call(E_CLIENT_HOOK_MOVE_UPDATE, ec)) return;
    evas_object_freeze_events_set(ec->frame, 1);
 
@@ -4933,7 +5043,7 @@ e_client_resize_begin(E_Client *ec)
         ec->manage_resize.ah = ec->h - ec->manage_resize.header_h - ec->manage_resize.footer_h;
      }
 
-   wl_signal_emit_mutable(&PRI(ec)->events.move_begin, NULL);
+   wl_signal_emit(&PRI(ec)->events.move_begin, NULL);
    _e_client_hook_call(E_CLIENT_HOOK_RESIZE_BEGIN, ec);
    if (ec->transformed)
      _e_client_transform_resize_begin(ec);
@@ -5137,12 +5247,12 @@ e_client_redirected_set(E_Client *ec, Eina_Bool set)
      {
         e_client_frame_recalc(ec);
 
-        wl_signal_emit_mutable(&PRI(ec)->events.redirect, NULL);
+        wl_signal_emit(&PRI(ec)->events.redirect, NULL);
         if (!_e_client_hook_call(E_CLIENT_HOOK_REDIRECT, ec)) return;
      }
    else
      {
-        wl_signal_emit_mutable(&PRI(ec)->events.unredirect, NULL);
+        wl_signal_emit(&PRI(ec)->events.unredirect, NULL);
         if (!_e_client_hook_call(E_CLIENT_HOOK_UNREDIRECT, ec)) return;
      }
    e_comp_object_redirected_set(ec->frame, set);
@@ -5419,7 +5529,7 @@ e_client_transform_core_update(E_Client *ec)
 
         if (!e_object_is_del(E_OBJECT(ec)))
           {
-             wl_signal_emit_mutable(&PRI(ec)->events.transform_change, NULL);
+             wl_signal_emit(&PRI(ec)->events.transform_change, NULL);
              _e_client_hook_call(E_CLIENT_HOOK_TRANSFORM_CHANGE, ec);
           }
      }
@@ -5436,7 +5546,7 @@ e_client_transform_core_update(E_Client *ec)
 
              if (!e_object_is_del(E_OBJECT(ec)))
                {
-                  wl_signal_emit_mutable(&PRI(ec)->events.transform_change, NULL);
+                  wl_signal_emit(&PRI(ec)->events.transform_change, NULL);
                   _e_client_hook_call(E_CLIENT_HOOK_TRANSFORM_CHANGE, ec);
                }
           }
@@ -5556,7 +5666,7 @@ e_client_window_role_set(E_Client *ec, const char *role)
 
    if (eina_stringshare_replace(&ec->icccm.window_role, role))
      {
-        wl_signal_emit_mutable(&PRI(ec)->events.window_role_change, NULL);
+        wl_signal_emit(&PRI(ec)->events.window_role_change, NULL);
         _e_client_hook_call(E_CLIENT_HOOK_WINDOW_ROLE_CHANGE, ec);
      }
 }
@@ -6116,6 +6226,31 @@ e_client_util_move_resize_without_frame(E_Client *ec, int x, int y, int w, int h
      }
 }
 
+static void
+_e_input_thread_client_layer_set(void *data)
+{
+   E_Input_Thread_Request_EClient_Data *ec_data = data;
+   EINA_SAFETY_ON_NULL_RETURN(ec_data);
+
+   INF("[input thread|%s] ec(%p), layer(%d)\n", __func__, ec_data->ec, ec_data->layer);
+   e_input_thread_client_layer_set(e_input_thread_client_get(ec_data->ec), ec_data->layer);
+}
+
+EINTERN void
+e_client_input_thread_layer_set(E_Client *ec, E_Layer layer)
+{
+   EINA_SAFETY_ON_NULL_RETURN(ec);
+
+   E_Input_Thread_Request_EClient_Data ec_data;
+   memset(&ec_data, 0, sizeof(E_Input_Thread_Request_EClient_Data));
+
+   ec_data.ec = ec;
+   ec_data.layer = layer;
+
+   INF("[%s] ec(%p), layer(%d)\n", __func__, ec, layer);
+   e_input_thread_safe_call(_e_input_thread_client_layer_set, &ec_data, sizeof(E_Input_Thread_Request_EClient_Data));
+}
+
 E_API Eina_Bool
 e_client_layer_set(E_Client *ec,
                    E_Layer layer)
@@ -6159,11 +6294,12 @@ e_client_layer_set(E_Client *ec,
         if (ec->layer_pending || ec->layer_block)
           {
              ec->layer = layer;
+             e_client_input_thread_layer_set(ec, layer);
              return EINA_TRUE;
           }
      }
 
-   wl_signal_emit_mutable(&PRI(ec)->events.set_layer, NULL);
+   wl_signal_emit(&PRI(ec)->events.set_layer, NULL);
 
    return EINA_TRUE;
 }
@@ -6383,7 +6519,7 @@ e_client_raise(E_Client *ec)
    else
      evas_object_raise(ec->frame);
 
-   wl_signal_emit_mutable(&PRI(ec)->events.raise, NULL);
+   wl_signal_emit(&PRI(ec)->events.raise, NULL);
 }
 
 static void
@@ -6497,7 +6633,7 @@ e_client_lower(E_Client *ec)
           {
              e_desk_area_ec_lower(eda, ec);
 
-             wl_signal_emit_mutable(&PRI(ec)->events.lower, NULL);
+             wl_signal_emit(&PRI(ec)->events.lower, NULL);
              return;
           }
      }
@@ -6508,7 +6644,7 @@ e_client_lower(E_Client *ec)
    else
      evas_object_lower(ec->frame);
 
-   wl_signal_emit_mutable(&PRI(ec)->events.lower, NULL);
+   wl_signal_emit(&PRI(ec)->events.lower, NULL);
 }
 
 E_API void
@@ -6535,7 +6671,7 @@ e_client_stack_above(E_Client *ec, E_Client *above)
 
    evas_object_stack_above(ec->frame, above->frame);
 
-   wl_signal_emit_mutable(&PRI(ec)->events.stack_above, NULL);
+   wl_signal_emit(&PRI(ec)->events.stack_above, NULL);
 }
 
 E_API void
@@ -6562,7 +6698,7 @@ e_client_stack_below(E_Client *ec, E_Client *below)
 
    evas_object_stack_below(ec->frame, below->frame);
 
-   wl_signal_emit_mutable(&PRI(ec)->events.stack_below, NULL);
+   wl_signal_emit(&PRI(ec)->events.stack_below, NULL);
 }
 
 E_API int
@@ -6917,7 +7053,7 @@ e_client_stack_transient_for_done_notify(E_Client *ec)
 {
    EINA_SAFETY_ON_NULL_RETURN(ec);
 
-   wl_signal_emit_mutable(&PRI(ec)->events.stack_transient_for_done, NULL);
+   wl_signal_emit(&PRI(ec)->events.stack_transient_for_done, NULL);
 }
 
 #ifdef REFACTOR_DESK_AREA
@@ -6926,7 +7062,7 @@ e_client_subsurface_stack_update(E_Client *ec)
 {
    EINA_SAFETY_ON_NULL_RETURN(ec);
 
-   wl_signal_emit_mutable(&PRI(ec)->events.subsurface_stack_update, ec);
+   wl_signal_emit(&PRI(ec)->events.subsurface_stack_update, ec);
 }
 #endif
 
@@ -7356,13 +7492,38 @@ e_client_shell_ping(E_Client *ec)
    ec->comp_data->shell.ping(ec->comp_data->shell.surface);
 }
 
+static void
+_e_input_thread_client_icccm_name_set(void *data)
+{
+   E_Input_Thread_Request_EClient_Data *ec_data = data;
+   EINA_SAFETY_ON_NULL_RETURN(ec_data);
+
+   INF("[input thread|%s] ec(%p), name(%s)\n", __func__, ec_data->ec, ec_data->icccm_name);
+   e_input_thread_client_icccm_name_set(e_input_thread_client_get(ec_data->ec), ec_data->icccm_name);
+}
+
 EINTERN void
 e_client_icccm_name_set(E_Client *ec, const char *name)
 {
+   E_Input_Thread_Request_EClient_Data ec_data;
+   memset(&ec_data, 0, sizeof(E_Input_Thread_Request_EClient_Data));
+
    EINA_SAFETY_ON_NULL_RETURN(ec);
 
    if (eina_stringshare_replace(&ec->icccm.name, name))
-     ec->changes.title = EINA_TRUE;
+     {
+        ec->changes.title = EINA_TRUE;
+
+        ec_data.ec = ec;
+        ec_data.wl_surface = ec->comp_data ? ec->comp_data->wl_surface : NULL;
+        ec_data.is_video = EINA_FALSE;
+
+        if (name)
+          strncpy(ec_data.icccm_name, name, sizeof(ec_data.icccm_name)-1);
+
+        INF("[%s] ec(%p), surface(%p), name(%s)\n", __func__, ec, ec_data.wl_surface, name);
+        e_input_thread_safe_call(_e_input_thread_client_icccm_name_set, &ec_data, sizeof(E_Input_Thread_Request_EClient_Data));
+     }
 }
 
 E_API Eina_Stringshare *
@@ -7373,12 +7534,34 @@ e_client_icccm_name_get(E_Client *ec)
    return ec->icccm.name;
 }
 
+static void
+_e_input_thread_client_netwm_name_set(void *data)
+{
+   E_Input_Thread_Request_EClient_Data *ec_data = data;
+   EINA_SAFETY_ON_NULL_RETURN(ec_data);
+
+   INF("[input thread|%s] ec(%p), name(%p)\n", __func__, ec_data->ec, ec_data->netwm_name);
+   e_input_thread_client_netwm_name_set(e_input_thread_client_get(ec_data->ec), ec_data->netwm_name);
+}
+
 EINTERN void
 e_client_netwm_name_set(E_Client *ec, const char *name)
 {
+   E_Input_Thread_Request_EClient_Data ec_data = { NULL, NULL, EINA_FALSE, EINA_FALSE };
+   memset(&ec_data, 0, sizeof(E_Input_Thread_Request_EClient_Data));
+
    EINA_SAFETY_ON_NULL_RETURN(ec);
 
    eina_stringshare_replace(&ec->netwm.name, name);
+
+   ec_data.ec = ec;
+   ec_data.wl_surface = ec->comp_data ? ec->comp_data->wl_surface : NULL;
+
+   if (name)
+     strncpy(ec_data.netwm_name, name, sizeof(ec_data.netwm_name)-1);
+
+   INF("[%s] ec(%p), surface(%p), name(%s)\n", __func__, ec, ec_data.wl_surface, ec_data.netwm_name);
+   e_input_thread_safe_call(_e_input_thread_client_netwm_name_set, &ec_data, sizeof(E_Input_Thread_Request_EClient_Data));
 }
 
 E_API Eina_Stringshare *
@@ -7389,13 +7572,36 @@ e_client_netwm_name_get(E_Client *ec)
    return ec->netwm.name;
 }
 
+static void
+_e_input_thread_client_icccm_title_set(void *data)
+{
+   E_Input_Thread_Request_EClient_Data *ec_data = data;
+   EINA_SAFETY_ON_NULL_RETURN(ec_data);
+
+   INF("[input thread|%s] ec(%p), title(%s)\n", __func__, ec_data->ec, ec_data->icccm_title);
+   e_input_thread_client_icccm_title_set(e_input_thread_client_get(ec_data->ec), ec_data->icccm_title);
+}
+
 EINTERN void
 e_client_icccm_title_set(E_Client *ec, const char *title)
 {
+   E_Input_Thread_Request_EClient_Data ec_data;
+   memset(&ec_data, 0, sizeof(E_Input_Thread_Request_EClient_Data));
+
    EINA_SAFETY_ON_NULL_RETURN(ec);
 
    if (eina_stringshare_replace(&ec->icccm.title, title))
-     ec->changes.title = EINA_TRUE;
+     {
+        ec->changes.title = EINA_TRUE;
+
+        ec_data.ec = ec;
+        ec_data.wl_surface = ec->comp_data ? ec->comp_data->wl_surface : NULL;
+        if (title)
+          strncpy(ec_data.icccm_title, title, sizeof(ec_data.icccm_title)-1);
+
+        INF("[%s] ec(%p), surface(%p)\n", __func__, ec, ec_data.wl_surface);
+        e_input_thread_safe_call(_e_input_thread_client_icccm_title_set, &ec_data, sizeof(E_Input_Thread_Request_EClient_Data));
+     }
 }
 
 E_API Eina_Stringshare *
@@ -7501,3 +7707,31 @@ e_client_hide(E_Client *ec)
         ec->comp_data->mapped = 0;
      }
 }
+
+static void
+_e_input_thread_client_video_mode_set(void *data)
+{
+   E_Input_Thread_Request_EClient_Data *ec_data = data;
+   EINA_SAFETY_ON_NULL_RETURN(ec_data);
+
+   INF("[input thread|%s] ec(%p), is_video(%d)\n", __func__, ec_data->ec, ec_data->is_video);
+   e_input_thread_client_video_set(e_input_thread_client_get(ec_data->ec), ec_data->is_video);
+}
+
+EINTERN void
+e_client_video_mode_set(E_Client *ec, Eina_Bool is_video)
+{
+   E_Input_Thread_Request_EClient_Data ec_data;
+   memset(&ec_data, 0, sizeof(E_Input_Thread_Request_EClient_Data));
+
+   EINA_SAFETY_ON_NULL_RETURN(ec);
+   EINA_SAFETY_ON_NULL_RETURN(ec->hwc_window);
+
+   ec->hwc_window->is_video = is_video;
+
+   ec_data.ec = ec;
+   ec_data.is_video = is_video;
+
+   INF("[%s] ec(%p), is_video(%d)\n", __func__, ec, is_video);
+   e_input_thread_safe_call(_e_input_thread_client_video_mode_set, &ec_data, sizeof(E_Input_Thread_Request_EClient_Data));
+}