Add e_client_under_position_input_get() 26/283226/4
authorArtur Świgoń <a.swigon@samsung.com>
Thu, 20 Oct 2022 09:19:59 +0000 (11:19 +0200)
committerDoyoun Kang <doyoun.kang@samsung.com>
Mon, 18 Sep 2023 05:23:48 +0000 (05:23 +0000)
Similarly to e_client_under_position_get(), it performs a hit-test, but input
regions are also considered. If input regions are present, then the specified
position needs to be inside such a region.

Change-Id: Ie75c346ffc6e535fdb678e7b5748435f9a003bbb

src/bin/e_client.c
src/bin/e_client.h

index 76d6e0a..13508af 100644 (file)
@@ -1893,6 +1893,18 @@ _e_client_position_inside_input_rect(E_Client *ec, int tx, int ty)
    return res;
 }
 
+static Eina_Bool
+_e_client_under_pointer_helper_ignore_client(E_Desk *desk, E_Client *client)
+{
+   /* If a border was specified which should be excluded from the list
+    * (because it will be closed shortly for example), skip */
+   if (e_client_util_ignored_get(client) || (!e_desk_has_ec(desk, client))) return EINA_TRUE;
+   if (!evas_object_visible_get(client->frame)) return EINA_TRUE;
+   if (e_policy_client_is_cursor(client)) return EINA_TRUE;
+
+   return EINA_FALSE;
+}
+
 static E_Client *
 _e_client_under_pointer_helper(E_Desk *desk, E_Client *exclude, int x, int y)
 {
@@ -1900,11 +1912,7 @@ _e_client_under_pointer_helper(E_Desk *desk, E_Client *exclude, int x, int y)
 
    E_CLIENT_REVERSE_FOREACH(cec)
      {
-        /* If a border was specified which should be excluded from the list
-         * (because it will be closed shortly for example), skip */
-        if (e_client_util_ignored_get(cec) || (!e_desk_has_ec(desk, cec))) continue;
-        if (!evas_object_visible_get(cec->frame)) continue;
-        if (e_policy_client_is_cursor(cec)) continue;
+        if (_e_client_under_pointer_helper_ignore_client(desk, cec)) continue;
         if ((exclude) && (cec == exclude)) continue;
         if (!E_INSIDE(x, y, cec->x, cec->y, cec->w, cec->h))
           continue;
@@ -1937,6 +1945,43 @@ _e_client_input_rect_under_pointer_helper(E_Desk *desk, E_Client *exclude, int x
         if (_e_client_position_inside_input_rect(cec, x, y))
           ec = cec;
      }
+
+   return ec;
+}
+
+static E_Client *
+_e_client_under_pointer_input_helper(E_Desk *desk, int x, int y)
+{
+   E_Client *ec = NULL, *cec;
+
+   E_CLIENT_REVERSE_FOREACH(cec)
+     {
+        if (_e_client_under_pointer_helper_ignore_client(desk, cec)) continue;
+
+        Eina_List *list = NULL;
+        Eina_Rectangle *rect;
+        Eina_Bool inside = EINA_FALSE;
+        e_comp_object_input_rect_get(cec->frame, &list);
+        if (list)
+          {
+             EINA_LIST_FREE(list, rect)
+               {
+                  if (E_INSIDE(x, y, rect->x, rect->y, rect->w, rect->h))
+                    inside = EINA_TRUE;
+               }
+          }
+        else if (E_INSIDE(x, y, cec->x, cec->y, cec->w, cec->h))
+          {
+             inside = EINA_TRUE;
+          }
+
+        if (!inside) continue;
+        /* If the layer is higher, the position of the window is higher
+         * (always on top vs always below) */
+        if (!ec || (cec->layer > ec->layer))
+          ec = cec;
+     }
+
    return ec;
 }
 
@@ -6902,6 +6947,13 @@ E_API E_Client *e_client_under_position_get(E_Desk *desk, int x, int y, E_Client
    return _e_client_under_pointer_helper(desk, exclude, x, y);
 }
 
+E_API E_Client *e_client_under_position_input_get(E_Desk *desk, int x, int y)
+{
+   if (!desk) return NULL;
+
+   return _e_client_under_pointer_input_helper(desk, x, y);
+}
+
 EINTERN E_Client *
 e_client_input_rect_under_pointer_get(E_Desk *desk, E_Client *exclude)
 {
index ca4b8c2..7f1dc9e 100644 (file)
@@ -1210,6 +1210,7 @@ EINTERN void e_client_resize_limit(E_Client *ec, int *w, int *h);
 EINTERN E_Client *e_client_under_pointer_get(E_Desk *desk, E_Client *exclude);
 E_API E_Client *e_client_under_position_get(E_Desk *desk, int x, int y, E_Client *exclude);
 EINTERN E_Client *e_client_input_rect_under_pointer_get(E_Desk *desk, E_Client *exclude);
+E_API E_Client *e_client_under_position_input_get(E_Desk *desk, int x, int y);
 E_API void e_client_redirected_set(E_Client *ec, Eina_Bool set);
 EINTERN Eina_Bool e_client_is_stacking(const E_Client *ec);
 EINTERN E_Client *e_client_transient_child_top_get(E_Client *ec, Eina_Bool consider_focus);