Add some safety checks.

Reorder some checks inside functions (easier/faster checks first).

When mode changes and we check the 'home' window count, make sure we
actually have some home windows first before trying eina_list_count on
a potentially null list.

When doing focus back/forward, make sure we have a focused border to
begin with.

Dot some i's and cross some T's ;)



SVN revision: 50896
This commit is contained in:
Christopher Michael 2010-08-08 11:37:34 +00:00
parent c91b95cb1d
commit 1f672ba9cf
1 changed files with 90 additions and 35 deletions

View File

@ -41,6 +41,8 @@ static Eina_List *_pol_focus_stack;
static void
_policy_border_set_focus(E_Border *bd)
{
if (!bd) return;
/* if focus is locked out then get out */
if (bd->lock_focus_out) return;
@ -95,6 +97,8 @@ _policy_border_set_focus(E_Border *bd)
static void
_policy_border_move(E_Border *bd, int x, int y)
{
if (!bd) return;
/* NB: Qt uses a weird window type called 'VCLSalFrame' that needs to
* have bd->placed set else it doesn't position correctly...
* this could be a result of E honoring the icccm request position,
@ -113,6 +117,8 @@ _policy_border_move(E_Border *bd, int x, int y)
static void
_policy_border_resize(E_Border *bd, int w, int h)
{
if (!bd) return;
bd->w = w;
bd->h = h;
bd->client.w = (bd->w - (bd->client_inset.l + bd->client_inset.r));
@ -129,6 +135,8 @@ _policy_border_hide_below(E_Border *bd)
// printf("Hide Borders Below: %s %d %d\n",
// bd->client.icccm.name, bd->x, bd->y);
if (!bd) return;
/* determine layering position */
if (bd->layer <= 0) pos = 0;
else if ((bd->layer > 0) && (bd->layer <= 50)) pos = 1;
@ -145,12 +153,12 @@ _policy_border_hide_below(E_Border *bd)
EINA_LIST_FOREACH(bd->zone->container->layers[i].clients, l, b)
{
/* skip if it's not on this zone */
if (b->zone != bd->zone) continue;
/* skip if it's the same border */
if (b == bd) continue;
/* skip if it's not on this zone */
if (b->zone != bd->zone) continue;
/* skip special borders */
if (e_illume_border_is_indicator(b)) continue;
if (e_illume_border_is_softkey(b)) continue;
@ -183,6 +191,8 @@ _policy_border_show_below(E_Border *bd)
// printf("Show Borders Below: %s %d %d\n",
// bd->client.icccm.class, bd->x, bd->y);
if (!bd) return;
if (bd->client.icccm.transient_for)
{
if (prev = e_border_find_by_client_window(bd->client.icccm.transient_for))
@ -207,12 +217,12 @@ _policy_border_show_below(E_Border *bd)
EINA_LIST_REVERSE_FOREACH(bd->zone->container->layers[i].clients, l, b)
{
/* skip if it's not on this zone */
if (b->zone != bd->zone) continue;
/* skip if it's the same border */
if (b == bd) continue;
/* skip if it's not on this zone */
if (b->zone != bd->zone) continue;
/* skip special borders */
if (e_illume_border_is_indicator(b)) continue;
if (e_illume_border_is_softkey(b)) continue;
@ -256,6 +266,8 @@ _policy_zone_layout_update(E_Zone *zone)
Eina_List *l;
E_Border *bd;
if (!zone) return;
EINA_LIST_FOREACH(e_border_client_list(), l, bd)
{
/* skip borders not on this zone */
@ -274,6 +286,8 @@ _policy_zone_layout_update(E_Zone *zone)
static void
_policy_zone_layout_indicator(E_Border *bd, E_Illume_Config_Zone *cz)
{
if ((!bd) || (!cz)) return;
/* grab minimum indicator size */
e_illume_border_min_get(bd, NULL, &cz->indicator.size);
@ -343,6 +357,8 @@ _policy_zone_layout_quickpanel(E_Border *bd)
{
int mh;
if (!bd) return;
/* grab minimum size */
e_illume_border_min_get(bd, NULL, &mh);
@ -362,6 +378,8 @@ _policy_zone_layout_softkey(E_Border *bd, E_Illume_Config_Zone *cz)
// printf("\tLayout Softkey\n");
if (!bd) return;
/* grab minimum softkey size */
e_illume_border_min_get(bd, NULL, &cz->softkey.size);
@ -397,6 +415,8 @@ _policy_zone_layout_keyboard(E_Border *bd, E_Illume_Config_Zone *cz)
// printf("\tLayout Keyboard\n");
if ((!bd) || (!cz)) return;
/* grab minimum keyboard size */
e_illume_border_min_get(bd, NULL, &cz->vkbd.size);
@ -427,6 +447,8 @@ _policy_zone_layout_home_single(E_Border *bd, E_Illume_Config_Zone *cz)
{
int ny, nh;
if ((!bd) || (!cz)) return;
/* no point in adjusting size or position if it's not visible */
if (!bd->visible) return;
@ -452,6 +474,8 @@ _policy_zone_layout_home_dual_top(E_Border *bd, E_Illume_Config_Zone *cz)
E_Border *home;
int ny, nh;
if ((!bd) || (!cz)) return;
/* no point in adjusting size or position if it's not visible */
if (!bd->visible) return;
@ -486,6 +510,8 @@ _policy_zone_layout_home_dual_custom(E_Border *bd, E_Illume_Config_Zone *cz)
// printf("\tLayout Home Dual Custom: %s\n", bd->client.icccm.class);
if ((!bd) || (!cz)) return;
/* no point in adjusting size or position if it's not visible */
if (!bd->visible) return;
@ -527,6 +553,8 @@ _policy_zone_layout_home_dual_left(E_Border *bd, E_Illume_Config_Zone *cz)
// printf("\tLayout Home Dual Left: %s\n", bd->client.icccm.class);
if ((!bd) || (!cz)) return;
/* no point in adjusting size or position if it's not visible */
if (!bd->visible) return;
@ -562,6 +590,8 @@ _policy_zone_layout_fullscreen(E_Border *bd)
// printf("\tLayout Fullscreen: %s\n", bd->client.icccm.name);
if (!bd) return;
/* grab keyboard safe region */
e_illume_keyboard_safe_app_region_get(bd->zone, NULL, NULL, NULL, &kh);
@ -580,6 +610,7 @@ _policy_zone_layout_app_single(E_Border *bd, E_Illume_Config_Zone *cz)
E_Border *home;
int ky, kh, ny, nh;
if ((!bd) || (!cz)) return;
if ((!bd->new_client) && (!bd->visible)) return;
// printf("\tLayout App Single: %s\n", bd->client.icccm.name);
@ -614,6 +645,7 @@ _policy_zone_layout_app_dual_top(E_Border *bd, E_Illume_Config_Zone *cz)
// printf("\tLayout App Dual Top: %s\n", bd->client.icccm.name);
if ((!bd) || (!cz)) return;
if ((!bd->new_client) && (!bd->visible)) return;
/* set a default Y position */
@ -680,6 +712,7 @@ _policy_zone_layout_app_dual_custom(E_Border *bd, E_Illume_Config_Zone *cz)
// printf("\tLayout App Dual Custom: %s\n", bd->client.icccm.class);
if ((!bd) || (!cz)) return;
if ((!bd->new_client) && (!bd->visible)) return;
/* grab indicator position */
@ -719,6 +752,7 @@ _policy_zone_layout_app_dual_left(E_Border *bd, E_Illume_Config_Zone *cz)
// printf("\tLayout App Dual Left: %s\n", bd->client.icccm.name);
if ((!bd) || (!cz)) return;
if ((!bd->new_client) && (!bd->visible)) return;
/* grab keyboard safe region */
@ -763,6 +797,8 @@ _policy_zone_layout_dialog(E_Border *bd, E_Illume_Config_Zone *cz)
/* NB: This policy ignores any ICCCM requested positions and centers the
* dialog on it's parent (if it exists) or on the zone */
if ((!bd) || (!cz)) return;
/* no point in adjusting size or position if it's not visible */
if (!bd->visible) return;
@ -826,6 +862,8 @@ _policy_zone_layout_splash(E_Border *bd, E_Illume_Config_Zone *cz)
/* NB: This policy ignores any ICCCM requested positions and centers the
* splash screen on it's parent (if it exists) or on the zone */
if ((!bd) || (!cz)) return;
/* no point in adjusting size or position if it's not visible */
if (!bd->visible) return;
@ -875,6 +913,7 @@ _policy_zone_layout_splash(E_Border *bd, E_Illume_Config_Zone *cz)
static void
_policy_zone_layout_conformant_single(E_Border *bd, E_Illume_Config_Zone *cz)
{
if ((!bd) || (!cz)) return;
if ((!bd->new_client) && (!bd->visible)) return;
/* make sure it's the required width & height */
@ -897,7 +936,7 @@ _policy_zone_layout_conformant_dual_top(E_Border *bd, E_Illume_Config_Zone *cz)
/* according to the docs I have, conformant windows are always on the
* bottom in dual-top mode */
if ((!bd) || (!cz)) return;
if ((!bd->new_client) && (!bd->visible)) return;
/* set some defaults */
@ -925,6 +964,7 @@ _policy_zone_layout_conformant_dual_custom(E_Border *bd, E_Illume_Config_Zone *c
// printf("\tLayout Conformant Dual Custom: %s\n", bd->client.icccm.class);
if ((!bd) || (!cz)) return;
if ((!bd->new_client) && (!bd->visible)) return;
/* grab indicator position */
@ -953,7 +993,7 @@ _policy_zone_layout_conformant_dual_left(E_Border *bd, E_Illume_Config_Zone *cz)
/* according to the docs I have, conformant windows are always on the
* left in dual-left mode */
if ((!bd) || (!cz)) return;
if ((!bd->new_client) && (!bd->visible)) return;
/* set some defaults */
@ -980,6 +1020,8 @@ _policy_border_add(E_Border *bd)
{
// printf("Border added: %s\n", bd->client.icccm.class);
if (!bd) return;
/* NB: this call sets an atom on the window that specifices the zone.
* the logic here is that any new windows created can access the zone
* window by a 'get' call. This is useful for elementary apps as they
@ -1029,6 +1071,8 @@ _policy_border_del(E_Border *bd)
{
// printf("Border deleted: %s\n", bd->client.icccm.class);
if (!bd) return;
/* if this is a fullscreen window, than we need to show indicator window */
/* NB: we could use the e_illume_border_is_fullscreen function here
* but we save ourselves a function call this way */
@ -1084,6 +1128,8 @@ _policy_border_focus_out(E_Border *bd)
{
// printf("Border focus out: %s\n", bd->client.icccm.name);
if (!bd) return;
/* NB: if we got this focus_out event on a deleted border, we check if
* it is a transient (child) of another window. If it is, then we
* transfer focus back to the parent window */
@ -1106,6 +1152,8 @@ _policy_border_activate(E_Border *bd)
// printf("Border Activate: %s\n", bd->client.icccm.name);
if (!bd) return;
/* NB: stolen borders may or may not need focus call...have to test */
if (bd->stolen) return;
@ -1165,14 +1213,15 @@ _policy_border_post_fetch(E_Border *bd)
{
// printf("Border post fetch\n");
if (!bd) return;
/* NB: for this policy we disable all remembers set on a border */
if (bd->remember) e_remember_del(bd->remember);
bd->remember = NULL;
/* set this border to borderless */
#ifdef DIALOG_USES_PIXEL_BORDER
if ((e_illume_border_is_dialog(bd)) &&
(e_illume_border_parent_get(bd)))
if ((e_illume_border_is_dialog(bd)) && (e_illume_border_parent_get(bd)))
eina_stringshare_replace(&bd->bordername, "pixel");
else
bd->borderless = 1;
@ -1189,6 +1238,8 @@ _policy_border_post_assign(E_Border *bd)
{
// printf("Border post assign\n");
if (!bd) return;
bd->internal_no_remember = 1;
/* do not allow client to change these properties */
@ -1214,6 +1265,8 @@ _policy_border_post_assign(E_Border *bd)
void
_policy_border_show(E_Border *bd)
{
if (!bd) return;
/* make sure we have a name so that we don't handle windows like E's root */
if (!bd->client.icccm.name) return;
@ -1237,18 +1290,20 @@ _policy_zone_layout(E_Zone *zone)
// printf("Zone Layout: %d\n", zone->id);
if (!zone) return;
/* get the config for this zone */
cz = e_illume_zone_config_get(zone->id);
/* loop through border list and update layout */
EINA_LIST_FOREACH(e_border_client_list(), l, bd)
{
/* skip borders not on this zone */
if (bd->zone != zone) continue;
/* skip borders that are being deleted */
if (e_object_is_del(E_OBJECT(bd))) continue;
/* skip borders not on this zone */
if (bd->zone != zone) continue;
/* only update layout for this border if it really needs it */
if ((!bd->new_client) && (!bd->changes.pos) && (!bd->changes.size) &&
(!bd->changes.visible) && (!bd->pending_move_resize) &&
@ -1368,6 +1423,8 @@ _policy_zone_move_resize(E_Zone *zone)
// printf("Zone move resize\n");
if (!zone) return;
EINA_LIST_FOREACH(e_border_client_list(), l, bd)
{
/* skip borders not on this zone */
@ -1383,11 +1440,14 @@ void
_policy_zone_mode_change(E_Zone *zone, Ecore_X_Atom mode)
{
E_Illume_Config_Zone *cz;
Eina_List *homes = NULL;
E_Border *bd;
int count;
// printf("Zone mode change: %d\n", zone->id);
if (!zone) return;
/* get the config for this zone */
cz = e_illume_zone_config_get(zone->id);
@ -1423,7 +1483,9 @@ _policy_zone_mode_change(E_Zone *zone, Ecore_X_Atom mode)
}
}
count = eina_list_count(e_illume_border_home_borders_get(zone));
if (!(homes = e_illume_border_home_borders_get(zone))) return;
count = eina_list_count(homes);
/* create a new home window (if needed) for dual mode */
if (cz->mode.dual == 1)
@ -1455,6 +1517,8 @@ _policy_zone_close(E_Zone *zone)
// printf("Zone close\n");
if (!zone) return;
/* make sure we have a focused border */
if (!(bd = e_border_focused_get())) return;
@ -1470,6 +1534,8 @@ _policy_drag_start(E_Border *bd)
{
// printf("Drag start\n");
if (!bd) return;
/* ignore stolen borders */
if (bd->stolen) return;
@ -1485,6 +1551,8 @@ _policy_drag_end(E_Border *bd)
{
// printf("Drag end\n");
if (!bd) return;
/* ignore stolen borders */
if (bd->stolen) return;
@ -1501,6 +1569,7 @@ _policy_focus_back(E_Zone *zone)
Eina_List *l, *fl = NULL;
E_Border *bd, *fbd;
if (!zone) return;
if (eina_list_count(_pol_focus_stack) < 1) return;
// printf("Focus back\n");
@ -1511,11 +1580,8 @@ _policy_focus_back(E_Zone *zone)
fl = eina_list_append(fl, bd);
}
fbd = e_border_focused_get();
if (fbd)
{
if (fbd->parent) return;
}
if (!(fbd = e_border_focused_get())) return;
if (fbd->parent) return;
EINA_LIST_REVERSE_FOREACH(fl, l, bd)
{
@ -1548,6 +1614,7 @@ _policy_focus_forward(E_Zone *zone)
Eina_List *l, *fl = NULL;
E_Border *bd, *fbd;
if (!zone) return;
if (eina_list_count(_pol_focus_stack) < 1) return;
// printf("Focus forward\n");
@ -1558,11 +1625,8 @@ _policy_focus_forward(E_Zone *zone)
fl = eina_list_append(fl, bd);
}
fbd = e_border_focused_get();
if (fbd)
{
if (fbd->parent) return;
}
if (!(fbd = e_border_focused_get())) return;
if (fbd->parent) return;
EINA_LIST_FOREACH(fl, l, bd)
{
@ -1595,6 +1659,8 @@ _policy_focus_home(E_Zone *zone)
E_Border *bd;
// printf("Focus home\n");
if (!zone) return;
if (!(bd = e_illume_border_home_get(zone))) return;
_policy_border_set_focus(bd);
}
@ -1656,9 +1722,6 @@ _policy_property_change(Ecore_X_Event_Window_Property *event)
w = bd->w;
h = bd->h;
/* NB: Remove X Round-Trip */
// ecore_x_e_illume_indicator_geometry_get(zone->black_win, &x, &y, &w, &h);
/* look for conformant borders */
EINA_LIST_FOREACH(e_border_client_list(), l, bd)
{
@ -1687,10 +1750,6 @@ _policy_property_change(Ecore_X_Event_Window_Property *event)
w = bd->w;
h = bd->h;
/* get the geometry. This is X round-trip :( */
/* NB: Remove X Round-Trip */
// ecore_x_e_illume_softkey_geometry_get(zone->black_win, &x, &y, &w, &h);
/* look for conformant borders */
EINA_LIST_FOREACH(e_border_client_list(), l, bd)
{
@ -1727,10 +1786,6 @@ _policy_property_change(Ecore_X_Event_Window_Property *event)
y = 0;
if (kbd->border->fx.y <= 0) y = kbd->border->y;
/* get the geometry. This is X round-trip :( */
/* NB: Remove X Round-Trip */
// ecore_x_e_illume_keyboard_geometry_get(zone->black_win, &x, &y, &w, &h);
/* look for conformant borders */
EINA_LIST_FOREACH(e_border_client_list(), l, bd)
{