add flag for zone obstacles to indicate verticality

I added a lower quality and less precise workaround for this before
since I didn't have enough test cases to think of something which would
be suffiently good to handle all cases.

as a result, initial calculations for obstacles would incorrectly detect
horizontally-oriented obstacles as being vertical, causing inconsistencies
in window placement. this would become even more severe if the obstacle
never resized itself, erroneously modifying window placement to position
around obstacles which did not exist

having a hint on the obstacle to indicate a direction is sufficient for
most cases, specifically zone useful geometry calcs, where obstacles are
expanded to cover the entire screen on which they reside and must expand
accurately based on the orientation of the obstacle

ref 10c43efc83
This commit is contained in:
Mike Blumenkrantz 2016-02-08 14:05:35 -05:00
parent 7d3319e6ee
commit e8b8fe8310
3 changed files with 51 additions and 13 deletions

View File

@ -84,6 +84,39 @@ E_API int E_EVENT_SHELF_ADD = -1;
E_API int E_EVENT_SHELF_DEL = -1;
static Eina_List *handlers;
static inline Eina_Bool
_e_shelf_is_horizontal(const E_Shelf *es)
{
Eina_Bool horiz = EINA_FALSE;
switch (es->gadcon->orient)
{
case E_GADCON_ORIENT_FLOAT:
case E_GADCON_ORIENT_HORIZ:
case E_GADCON_ORIENT_TOP:
case E_GADCON_ORIENT_BOTTOM:
case E_GADCON_ORIENT_CORNER_TL:
case E_GADCON_ORIENT_CORNER_TR:
case E_GADCON_ORIENT_CORNER_BL:
case E_GADCON_ORIENT_CORNER_BR:
horiz = 1;
break;
case E_GADCON_ORIENT_VERT:
case E_GADCON_ORIENT_LEFT:
case E_GADCON_ORIENT_RIGHT:
case E_GADCON_ORIENT_CORNER_LT:
case E_GADCON_ORIENT_CORNER_RT:
case E_GADCON_ORIENT_CORNER_LB:
case E_GADCON_ORIENT_CORNER_RB:
horiz = 0;
break;
default:
break;
}
return horiz;
}
static void
_e_shelf_remaximize(E_Shelf *es)
{
@ -109,7 +142,7 @@ _e_shelf_obstacles_update(E_Shelf *es)
E_Zone_Obstacle *obs;
EINA_LIST_FOREACH(es->zone_obstacles, l, obs)
e_zone_obstacle_modify(obs, &(Eina_Rectangle){es->x, es->y, es->w, es->h});
e_zone_obstacle_modify(obs, &(Eina_Rectangle){es->x, es->y, es->w, es->h}, !_e_shelf_is_horizontal(es));
}
static Eina_Bool
@ -996,12 +1029,14 @@ e_shelf_obstacles_update(E_Shelf *es)
desk = e_desk_at_xy_get(es->zone, sd->x, sd->y);
if (!desk) continue;
es->zone_obstacles = eina_list_append(es->zone_obstacles,
e_zone_obstacle_add(es->zone, desk, &(Eina_Rectangle){es->x, es->y, es->w, es->h}));
e_zone_obstacle_add(es->zone, desk, &(Eina_Rectangle){es->x, es->y, es->w, es->h},
!_e_shelf_is_horizontal(es)));
}
}
else
es->zone_obstacles = eina_list_append(es->zone_obstacles,
e_zone_obstacle_add(es->zone, NULL, &(Eina_Rectangle){es->x, es->y, es->w, es->h}));
e_zone_obstacle_add(es->zone, NULL, &(Eina_Rectangle){es->x, es->y, es->w, es->h},
!_e_shelf_is_horizontal(es)));
}
E_API E_Shelf *

View File

