input: Support new APIs for traversing client lists 82/309382/1
authorInhong Han <inhong1.han@samsung.com>
Tue, 9 Apr 2024 04:53:34 +0000 (13:53 +0900)
committerTizen Window System <tizen.windowsystem@gmail.com>
Tue, 9 Apr 2024 08:26:09 +0000 (17:26 +0900)
Change-Id: Iae44ca0f36a9cc44914498bf5f3072e9df872c36

16 files changed:
src/bin/e_client.c
src/bin/e_client_intern.h
src/bin/e_comp_input.c
src/bin/e_comp_input_intern.h
src/bin/e_comp_object.c
src/bin/e_comp_wl_input.c
src/bin/e_comp_wl_shell.c
src/bin/e_desk_area.c
src/bin/e_info_server.c
src/bin/e_input_thread_client.c
src/bin/e_input_thread_client_intern.h
src/bin/e_policy_stack.c
src/bin/e_policy_wl.c
src/bin/e_zone.c
src/include/e_includes.h
src/include/e_input_thread_client.h

index dc60597..a0b62d7 100644 (file)
@@ -980,10 +980,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);
 
@@ -1028,6 +1041,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);
 
@@ -1035,10 +1052,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);
 
@@ -1113,6 +1142,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);
 }
 
@@ -2656,13 +2689,13 @@ e_client_visibility_get(E_Client *ec)
 }
 
 static void
-_e_input_thread_client_visible_set(void *data)
+_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), visible(%d)\n", __func__, ec_data->ec, ec_data->visible);
-   e_input_thread_client_visible_set(e_input_thread_client_get(ec_data->ec), ec_data->visible);
+   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
@@ -2678,10 +2711,10 @@ e_client_visibility_set(E_Client *ec, E_Visibility visibility)
    ec->visibility.obscured = visibility;
 
    ec_data.ec = ec;
-   ec_data.visible = ec->visibility.obscured;
+   ec_data.visibility = ec->visibility.obscured;
 
-   INF("[%s] ec(%p), visible(%d)\n", __func__, ec, ec->visibility.obscured);
-   e_input_thread_safe_call(_e_input_thread_client_visible_set, &ec_data, sizeof(E_Input_Thread_Request_EClient_Data));
+   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
@@ -6154,6 +6187,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)
@@ -6197,6 +6255,7 @@ 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;
           }
      }
@@ -7418,7 +7477,6 @@ e_client_icccm_name_set(E_Client *ec, const char *name)
 
         ec_data.ec = ec;
         ec_data.wl_surface = ec->comp_data ? ec->comp_data->wl_surface : NULL;
-        ec_data.visible = ec->visible;
         ec_data.is_video = EINA_FALSE;
 
         if (name)
@@ -7459,7 +7517,6 @@ e_client_netwm_name_set(E_Client *ec, const char *name)
 
    ec_data.ec = ec;
    ec_data.wl_surface = ec->comp_data ? ec->comp_data->wl_surface : NULL;
-   ec_data.visible = EINA_FALSE;
 
    if (name)
      strncpy(ec_data.netwm_name, name, sizeof(ec_data.netwm_name)-1);
index 40de000..f93fbf3 100644 (file)
@@ -168,6 +168,8 @@ EINTERN Eina_Bool e_client_desk_area_client_layer_set(E_Client *ec, E_Desk_Area_
 EINTERN E_Desk_Area_Client_Layer e_client_desk_area_client_layer_get(E_Client *ec);
 //#endif
 
+EINTERN void      e_client_input_thread_layer_set(E_Client *ec, E_Layer layer);
+
 // get a comp_data from a ec
 EINTERN E_Comp_Wl_Client_Data   *e_client_cdata_new(E_Client *ec);
 EINTERN void                     e_client_cdata_free(E_Client *ec);
index ef7fee8..349fb07 100644 (file)
@@ -1,9 +1,11 @@
 #include "e_comp_input_intern.h"
 #include "e_input_log.h"
+#include "e_input_thread_client_intern.h"
 
 #include <sys/mman.h>
 
 EINTERN E_Comp_Input_Key_Data *e_comp_input_key = NULL;
+EINTERN E_Comp_Input *e_comp_input = NULL;
 
 EINTERN void
 e_comp_input_init(void)
@@ -15,6 +17,13 @@ e_comp_input_init(void)
         return;
      }
 
+   e_comp_input = E_NEW(E_Comp_Input, 1);
+   if (!e_comp_input)
+     {
+        ERR("Failed to allocate memory for input\n");
+        return;
+     }
+
    e_comp_input_key->xkb.fd = -1;
 }
 
@@ -42,4 +51,33 @@ e_comp_input_shutdown(void)
 
         E_FREE(e_comp_input_key);
      }
