e_policy_visibility: get below activity clients with eina_tiler 03/229003/2
authorJunseok, Kim <juns.kim@samsung.com>
Fri, 27 Mar 2020 04:19:32 +0000 (13:19 +0900)
committerJunseok, Kim <juns.kim@samsung.com>
Mon, 30 Mar 2020 07:52:05 +0000 (16:52 +0900)
Change-Id: I1710f3174a9c85ff33a53693150bf4542e02cd54

src/bin/e_policy_visibility.c

index 590458203770fbf50958b02153ec879d1e86df5f..3e2981ec11d68810389848e29cba6285e85b6f60 100644 (file)
@@ -1718,46 +1718,16 @@ _e_vis_ec_above_visible_type(E_Client *ec, Eina_Bool check_child)
 }
 
 static Eina_Bool
-_e_vis_client_check_obscured_by_above_regions(E_Client *ec, E_Client *except_ec)
+_e_vis_client_check_obscure_below(E_Client *ec)
 {
-   E_Client *above = NULL;
-   Eina_Tiler *t = NULL;
-   Eina_Rectangle r;
-   int ex, ey, ew, eh;
-   int ax, ay, aw, ah;
-
-   t = eina_tiler_new(ec->w, ec->h);
-   eina_tiler_tile_size_set(t, 1, 1);
-   e_client_geometry_get(ec, &ex, &ey, &ew, &eh);
-   EINA_RECTANGLE_SET(&r, ex, ey, ew, eh);
-   eina_tiler_rect_add(t, &r);
-
-   for (above = e_client_above_get(ec); above; above = e_client_above_get(above))
-     {
-        if (above == except_ec) continue;
-        if (e_client_util_ignored_get(above)) continue;
-        if (e_object_is_del(E_OBJECT(above))) continue;
-        if (above->iconic && above->exp_iconify.by_client) continue;
-        if (above->bg_state) continue;
-        if (above->comp_data && !above->comp_data->mapped) continue;
-
-        e_client_geometry_get(above, &ax, &ay, &aw, &ah);
-        if (!E_CONTAINS(ax, ay, aw, ah, ex, ey, ew, eh)) continue;
-
-        if (!(above->argb) || !(above->visibility.opaque <= 0))
-          {
-             e_client_geometry_get(above, &ax, &ay, &aw, &ah);
-             EINA_RECTANGLE_SET(&r, ax, ay, aw, ah);
-             eina_tiler_rect_del(t, &r);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
 
-             if (eina_tiler_empty(t))
-               {
-                  eina_tiler_free(t);
-                  return EINA_TRUE;
-               }
-          }
-     }
-   eina_tiler_free(t);
+   if (e_client_util_ignored_get(ec)) return EINA_FALSE;
+   if (e_object_is_del(E_OBJECT(ec))) return EINA_FALSE;
+   if (ec->iconic && ec->exp_iconify.by_client) return EINA_FALSE;
+   if (ec->bg_state) return EINA_FALSE;
+   if (ec->comp_data && !ec->comp_data->mapped) return EINA_FALSE;
+   if (!(ec->argb) || !(ec->visibility.opaque <= 0)) return EINA_TRUE;
 
    return EINA_FALSE;
 }
@@ -1766,11 +1736,57 @@ static void
 _e_vis_ec_below_activity_clients_get(E_Client *ec, Eina_List **below_list)
 {
    E_Client *below;
+   E_Client *above;
+   Eina_Tiler *above_tile = NULL;
+   Eina_Tiler *below_tile = NULL;
+   Eina_Tiler *temp_tile = NULL;
+   Eina_Rectangle r;
+   Eina_Rectangle desk_rect;
+   int x, y, w, h;
+
+   EINA_RECTANGLE_SET(&desk_rect, ec->desk->geom.x, ec->desk->geom.y, ec->desk->geom.w, ec->desk->geom.h);
+
+   above_tile = eina_tiler_new(ec->desk->geom.w, ec->desk->geom.h);
+   EINA_SAFETY_ON_NULL_GOTO(above_tile, finish);
+   below_tile = eina_tiler_new(ec->desk->geom.w, ec->desk->geom.h);
+   EINA_SAFETY_ON_NULL_GOTO(below_tile, finish);
+   temp_tile = eina_tiler_new(ec->desk->geom.w, ec->desk->geom.h);
+   EINA_SAFETY_ON_NULL_GOTO(temp_tile, finish);
+
+   eina_tiler_tile_size_set(above_tile, 1, 1);
+   eina_tiler_tile_size_set(below_tile, 1, 1);
+   eina_tiler_tile_size_set(temp_tile, 1, 1);
+
+   for (above = e_client_above_get(ec); above; above = e_client_above_get(above))
+     {
+        if (_e_vis_client_check_obscure_below(above))
+          {
+             e_client_geometry_get(above, &x, &y, &w, &h);
+             EINA_RECTANGLE_SET(&r, x, y, w, h);
+             eina_tiler_rect_add(above_tile, &r);
+          }
+     }
+
+   // if fully obscured by aboves, no need to get below list
+   eina_tiler_rect_add(temp_tile, &desk_rect);
+   eina_tiler_subtract(temp_tile, above_tile);
+   if (eina_tiler_empty(temp_tile))
+     goto finish;
 
    for (below = e_client_below_get(ec); below; below = e_client_below_get(below))
      {
         if (!_e_vis_ec_activity_check(below, EINA_FALSE, EINA_FALSE)) continue;
-        if (_e_vis_client_check_obscured_by_above_regions(below, ec)) continue;
+        e_client_geometry_get(below, &x, &y, &w, &h);
+        EINA_RECTANGLE_SET(&r, x, y, w, h);
+        eina_tiler_rect_add(below_tile, &r);
+
+        // get unobscured region of below ec
+        eina_tiler_clear(temp_tile);
+        eina_tiler_union(temp_tile, above_tile);
+        eina_tiler_union(temp_tile, below_tile);
+        eina_tiler_subtract(temp_tile, above_tile);
+
+        if (eina_tiler_empty(temp_tile)) continue;
 
         E_VIS_CLIENT_GET(vc, below);
         if (!vc) continue;
@@ -1780,11 +1796,27 @@ _e_vis_ec_below_activity_clients_get(E_Client *ec, Eina_List **below_list)
           continue;
 
         *below_list = eina_list_prepend(*below_list, vc);
-        if ((below->argb) && (below->visibility.opaque <= 0))
-          continue;
-        else
-          break;
+        if (!(below->argb) || !(below->visibility.opaque <= 0))
+          {
+             eina_tiler_union(above_tile, below_tile);
+
+             // if fully obscured by aboves, no need to continue
+             eina_tiler_rect_add(temp_tile, &desk_rect);
+             eina_tiler_subtract(temp_tile, above_tile);
+             if (eina_tiler_empty(temp_tile))
+               break;
+          }
      }
+
+finish:
+   if (above_tile)
+     eina_tiler_free(above_tile);
+
+   if (below_tile)
+     eina_tiler_free(below_tile);
+
+   if (temp_tile)
+     eina_tiler_free(temp_tile);
 }
 
 static Eina_Bool