}
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;
}
_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;
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