@ -1239,10 +1239,10 @@ _e_zone_useful_geometry_calc(const E_Zone *zone, int dx, int dy, int *x, int *y,
EINA_INLIST_FOREACH(zone->obstacles, obs)
{
if (!E_INTERSECTS(obs->x, obs->y, obs->w, obs->h, zx, zy, zw, zh)) continue;
if (obs->w >= obs->h)
eina_tiler_rect_del(tiler, &(Eina_Rectangle){0, obs->y - zy, zw, obs->h});
else
if (obs->vertical)
eina_tiler_rect_del(tiler, &(Eina_Rectangle){obs->x - zx, 0, obs->w, zh});
else
eina_tiler_rect_del(tiler, &(Eina_Rectangle){0, obs->y - zy, zw, obs->h});
}
desk = e_desk_at_xy_get(zone, dx, dy);
if (desk)
@ -1250,10 +1250,10 @@ _e_zone_useful_geometry_calc(const E_Zone *zone, int dx, int dy, int *x, int *y,
EINA_INLIST_FOREACH(desk->obstacles, obs)
{
if (!E_INTERSECTS(obs->x, obs->y, obs->w, obs->h, zx, zy, zw, zh)) continue;
if (obs->w >= obs->h)
eina_tiler_rect_del(tiler, &(Eina_Rectangle){0, obs->y - zy, zw, obs->h});
else
if (obs->vertical)
eina_tiler_rect_del(tiler, &(Eina_Rectangle){obs->x - zx, 0, obs->w, zh});
else
eina_tiler_rect_del(tiler, &(Eina_Rectangle){0, obs->y - zy, zw, obs->h});
}
}
it = eina_tiler_iterator_new(tiler);
@ -1340,7 +1340,7 @@ e_zone_useful_geometry_dirty(E_Zone *zone)
}
E_API E_Zone_Obstacle *
e_zone_obstacle_add(E_Zone *zone, E_Desk *desk, Eina_Rectangle *geom)
e_zone_obstacle_add(E_Zone *zone, E_Desk *desk, Eina_Rectangle *geom, Eina_Bool vertical)
{
E_Zone_Obstacle *obs;
@ -1360,6 +1360,7 @@ e_zone_obstacle_add(E_Zone *zone, E_Desk *desk, Eina_Rectangle *geom)
obs->x = geom->x, obs->y = geom->y;
obs->w = geom->w, obs->h = geom->h;
obs->owner = E_OBJECT(desk) ?: E_OBJECT(zone);
obs->vertical = !!vertical;
if (desk)
{
desk->obstacles = eina_inlist_append(desk->obstacles, EINA_INLIST_GET(obs));
@ -1375,7 +1376,7 @@ e_zone_obstacle_add(E_Zone *zone, E_Desk *desk, Eina_Rectangle *geom)
}
E_API void
e_zone_obstacle_modify(E_Zone_Obstacle *obs, Eina_Rectangle *geom)
e_zone_obstacle_modify(E_Zone_Obstacle *obs, Eina_Rectangle *geom, Eina_Bool vertical)
{
E_Zone *zone;
E_Desk *desk;
@ -1387,6 +1388,7 @@ e_zone_obstacle_modify(E_Zone_Obstacle *obs, Eina_Rectangle *geom)
return;
obs->x = geom->x, obs->y = geom->y;
obs->w = geom->w, obs->h = geom->h;
obs->vertical = !!vertical;
if (obs->owner->type == E_DESK_TYPE)
{

View File

@ -129,6 +129,7 @@ struct _E_Zone_Obstacle
EINA_INLIST;
int x, y, w, h;
E_Object *owner;
Eina_Bool vertical : 1;
};
EINTERN int e_zone_init(void);
@ -164,8 +165,8 @@ E_API void e_zone_unstow(E_Zone *zone);
E_API void e_zone_fade_handle(E_Zone *zone, int out, double tim);
E_API E_Zone_Obstacle *e_zone_obstacle_add(E_Zone *zone, E_Desk *desk, Eina_Rectangle *geom);
E_API void e_zone_obstacle_modify(E_Zone_Obstacle *obs, Eina_Rectangle *geom);
E_API E_Zone_Obstacle *e_zone_obstacle_add(E_Zone *zone, E_Desk *desk, Eina_Rectangle *geom, Eina_Bool vertical);
E_API void e_zone_obstacle_modify(E_Zone_Obstacle *obs, Eina_Rectangle *geom, Eina_Bool vertical);
extern E_API int E_EVENT_ZONE_DESK_COUNT_SET;
extern E_API int E_EVENT_ZONE_MOVE_RESIZE;