+
+   if (e_comp_input)
+     E_FREE(e_comp_input);
+}
+
+EINTERN void e_comp_input_layers_update(E_Comp_Input_Layer_Data *layer_data)
+{
+   switch (layer_data->type)
+     {
+        case E_COMP_INPUT_INLIST_APPEND:
+          e_comp_input->layers[layer_data->layer].clients = eina_inlist_append(e_comp_input->layers[layer_data->layer].clients, e_input_thread_client_Inlist_get(layer_data->item));
+          break;
+        case E_COMP_INPUT_INLIST_PREPEND:
+          e_comp_input->layers[layer_data->layer].clients = eina_inlist_prepend(e_comp_input->layers[layer_data->layer].clients, e_input_thread_client_Inlist_get(layer_data->item));
+          break;
+        case E_COMP_INPUT_INLIST_APPEND_RELATIVE:
+          e_comp_input->layers[layer_data->layer].clients = eina_inlist_append_relative(e_comp_input->layers[layer_data->layer].clients, e_input_thread_client_Inlist_get(layer_data->item), e_input_thread_client_Inlist_get(layer_data->relative));
+          break;
+        case E_COMP_INPUT_INLIST_PREPEND_RELATIVE:
+          e_comp_input->layers[layer_data->layer].clients = eina_inlist_prepend_relative(e_comp_input->layers[layer_data->layer].clients, e_input_thread_client_Inlist_get(layer_data->item), e_input_thread_client_Inlist_get(layer_data->relative));
+          break;
+        case E_COMP_INPUT_INLIST_REMOVE:
+          e_comp_input->layers[layer_data->layer].clients = eina_inlist_remove(e_comp_input->layers[layer_data->layer].clients, e_input_thread_client_Inlist_get(layer_data->item));
+          e_comp_input->layers[layer_data->layer].clients_count--;
+          break;
+     }
+
+   if (layer_data->type < E_COMP_INPUT_INLIST_REMOVE)
+     e_comp_input->layers[layer_data->layer].clients_count++;
 }
index cd3ed45..6240e13 100644 (file)
@@ -4,7 +4,17 @@
 #include "e_intern.h"
 #include <xkbcommon/xkbcommon.h>
 
+typedef enum _E_Comp_Input_Inlist_Function_Type {
+   E_COMP_INPUT_INLIST_APPEND,
+   E_COMP_INPUT_INLIST_PREPEND,
+   E_COMP_INPUT_INLIST_APPEND_RELATIVE,
+   E_COMP_INPUT_INLIST_PREPEND_RELATIVE,
+   E_COMP_INPUT_INLIST_REMOVE,
+} E_Comp_Input_Inlist_Function_Type;
+
 typedef struct _E_Comp_Input_Key_Data E_Comp_Input_Key_Data;
+typedef struct _E_Comp_Input_Layer_Data E_Comp_Input_Layer_Data;
+typedef struct _E_Comp_Input E_Comp_Input;
 
 struct _E_Comp_Input_Key_Data
 {
@@ -38,9 +48,30 @@ struct _E_Comp_Input_Key_Data
      } kbd;
 };
 
+struct _E_Comp_Input_Layer_Data
+{
+   unsigned int layer;
+   E_Client *item;
+   E_Client *relative;
+   E_Comp_Input_Inlist_Function_Type type;
+};
+
+struct _E_Comp_Input
+{
+   E_Client *focused_ec;
+
+   struct
+     {
+        Eina_Inlist *clients;
+        unsigned int clients_count;
+     } layers[E_LAYER_COUNT];
+};
+
 extern EINTERN E_Comp_Input_Key_Data *e_comp_input_key;
+extern EINTERN E_Comp_Input *e_comp_input;
 
 EINTERN void e_comp_input_init(void);
 EINTERN void e_comp_input_shutdown(void);
+EINTERN void e_comp_input_layers_update(E_Comp_Input_Layer_Data *layer_data);
 
 #endif /* E_COMP_INPUT_INTERN_H */
index 679701e..6306feb 100644 (file)
@@ -490,20 +490,58 @@ _e_comp_shaped_check(int w, int h, const Eina_Rectangle *rects, int num)
 #ifdef REFACTOR_DESK_AREA
 #else
 static void
