e_client: Add function to get E_Client under pointer consider input rect 74/288574/1
authorJunseok Kim <juns.kim@samsung.com>
Thu, 9 Feb 2023 09:53:56 +0000 (18:53 +0900)
committerDoyoun Kang <doyoun.kang@samsung.com>
Mon, 20 Feb 2023 05:02:04 +0000 (05:02 +0000)
Add function to get E_Client under pointer with considering input rect
of client.

Change-Id: I33d41f1434da70feb42f203bfc43412ff969b344

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

index 43d09c4628143e07503d582d950c8a36d3fda560..0ff095b1cf1a9a02df0f65832127a1addffd414c 100644 (file)
@@ -2163,6 +2163,44 @@ _e_client_resize_mouse_down(void *data EINA_UNUSED, int type EINA_UNUSED, void *
 
 ////////////////////////////////////////////////
 
+static Eina_Bool
+_e_client_position_inside_input_rect(E_Client *ec, int tx, int ty)
+{
+   int x, y, w, h;
+   Eina_Bool res = EINA_FALSE;
+   Eina_List *list = NULL, *l;
+   Eina_Rectangle *data;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
+
+   e_comp_object_input_rect_get(ec->frame, &list);
+   if (list)
+     {
+        EINA_LIST_FOREACH(list, l, data)
+          {
+             if ((tx >= data->x) && (tx <= data->x + data->w) &&
+                 (ty >= data->y) && (ty <= data->y + data->h))
+               {
+                  res = EINA_TRUE;
+                  break;
+               }
+          }
+        list = eina_list_free(list);
+     }
+   else
+     {
+        e_client_geometry_get(ec, &x, &y, &w, &h);
+
+        if ((tx >= x) && (tx <= x + w) &&
+            (ty >= y) && (ty <= y + h))
+          {
+             res = EINA_TRUE;
+          }
+     }
+
+   return res;
+}
+
 static E_Client *
 _e_client_under_pointer_helper(E_Desk *desk, E_Client *exclude, int x, int y)
 {
@@ -2186,6 +2224,30 @@ _e_client_under_pointer_helper(E_Desk *desk, E_Client *exclude, int x, int y)
    return ec;
 }
 
+static E_Client *
+_e_client_input_rect_under_pointer_helper(E_Desk *desk, E_Client *exclude, int x, int y)
+{
+   E_Client *ec = NULL, *cec;
+
+   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_client_util_desk_visible(cec, desk))) continue;
+        if (!evas_object_visible_get(cec->frame)) continue;
+        if (e_policy_client_is_cursor(cec)) continue;
+        if ((exclude) && (cec == exclude)) continue;
+        if (!E_INSIDE(x, y, cec->x, cec->y, cec->w, cec->h))
+          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)) continue;
+        if (_e_client_position_inside_input_rect(cec, x, y))
+          ec = cec;
+     }
+   return ec;
+}
+
 ////////////////////////////////////////////////
 
 static void
@@ -3560,41 +3622,14 @@ e_client_transient_child_top_get(E_Client *ec, Eina_Bool consider_focus)
 static Eina_Bool
 _e_client_visibility_touched_check(E_Client *ec)
 {
-   int x, y, w, h;
    int tx, ty;
-   Eina_List *list = NULL, *l;
-   Eina_Rectangle *data;
 
    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
 
    tx = wl_fixed_to_int(e_comp->wl_comp_data->ptr.x);
    ty = wl_fixed_to_int(e_comp->wl_comp_data->ptr.y);
 
-   e_comp_object_input_rect_get(ec->frame, &list);
-   if (list)
-     {
-        EINA_LIST_FOREACH(list, l, data)
-          {
-             if ((tx >= data->x) && (tx <= data->x + data->w) &&
-                 (ty >= data->y) && (ty <= data->y + data->h))
-               {
-                  return EINA_TRUE;
-               }
-          }
-        list = eina_list_free(list);
-     }
-   else
-     {
-        e_client_geometry_get(ec, &x, &y, &w, &h);
-
-        if ((tx >= x) && (tx <= x + w) &&
-            (ty >= y) && (ty <= y + h))
-          {
-             return EINA_TRUE;
-          }
-     }
-
-   return EINA_FALSE;
+   return _e_client_position_inside_input_rect(ec, tx, ty);
 }
 
 static void
@@ -7383,6 +7418,36 @@ 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);
 }
 
+EINTERN E_Client *
+e_client_input_rect_under_pointer_get(E_Desk *desk, E_Client *exclude)
+{
+   int x, y;
+
+   /* We need to ensure that we can get the comp window for the
+    * zone of either the given desk or the desk of the excluded
+    * window, so return if neither is given */
+   if (desk)
+     e_input_device_pointer_xy_get(NULL, &x, &y);
+   else if (exclude)
+     e_input_device_pointer_xy_get(NULL, &x, &y);
+   else
+     return NULL;
+
+   if (!desk)
+     {
+        desk = exclude->desk;
+        if (!desk)
+          {
+             if (exclude->zone)
+               desk = e_desk_current_get(exclude->zone);
+             else
+               desk = e_desk_current_get(e_zone_current_get());
+          }
+     }
+
+   return desk ? _e_client_input_rect_under_pointer_helper(desk, exclude, x, y) : NULL;
+}
+
 ////////////////////////////////////////////
 
 E_API int
index bd442002ce335e0b133b838f6647de6858adb0a6..6504cc0453ac77be7ec3b3f8c56c70e7f6c9e347 100644 (file)
@@ -1214,6 +1214,7 @@ E_API void e_client_signal_resize_end(E_Client *ec, const char *dir EINA_UNUSED,
 E_API void e_client_resize_limit(E_Client *ec, int *w, int *h);
 E_API 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 int e_client_pointer_warp_to_center_now(E_Client *ec);
 E_API int e_client_pointer_warp_to_center(E_Client *ec);
 E_API void e_client_redirected_set(E_Client *ec, Eina_Bool set);