+_e_comp_input_thread_layers_update(void *data)
+{
+   E_Comp_Input_Layer_Data *layer_data = data;
+   EINA_SAFETY_ON_NULL_RETURN(layer_data);
+
+   INF("[input thread|%s] layer(%u), function type(%d), item(%p), relative(%p)\n",
+       __func__, layer_data->layer, layer_data->type, layer_data->item, layer_data->relative);
+   e_comp_input_layers_update(layer_data);
+}
+
+static void
+_e_comp_object_layers_update(unsigned int layer, E_Comp_Input_Inlist_Function_Type type, E_Client *item, E_Client *relative)
+{
+   E_Comp_Input_Layer_Data layer_data;
+   memset(&layer_data, 0, sizeof(E_Comp_Input_Layer_Data));
+
+   layer_data.layer = layer;
+   layer_data.type = type;
+   layer_data.item = item;
+   layer_data.relative = relative;
+
+   INF("[%s] layer(%u), function type(%d), item(%p), relative(%p)\n", __func__, layer, type, item, relative);
+   e_input_thread_safe_call(_e_comp_input_thread_layers_update, &layer_data, sizeof(E_Comp_Input_Layer_Data));
+}
+
+static void
 _e_comp_object_layers_add(E_Comp_Object *cw, E_Comp_Object *above, E_Comp_Object *below, Eina_Bool prepend)
 {
    g_rec_mutex_lock(&e_comp->ec_list_mutex);
 
    if (above)
-    e_comp->layers[above->layer].clients = eina_inlist_append_relative(e_comp->layers[above->layer].clients, EINA_INLIST_GET(cw->ec), EINA_INLIST_GET(above->ec));
+     {
+        e_comp->layers[above->layer].clients = eina_inlist_append_relative(e_comp->layers[above->layer].clients, EINA_INLIST_GET(cw->ec), EINA_INLIST_GET(above->ec));
+        _e_comp_object_layers_update(above->layer, E_COMP_INPUT_INLIST_APPEND_RELATIVE, e_comp->layers[above->layer].clients, cw->ec, above->ec);
+     }
    else if (below)
-     e_comp->layers[below->layer].clients = eina_inlist_prepend_relative(e_comp->layers[below->layer].clients, EINA_INLIST_GET(cw->ec), EINA_INLIST_GET(below->ec));
+     {
+        e_comp->layers[below->layer].clients = eina_inlist_prepend_relative(e_comp->layers[below->layer].clients, EINA_INLIST_GET(cw->ec), EINA_INLIST_GET(below->ec));
+        _e_comp_object_layers_update(above->layer, E_COMP_INPUT_INLIST_APPEND_RELATIVE, cw->ec, above->ec);
+     }
    if ((!above) && (!below))
      {
         if (prepend)
-          e_comp->layers[cw->layer].clients = eina_inlist_prepend(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
+          {
+             e_comp->layers[cw->layer].clients = eina_inlist_prepend(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
+             _e_comp_object_layers_update(cw->layer, E_COMP_INPUT_INLIST_PREPEND, cw->ec, NULL);
+          }
         else //this is either the layer object or a tough actin tinactin^W^W^Wfast stacking client
-          e_comp->layers[cw->layer].clients = eina_inlist_append(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
+          {
+             e_comp->layers[cw->layer].clients = eina_inlist_append(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
+             _e_comp_object_layers_update(cw->layer, E_COMP_INPUT_INLIST_APPEND, cw->ec, NULL);
+          }
      }
    e_comp->layers[cw->layer].clients_count++;
 
@@ -518,6 +556,7 @@ _e_comp_object_layers_remove(E_Comp_Object *cw)
    if (cw->ec && e_comp->layers[cw->layer].clients)
      {
         e_comp->layers[cw->layer].clients = eina_inlist_remove(e_comp->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
+        _e_comp_object_layers_update(cw->layer, E_COMP_INPUT_INLIST_REMOVE, cw->ec, NULL);
         e_comp->layers[cw->layer].clients_count--;
      }
 
@@ -1862,6 +1901,7 @@ layer_set:
    /* clamp to valid client layer */
    layer = e_comp_canvas_client_layer_map_nearest(layer);
    cw->ec->layer = layer;
+   e_client_input_thread_layer_set(cw->ec, layer);
    if (e_config->transient.layer)
      {
         E_Client *child;
index b43fcec..b9d3fb0 100644 (file)
@@ -145,12 +145,26 @@ _e_comp_wl_input_cb_resource_destroy(struct wl_client *client EINA_UNUSED, struc
 }
 
 static void
+_e_comp_wl_input_thread_cursor_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_block(%d), is_cursor(%d)\n", __func__, ec_data->ec, ec_data->layer_block, ec_data->is_cursor);
+   e_input_thread_client_layer_block_set(e_input_thread_client_get(ec_data->ec), ec_data->layer_block);
+   e_input_thread_client_is_cursor_set(e_input_thread_client_get(ec_data->ec), ec_data->is_cursor);
+}
+
+static void
 _e_comp_wl_input_pointer_cb_cursor_set(struct wl_client *client, struct wl_resource *resource EINA_UNUSED, uint32_t serial EINA_UNUSED, struct wl_resource *surface_resource, int32_t x, int32_t y)
 {
    E_Client *ec;
    Eina_Bool got_mouse = EINA_FALSE;
    struct wl_resource *surface;
 
+   E_Input_Thread_Request_EClient_Data ec_data;
+   memset(&ec_data, 0, sizeof(E_Input_Thread_Request_EClient_Data));
+
    E_CLIENT_FOREACH(ec)
      {
        if (e_object_is_del(E_OBJECT(ec))) continue;
@@ -209,6 +223,12 @@ _e_comp_wl_input_pointer_cb_cursor_set(struct wl_client *client, struct wl_resou
 
         e_client_layer_set(ec, E_LAYER_CLIENT_CURSOR);
         ec->is_cursor = EINA_TRUE;
+
+        ec_data.ec = ec;
+        ec_data.layer_block = ec->layer_block;
+        ec_data.is_cursor = ec->is_cursor;
+        INF("[%s] ec(%p), layer_block(%d), is_cursor(%d)\n", __func__, ec, ec->layer_block, ec->is_cursor);
+        e_input_thread_safe_call(_e_comp_wl_input_thread_cursor_set, &ec_data, sizeof(E_Input_Thread_Request_EClient_Data));
      }
 
    /* Set a pointer_object after wl_surface commit
index 85e77e5..7e3e5b9 100644 (file)
@@ -569,6 +569,7 @@ _e_shell_surface_cb_popup_set(struct wl_client *client EINA_UNUSED, struct wl_re
    if (ec->comp_data)
      ec->comp_data->set_win_type = EINA_TRUE;
    ec->layer = E_LAYER_CLIENT_POPUP;
+   e_client_input_thread_layer_set(ec, E_LAYER_CLIENT_POPUP);
 
    /* set this client as a transient for parent */
    e_shell_e_client_parent_set(ec, parent_resource);
index 58ff68c..c4917d2 100644 (file)
@@ -7,6 +7,8 @@
 #include "e_policy_intern.h"
 #include "e_maximize_intern.h"
 #include "e_policy_visibility_intern.h"
+#include "e_input_intern.h"
+#include "e_comp_input_intern.h"
 #endif
 #include "e_comp_wl_subsurface_intern.h"
 #include "e_zone_intern.h"
@@ -152,6 +154,32 @@ _e_desk_area_client_data_set(E_Desk_Area *eda, E_Client *ec)
 }
 
 static void
+_e_comp_input_thread_layers_update(void *data)
+{
+   E_Comp_Input_Layer_Data *layer_data = data;
+   EINA_SAFETY_ON_NULL_RETURN(layer_data);
+
+   INF("[input thread|%s] layer(%u), function type(%d), item(%p), relative(%p)\n",
+       __func__, layer_data->layer, layer_data->type, layer_data->item, layer_data->relative);
+   e_comp_input_layers_update(layer_data);
+}
+
+static void
+_e_comp_object_layers_update(unsigned int layer, E_Comp_Input_Inlist_Function_Type type, E_Client *item, E_Client *relative)
+{
+   E_Comp_Input_Layer_Data layer_data;
+   memset(&layer_data, 0, sizeof(E_Comp_Input_Layer_Data));
+
+   layer_data.layer = layer;
+   layer_data.type = type;
+   layer_data.item = item;
+   layer_data.relative = relative;
+
+   INF("[%s] layer(%u), function type(%d), item(%p), relative(%p)\n", __func__, layer, type, item, relative);
+   e_input_thread_safe_call(_e_comp_input_thread_layers_update, &layer_data, sizeof(E_Comp_Input_Layer_Data));
+}
+
+static void
 _e_comp_object_layers_add(E_Desk_Area *eda, E_Comp_Object *cw, E_Comp_Object *above, E_Comp_Object *below, Eina_Bool prepend)
 {
    g_rec_mutex_lock(&e_comp->ec_list_mutex);
@@ -160,18 +188,26 @@ _e_comp_object_layers_add(E_Desk_Area *eda, E_Comp_Object *cw, E_Comp_Object *ab
      {
         eda->layers[above->layer].clients = eina_inlist_append_relative(eda->layers[above->layer].clients, EINA_INLIST_GET(cw->ec), EINA_INLIST_GET(above->ec));
         eda->layers[above->layer].clients_count++;
+        _e_comp_object_layers_update(above->layer, E_COMP_INPUT_INLIST_APPEND_RELATIVE, cw->ec, above->ec);
      }
    else if (below)
      {
         eda->layers[below->layer].clients = eina_inlist_prepend_relative(eda->layers[below->layer].clients, EINA_INLIST_GET(cw->ec), EINA_INLIST_GET(below->ec));
         eda->layers[below->layer].clients_count++;
+        _e_comp_object_layers_update(below->layer, E_COMP_INPUT_INLIST_PREPEND_RELATIVE, cw->ec, below->ec);
      }
    else
      {
         if (prepend)
-          eda->layers[cw->layer].clients = eina_inlist_prepend(eda->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
+          {
+             eda->layers[cw->layer].clients = eina_inlist_prepend(eda->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
+             _e_comp_object_layers_update(cw->layer, E_COMP_INPUT_INLIST_PREPEND, cw->ec, NULL);
+          }
         else //this is either the layer object or a tough actin tinactin^W^W^Wfast stacking client
-          eda->layers[cw->layer].clients = eina_inlist_append(eda->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
+          {
+             eda->layers[cw->layer].clients = eina_inlist_append(eda->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
+             _e_comp_object_layers_update(cw->layer, E_COMP_INPUT_INLIST_APPEND, cw->ec, NULL);
+          }
         eda->layers[cw->layer].clients_count++;
      }
 
@@ -187,6 +223,7 @@ _e_comp_object_layers_remove(E_Desk_Area *eda, E_Comp_Object *cw)
      {
         eda->layers[cw->layer].clients = eina_inlist_remove(eda->layers[cw->layer].clients, EINA_INLIST_GET(cw->ec));
         eda->layers[cw->layer].clients_count--;
+        _e_comp_object_layers_update(cw->layer, E_COMP_INPUT_INLIST_REMOVE, cw->ec, NULL);
      }
 
    g_rec_mutex_unlock(&e_comp->ec_list_mutex);
@@ -1917,6 +1954,7 @@ layer_set:
    /* clamp to valid client layer */
    layer = e_comp_canvas_client_layer_map_nearest(layer);
    cw->ec->layer = layer;
+   e_client_input_thread_layer_set(cw->ec, layer);
    if (e_config->transient.layer)
      {
         E_Client *child;
index 6e32221..33759a9 100644 (file)
@@ -1875,6 +1875,7 @@ _set_win_prop_Layer(Evas_Object *evas_obj, const char *prop_value)
      return strdup("invalid property value");
 
    ec->layer = layer_idx;
+   e_client_input_thread_layer_set(ec, layer_idx);
 
    return NULL;
 }
index 0cf2e95..74a54a7 100644 (file)
@@ -1,11 +1,19 @@
 #include "e_input_thread_client_intern.h"
+#include "e_comp_canvas.h"
+#include "e_comp_input_intern.h"
 
 struct _E_Input_Thread_Client
 {
+   EINA_INLIST;
    void *ec;
    struct wl_resource *surface;
-   Eina_Bool visible;
+   E_Layer layer;
+   E_Visibility visibility;
+   Eina_Bool layer_block;
+   Eina_Bool layer_pending;
    Eina_Bool is_video;
+   Eina_Bool deleted;
+   Eina_Bool is_cursor;
    Eina_Stringshare *icccm_name;
    Eina_Stringshare *netwm_name;
    Eina_Stringshare *icccm_title;
@@ -37,6 +45,8 @@ e_input_thread_client_new(E_Client *ec, struct wl_resource *surface)
 
    itc->ec = ec;
    itc->surface = surface;
+   itc->layer = E_LAYER_CLIENT_NORMAL;
+   itc->visibility = E_VISIBILITY_UNKNOWN;
 
    _itc_list = eina_list_append(_itc_list, itc);
    INF("[%s] iec(%p), ec(%p), surface(%p)\n", __func__, itc, ec, surface);
@@ -55,21 +65,28 @@ e_input_thread_client_free(E_Input_Thread_Client *iec)
 }
 
 EINTERN void
-e_input_thread_visible_set(E_Input_Thread_Client *iec, Eina_Bool visible)
+e_input_thread_client_del(E_Input_Thread_Client *iec)
 {
    EINA_SAFETY_ON_NULL_RETURN(iec);
 
-   INF("[%s] iec(%p), visible(%d)\n", __func__, iec, visible);
+   iec->deleted = 1;
+}
+
+EINTERN void
+e_input_thread_client_visibility_set(E_Input_Thread_Client *iec, E_Visibility visibility)
+{
+   EINA_SAFETY_ON_NULL_RETURN(iec);
 
-   iec->visible = visible;
+   iec->visibility = visibility;
+   INF("[%s] iec(%p), visibility(%d)\n", __func__, iec, visibility);
 }
 
-E_API Eina_Bool
-e_input_thread_visible_get(E_Input_Thread_Client *iec, Eina_Bool visible)
+E_API E_Visibility
+e_input_thread_client_visibility_get(E_Input_Thread_Client *iec)
 {
-   EINA_SAFETY_ON_NULL_RETURN_VAL(iec, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(iec, E_VISIBILITY_UNKNOWN);
 
-   return iec->visible;
+   return iec->visibility;
 }
 
 E_API Eina_Bool
@@ -89,21 +106,12 @@ e_input_thread_client_video_set(E_Input_Thread_Client *iec, Eina_Bool is_video)
    INF("[%s] iec(%p), video(%d)\n", __func__, iec, is_video);
 }
 
-EINTERN void
-e_input_thread_client_visible_set(E_Input_Thread_Client *iec, Eina_Bool visible)
-{
-   EINA_SAFETY_ON_NULL_RETURN(iec);
-
-   iec->visible = visible;
-   INF("[%s] iec(%p), ec(%p), visible(%d)\n", __func__, iec, iec->ec, visible);
-}
-
 E_API Eina_Bool
 e_input_thread_client_visible_get(E_Input_Thread_Client *iec)
 {
    EINA_SAFETY_ON_NULL_RETURN_VAL(iec, EINA_FALSE);
 
-   return iec->visible;
+   return iec->visibility;
 }
 
 EINTERN void
@@ -159,6 +167,58 @@ e_input_thread_client_netwm_name_get(E_Input_Thread_Client *iec)
    return iec->icccm_name;
 }
 
+E_API Eina_Stringshare *
+e_input_thread_client_util_name_get(E_Input_Thread_Client *iec)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(iec, NULL);
+
+   if (iec->netwm_name)
+     return iec->netwm_name;
+   else if (iec->icccm_title)
+     return iec->icccm_title;
+
+   return NULL;
+}
+
+E_API Eina_Bool e_input_thread_client_cursor_mode_get(E_Input_Thread_Client *iec)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(iec, EINA_FALSE);
+
+   return iec->is_cursor;
+}
+
+EINTERN void e_input_thread_client_layer_set(E_Input_Thread_Client *iec, E_Layer layer)
+{
+   EINA_SAFETY_ON_NULL_RETURN(iec);
+
+   iec->layer = layer;
+   INF("[%s] iec(%p), layer(%d)\n", __func__, iec, layer);
+}
+
+EINTERN void e_input_thread_client_layer_block_set(E_Input_Thread_Client *iec, Eina_Bool block)
+{
+   EINA_SAFETY_ON_NULL_RETURN(iec);
+
+   iec->layer_block = block;
+   INF("[%s] iec(%p), layer_block(%d)\n", __func__, iec, iec->layer_block);
+}
+
+EINTERN void e_input_thread_client_layer_pending_set(E_Input_Thread_Client *iec, Eina_Bool pending)
+{
+   EINA_SAFETY_ON_NULL_RETURN(iec);
+
+   iec->layer_pending = pending;
+   INF("[%s] iec(%p), layer_pending(%d)\n", __func__, iec, iec->layer_pending);
+}
+
+EINTERN void e_input_thread_client_is_cursor_set(E_Input_Thread_Client *iec, Eina_Bool is_cursor)
+{
+   EINA_SAFETY_ON_NULL_RETURN(iec);
+
+   iec->is_cursor = is_cursor;
+   INF("[%s] iec(%p), is_cursor(%d)\n", __func__, iec, iec->is_cursor);
+}
+
 EINTERN E_Input_Thread_Client * e_input_thread_client_get(E_Client *ec)
 {
    Eina_List *l;
@@ -176,3 +236,180 @@ EINTERN E_Input_Thread_Client * e_input_thread_client_get(E_Client *ec)
 
    return NULL;
 }
+
+EINTERN Eina_Inlist * e_input_thread_client_Inlist_get(E_Client *ec)
+{
+   E_Input_Thread_Client *iec = e_input_thread_client_get(ec);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(iec, NULL);
+
+   return &(iec->__in_list);
+}
+
+E_API E_Input_Thread_Client *e_input_thread_client_above_get(E_Input_Thread_Client *iec)
+{
+   unsigned int x;
+   E_Input_Thread_Client *iec2;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(iec, NULL);
+   if (EINA_INLIST_GET(iec)->next) //check current layer
+     {
+        EINA_INLIST_FOREACH(EINA_INLIST_GET(iec)->next, iec2)
+          {
+             if (iec == iec2)
+               {
+                  INF("[%s] iec: %p\n", __func__, iec);
+                  continue;
+               }
+             if (!iec2->deleted)
+               return iec2;
+          }
+     }
+   if (iec->layer == E_LAYER_CLIENT_CURSOR) return NULL;
+   if (e_comp_canvas_client_layer_map(iec->layer) == 9999) return NULL;
+
+   for (x = e_comp_canvas_layer_map(iec->layer) + 1; x <= e_comp_canvas_layer_map(E_LAYER_CLIENT_CURSOR); x++)
+     {
+        if (!e_comp_input->layers[x].clients) continue;
+        EINA_INLIST_FOREACH(e_comp_input->layers[x].clients, iec2)
+          {
+             if (iec == iec2)
+               {
+                  INF("EC exist above layer. ec layer_map:%d, cur layer_map:%d", e_comp_canvas_layer_map(iec->layer), x);
+                  continue;
+               }
+             if (!iec2->deleted)
+               {
+                  return iec2;
+               }
+          }
+     }
+
+   return NULL;
+}
+
+E_API E_Input_Thread_Client *e_input_thread_client_below_get(E_Input_Thread_Client *iec)
+{
+   unsigned int x;
+   E_Input_Thread_Client *iec2;
+   Eina_Inlist *l;
+   E_Layer iec_layer, iec_layer_cw;
+   int cw_layer;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(iec, NULL);
+   if (EINA_INLIST_GET(iec)->prev) //check current layer
+     {
+        for (l = EINA_INLIST_GET(iec)->prev; l; l = l->prev)
+          {
+             iec2 = EINA_INLIST_CONTAINER_GET(l, E_Input_Thread_Client);
+             if (iec == iec2)
+               {
+                  INF("CHECK the ec inlist prev");
+                  continue;
+               }
+             if (!iec2->deleted)
+               return iec2;
+          }
+     }
+
+   // check layer validation
+   iec_layer = iec->layer;
+   if (iec->layer_block || iec->layer_pending)
+     {
+        cw_layer = iec->layer;
+        if (cw_layer >= 0)
+          {
+             iec_layer_cw = e_comp_canvas_layer_map_to(cw_layer);
+             if (iec_layer != iec_layer_cw)
+               {
+                  INF("LAYER is not same. USE obj layer! (ec->layer:%d, obj:%d). block:%d, pending:%d)", iec_layer, iec_layer_cw, iec->layer_block, iec->layer_pending);
+                  iec_layer = iec_layer_cw;
+               }
+          }
+     }
+
+   if (iec_layer == E_LAYER_CLIENT_DESKTOP) return NULL;
+   if (e_comp_canvas_client_layer_map(iec_layer) == 9999) return NULL;
+
+   /* go down the layers until we find one */
+   x = e_comp_canvas_layer_map(iec_layer);
+   if (x > 0) x--;
+
+   for (; x >= e_comp_canvas_layer_map(E_LAYER_CLIENT_DESKTOP); x--)
+     {
+        if (!e_comp_input->layers[x].clients) continue;
+        EINA_INLIST_REVERSE_FOREACH(e_comp_input->layers[x].clients, iec2)
+          {
+             if (iec == iec2)
+               {
+                  INF("EC exist below layer. ec layer_map:%d, cur layer_map:%d", e_comp_canvas_layer_map(iec_layer), x);
+                  continue;
+               }
+             if (!iec2->deleted)
+               return iec2;
+          }
+     }
+
+   return NULL;
+}
+
+E_API E_Input_Thread_Client *e_input_thread_client_bottom_get()
+{
+   unsigned int x;
+   for (x = e_comp_canvas_layer_map(E_LAYER_CLIENT_DESKTOP); x <= e_comp_canvas_layer_map(E_LAYER_CLIENT_CURSOR); x++)
+     {
+        E_Input_Thread_Client *iec2;
+        if (!e_comp_input->layers[x].clients) continue;
+
+        EINA_INLIST_FOREACH(e_comp_input->layers[x].clients, iec2)
+          if (!iec2->deleted)
+            return iec2;
+     }
+
+   return NULL;
+}
+
+E_API E_Input_Thread_Client *e_input_thread_client_top_get()
+{
+   unsigned int x;
+   for (x = e_comp_canvas_layer_map(E_LAYER_CLIENT_CURSOR); x >= e_comp_canvas_layer_map(E_LAYER_CLIENT_DESKTOP); x--)
+     {
+        E_Input_Thread_Client *iec2;
+        if (!e_comp_input->layers[x].clients) continue;
+
+        EINA_INLIST_REVERSE_FOREACH(e_comp_input->layers[x].clients, iec2)
+          if (!iec2->deleted)
+            return iec2;
+     }
+
+   return NULL;
+}
+
+E_API E_Input_Thread_Client *e_input_thread_client_focused_get()
+{
+   return e_input_thread_client_get(e_comp_input->focused_ec);
+}
+
+E_API E_Input_Thread_Client *e_input_thread_client_from_surface_resource(struct wl_resource *surface_resource)
+{
+   Eina_List *l;
+   void *list_data;
+   E_Input_Thread_Client *itc = NULL;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(surface_resource, NULL);
+
+   EINA_LIST_FOREACH(_itc_list, l, list_data)
+     {
+        itc = (E_Input_Thread_Client *)list_data;
+        if (itc && itc->surface == surface_resource)
+          return itc;
+     }
+
+   return NULL;
+}
+
+E_API struct wl_resource *e_input_thread_client_wl_resource_get(E_Input_Thread_Client *iec)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(iec, NULL);
+
+   return iec->surface;
+}
index 102c8a5..7fbf922 100644 (file)
@@ -11,8 +11,13 @@ typedef struct
 {
   void *ec;
   struct wl_resource *wl_surface;
-  bool visible;
+  E_Layer layer;
+  E_Visibility visibility;
+  Eina_Bool layer_block;
+  Eina_Bool layer_pending;
   bool is_video;
+  Eina_Bool deleted;
+  Eina_Bool is_cursor;
   char icccm_name[1024];
   char netwm_name[1024];
   char icccm_title[1024];
@@ -35,13 +40,20 @@ typedef struct
 
 EINTERN E_Input_Thread_Client * e_input_thread_client_new(E_Client *ec, struct wl_resource *surface);
 EINTERN void e_input_thread_client_free(E_Input_Thread_Client *ec);
-EINTERN void e_input_thread_client_visible_set(E_Input_Thread_Client *ec, Eina_Bool visible);
+EINTERN void e_input_thread_client_del(E_Input_Thread_Client *ec);
+EINTERN void e_input_thread_client_visibility_set(E_Input_Thread_Client *ec, E_Visibility visibility);
 EINTERN void e_input_thread_client_video_set(E_Input_Thread_Client *ec, Eina_Bool is_video);
 
 EINTERN void e_input_thread_client_icccm_name_set(E_Input_Thread_Client *ec, char *name);
 EINTERN void e_input_thread_client_icccm_title_set(E_Input_Thread_Client *ec, char *title);
 EINTERN void e_input_thread_client_netwm_name_set(E_Input_Thread_Client *ec, char *name);
 
+EINTERN void e_input_thread_client_layer_set(E_Input_Thread_Client *ec, E_Layer layer);
+EINTERN void e_input_thread_client_layer_block_set(E_Input_Thread_Client *ec, Eina_Bool block);
+EINTERN void e_input_thread_client_layer_pending_set(E_Input_Thread_Client *ec, Eina_Bool pending);
+EINTERN void e_input_thread_client_is_cursor_set(E_Input_Thread_Client *ec, Eina_Bool is_cursor);
+
 EINTERN E_Input_Thread_Client * e_input_thread_client_get(E_Client *ec);
+EINTERN Eina_Inlist * e_input_thread_client_Inlist_get(E_Client *ec);
 
 #endif
index 18c3a54..3c205eb 100644 (file)
@@ -609,6 +609,7 @@ e_policy_stack_clients_restack_above_lockscreen(E_Client *ec_lock, Eina_Bool sho
                        ELOGF("CHANGE to Original layer", "AboveLock|layer: %d -> %d", ec, ec->layer, org_layer);
                        e_client_layer_set(ec, org_layer);
                        ec->layer = org_layer;
+                       e_client_input_thread_layer_set(ec, org_layer);
 
                        ec->changable_layer[E_CHANGABLE_LAYER_TYPE_ABOVE_NOTIFICATION].saved = EINA_FALSE;
                        ec->changable_layer[E_CHANGABLE_LAYER_TYPE_ABOVE_NOTIFICATION].saved_layer = 0;
@@ -680,6 +681,7 @@ e_policy_stack_clients_restack_above_lockscreen(E_Client *ec_lock, Eina_Bool sho
                     e_client_layer_set(ec, lock_layer);
 
                   ec->layer = lock_layer;
+                  e_client_input_thread_layer_set(ec, lock_layer);
                }
              eina_list_free(restack_list);
              restack_list = NULL;
index 293f5fa..54201a2 100644 (file)
@@ -31,6 +31,8 @@
 #include "e_utils_intern.h"
 #include "e_screensaver_intern.h"
 #include "e_hwc_window_intern.h"
+#include "e_input_intern.h"
+#include "e_input_thread_client_intern.h"
 
 #include <device/display.h>
 #include <wayland-server.h>
@@ -1846,6 +1848,16 @@ _tzpol_iface_cb_focus_skip_unset(struct wl_client *client EINA_UNUSED, struct wl
    e_client_focus_skip_set(ec, EINA_FALSE, EINA_TRUE);
 }
 
+static void
+_e_policy_wl_input_thread_cursor_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_cursor(%d)\n", __func__, ec_data->ec, ec_data->is_cursor);
+   e_input_thread_client_is_cursor_set(e_input_thread_client_get(ec_data->ec), ec_data->is_cursor);
+}
+
 // --------------------------------------------------------
 // role
 // --------------------------------------------------------
@@ -1854,6 +1866,8 @@ _tzpol_iface_cb_role_set(struct wl_client *client EINA_UNUSED, struct wl_resourc
 {
    E_Client *ec;
    E_Comp_Wl_Client_Data *cdata;
+   E_Input_Thread_Request_EClient_Data ec_data;
+   memset(&ec_data, 0, sizeof(E_Input_Thread_Request_EClient_Data));
 
    EINA_SAFETY_ON_NULL_RETURN(role);
 
@@ -1887,6 +1901,11 @@ _tzpol_iface_cb_role_set(struct wl_client *client EINA_UNUSED, struct wl_resourc
         e_client_layer_set(ec, E_LAYER_CLIENT_CURSOR);
         ec->is_cursor = EINA_TRUE;
         e_client_desk_iconify_skip_set(ec, EINA_TRUE);
+
+        ec_data.ec = ec;
+        ec_data.is_cursor = 1;
+        INF("[%s] ec(%p), is_cursor(%d)\n", __func__, ec, ec->is_cursor);
+        e_input_thread_safe_call(_e_policy_wl_input_thread_cursor_set, &ec_data, sizeof(E_Input_Thread_Request_EClient_Data));
      }
 }
 
index 1573649..23f9542 100644 (file)
@@ -16,6 +16,8 @@
 #include "e_policy_visibility_intern.h"
 #include "e_comp_object_intern.h"
 #include "e_comp_canvas_intern.h"
+#include "e_comp_input_intern.h"
+#include "e_input_thread_client_intern.h"
 
 #include <libds-tizen/screen.h>
 
@@ -52,6 +54,8 @@ struct _E_Zone_Private
    struct ds_tizen_screen *tizen_screen;
    struct wl_listener screen_destroy;
    struct wl_listener screen_get_splitscreen;
+
+   struct wl_listener focus_focused_ec_changed;
 };
 
 struct _E_Zone_Private_Client
@@ -152,6 +156,7 @@ _e_zone_private_finish(E_Zone *zone)
 
    e_object_data_set(E_OBJECT(zone), NULL);
 
+   wl_list_remove(&priv->focus_focused_ec_changed.link);
    wl_list_remove(&priv->screen_get_splitscreen.link);
    wl_list_remove(&priv->screen_destroy.link);
 
@@ -1167,6 +1172,36 @@ _e_zone_client_data_set(E_Zone *zone, E_Client *ec)
   evas_object_data_set(ec->frame, ZONE_EC_DATA_KEY, zone);
 }
 
+static void
+_e_zone_input_thread_focused_client_set(void *data)
+{
+   E_Input_Thread_Request_EClient_Data *ec_data = data;
+   EINA_SAFETY_ON_NULL_RETURN(ec_data);
+
+   if (e_comp_input->focused_ec != ec_data->ec)
+     {
+        INF("[input thread|%s] focused ec(%p)\n", __func__, ec_data->ec);
+        e_comp_input->focused_ec = ec_data->ec;
+     }
+}
+
+static void
+_zone_cb_focus_focused_ec_changed(struct wl_listener *listener, void *data)
+{
+   E_Zone_Private *zone_private;
+   E_Client *focused_ec;
+
+   zone_private = wl_container_of(listener, zone_private, focus_focused_ec_changed);
+   focused_ec = (E_Client *)data;
+
+   E_Input_Thread_Request_EClient_Data ec_data;
+   memset(&ec_data, 0, sizeof(E_Input_Thread_Request_EClient_Data));
+   ec_data.ec = focused_ec;
+
+   INF("[%s] focused ec(%p)\n", __func__, focused_ec);
+   e_input_thread_safe_call(_e_zone_input_thread_focused_client_set, &ec_data, sizeof(E_Input_Thread_Request_EClient_Data));
+}
+
 EINTERN E_Zone *
 e_zone_new(int num, int id, int x, int y, int w, int h)
 {
@@ -1209,6 +1244,14 @@ e_zone_new(int num, int id, int x, int y, int w, int h)
           }
      }
 
+   E_Zone_Private *priv;
+   priv = PRI(zone);
+   if (priv)
+     {
+        priv->focus_focused_ec_changed.notify = _zone_cb_focus_focused_ec_changed;
+        e_focus_focused_ec_changed_listener_add(zone->focus, &priv->focus_focused_ec_changed);
+     }
+
    //printf("@@@@@@@@@@ e_zone_new: %i %i | %i %i %ix%i = %p\n", num, id, x, y, w, h, zone);
 
    snprintf(name, sizeof(name), "Zone %d", zone->num);
index dd59eac..d691ab0 100644 (file)
@@ -64,3 +64,4 @@
 #include "e_desk_area.h"
 #include "e_comp_wl_capture.h"
 #include "e_map.h"
+#include "e_input_thread_client.h"
\ No newline at end of file
index e37b21d..a242cae 100644 (file)
@@ -7,8 +7,21 @@ typedef struct _E_Input_Thread_Client E_Input_Thread_Client;
 
 E_API Eina_Bool e_input_thread_client_video_mode_get(E_Input_Thread_Client *ec);
 E_API Eina_Bool e_input_thread_client_visible_get(E_Input_Thread_Client *ec);
+E_API E_Visibility e_input_thread_client_visibility_get(E_Input_Thread_Client *ec);
+E_API Eina_Bool e_input_thread_client_cursor_mode_get(E_Input_Thread_Client *ec);
+
 E_API Eina_Stringshare *e_input_thread_client_icccm_name_get(E_Input_Thread_Client *ec);
 E_API Eina_Stringshare *e_input_thread_client_netwm_name_get(E_Input_Thread_Client *ec);
 E_API Eina_Stringshare *e_input_thread_client_icccm_title_get(E_Input_Thread_Client *ec);
+E_API Eina_Stringshare *e_input_thread_client_util_name_get(E_Input_Thread_Client *ec);
+
+E_API E_Input_Thread_Client *e_input_thread_client_above_get(E_Input_Thread_Client *ec);
+E_API E_Input_Thread_Client *e_input_thread_client_below_get(E_Input_Thread_Client *ec);
+E_API E_Input_Thread_Client *e_input_thread_client_bottom_get();
+E_API E_Input_Thread_Client *e_input_thread_client_top_get();
+E_API E_Input_Thread_Client *e_input_thread_client_focused_get();
+
+E_API E_Input_Thread_Client *e_input_thread_client_from_surface_resource(struct wl_resource *surface_resource);
+E_API struct wl_resource *e_input_thread_client_wl_resource_get(E_Input_Thread_Client *ec);
 
 #endif