improvements to e_border positioning.

* e_border_center() will center window in a better way, accounting
   the shelves/panels instead of just centering on the screen. This is
   better and most noticeable if screens are small and a big shelf on
   just one edge.

 * e_border_move_without_border(), e_border_resize_without_border()
   and e_border_move_resize_without_border() will assume the given
   values do not acount border/decorations (client_inset) and will do
   automatically. As stated in documentation, this is specially useful
   when it is a new client and thus have no decorations when it is
   positioned, when decorations are added window would be placed at
   wrong position. One can try this by adding efwin window overflowing
   the bottom-right corner, closing it and when reopen fileman would
   try to make it inside the screen, this would not work well with
   part of the window still being outside.

 * e_win_move(), e_win_resize() and e_win_move_resize() will now use
   new e_border functions.



SVN revision: 40307
This commit is contained in:
Gustavo Sverzut Barbieri 2009-04-23 02:24:59 +00:00
parent 6ca152fef8
commit be6a6ba639
14 changed files with 425 additions and 157 deletions

View File

@ -572,35 +572,37 @@ e_border_res_change_geometry_restore(E_Border *bd)
}
else
{
int x, y, w, h;
int x, y, w, h, zx, zy, zw, zh;
bd->saved.x = bd->pre_res_change.saved.x;
bd->saved.y = bd->pre_res_change.saved.y;
bd->saved.w = bd->pre_res_change.saved.w;
bd->saved.h = bd->pre_res_change.saved.h;
e_zone_useful_geometry_get(bd->zone, &zx, &zy, &zw, &zh);
if (bd->saved.w > zw)
bd->saved.w = zw;
if ((bd->saved.x + bd->saved.w) > (zx + zw))
bd->saved.x = zx + zw - bd->saved.w;
if (bd->saved.w > bd->zone->w)
bd->saved.w = bd->zone->w;
if ((bd->saved.x + bd->saved.w) > (bd->zone->x + bd->zone->w))
bd->saved.x = bd->zone->x + bd->zone->w - bd->saved.w;
if (bd->saved.h > bd->zone->h)
bd->saved.h = bd->zone->h;
if ((bd->saved.y + bd->saved.h) > (bd->zone->y + bd->zone->h))
bd->saved.y = bd->zone->y + bd->zone->h - bd->saved.h;
if (bd->saved.h > zh)
bd->saved.h = zh;
if ((bd->saved.y + bd->saved.h) > (zy + zh))
bd->saved.y = zy + zh - bd->saved.h;
x = bd->pre_res_change.x;
y = bd->pre_res_change.y;
w = bd->pre_res_change.w;
h = bd->pre_res_change.h;
if (w > bd->zone->w)
w = bd->zone->w;
if (h > bd->zone->h)
h = bd->zone->h;
if ((x + w) > (bd->zone->x + bd->zone->w))
x = bd->zone->x + bd->zone->w - w;
if ((y + h) > (bd->zone->y + bd->zone->h))
y = bd->zone->y + bd->zone->h - h;
if (w > zw)
w = zw;
if (h > zh)
h = zh;
if ((x + w) > (zx + zw))
x = zx + zw - w;
if ((y + h) > (zy + zh))
y = zy + zh - h;
e_border_move_resize(bd, x, y, w, h);
}
memcpy(&bd->pre_res_change, &pre_res_change, sizeof(pre_res_change));
@ -799,10 +801,11 @@ e_border_hide(E_Border *bd, int manage)
bd->post_show = 0;
}
EAPI void
e_border_move(E_Border *bd, int x, int y)
static void
_e_border_move_internal(E_Border *bd, int x, int y, Eina_Bool without_border)
{
E_Event_Border_Move *ev;
int bx, by;
E_OBJECT_CHECK(bd);
E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
@ -820,6 +823,7 @@ e_border_move(E_Border *bd, int x, int y)
pnd->move = 1;
pnd->x = x;
pnd->y = y;
pnd->without_border = without_border;
bd->pending_move_resize = eina_list_append(bd->pending_move_resize, pnd);
return;
}
@ -836,13 +840,24 @@ e_border_move(E_Border *bd, int x, int y)
ecore_x_netwm_sync_request_send(bd->client.win, bd->client.netwm.sync.serial++);
}
#endif
if (!without_border)
{
bx = bd->client_inset.l;
by = bd->client_inset.t;
}
else
{
bx = 0;
by = 0;
}
if (bd->internal_ecore_evas)
ecore_evas_managed_move(bd->internal_ecore_evas,
bd->x + bd->fx.x + bd->client_inset.l,
bd->y + bd->fx.y + bd->client_inset.t);
bd->x + bd->fx.x + bx,
bd->y + bd->fx.y + by);
ecore_x_icccm_move_resize_send(bd->client.win,
bd->x + bd->fx.x + bd->client_inset.l,
bd->y + bd->fx.y + bd->client_inset.t,
bd->x + bd->fx.x + bx,
bd->y + bd->fx.y + by,
bd->client.w,
bd->client.h);
_e_border_move_update(bd);
@ -854,6 +869,58 @@ e_border_move(E_Border *bd, int x, int y)
_e_border_zone_update(bd);
}
/**
* Move window to coordinates that already account border decorations.
*
* This call will consider given position already accounts border
* decorations, so it will not be considered later. This will just
* work properly with borders that have being evaluated and border
* decorations are known (border->client_inset).
*
* @parm x horizontal position to place window.
* @parm y vertical position to place window.
*
* @see e_border_move_without_border()
*/
EAPI void
e_border_move(E_Border *bd, int x, int y)
{
_e_border_move_internal(bd, x, y, 0);
}
/**
* Move window to coordinates that do not account border decorations yet.
*
* This call will consider given position does not account border
* decoration, so these values (border->client_inset) will be
* accounted automatically. This is specially useful when it is a new
* client and has not be evaluated yet, in this case
* border->client_inset will be zeroed and no information is known. It
* will mark pending requests so border will be accounted on
* evalutation phase.
*
* @parm x horizontal position to place window.
* @parm y vertical position to place window.
*
* @see e_border_move()
*/
EAPI void
e_border_move_without_border(E_Border *bd, int x, int y)
{
_e_border_move_internal(bd, x, y, 1);
}
EAPI void
e_border_center(E_Border *bd)
{
int x, y, w, h;
E_OBJECT_CHECK(bd);
E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
e_zone_useful_geometry_get(bd->zone, &x, &y, &w, &h);
e_border_move(bd, x + (w - bd->w) / 2, y + (h - bd->h) / 2);
}
EAPI void
e_border_fx_offset(E_Border *bd, int x, int y)
{
@ -877,11 +944,12 @@ e_border_fx_offset(E_Border *bd, int x, int y)
if (bd->moving) _e_border_move_update(bd);
}
EAPI void
e_border_resize(E_Border *bd, int w, int h)
static void
_e_border_resize_internal(E_Border *bd, int w, int h, Eina_Bool without_border)
{
E_Event_Border_Resize *ev;
int bx, by, bw, bh;
E_OBJECT_CHECK(bd);
E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
@ -889,6 +957,22 @@ e_border_resize(E_Border *bd, int w, int h)
(((bd->maximized & E_MAXIMIZE_TYPE) == E_MAXIMIZE_FULLSCREEN) && (!e_config->allow_manip)))
return;
ecore_x_window_shadow_tree_flush();
if (!without_border)
{
bx = bd->client_inset.l;
by = bd->client_inset.t;
bw = (bd->client_inset.l + bd->client_inset.r);
bh = (bd->client_inset.t + bd->client_inset.b);
}
else
{
bx = 0;
by = 0;
bw = 0;
bh = 0;
}
if (bd->new_client)
{
E_Border_Pending_Move_Resize *pnd;
@ -896,8 +980,9 @@ e_border_resize(E_Border *bd, int w, int h)
pnd = E_NEW(E_Border_Pending_Move_Resize, 1);
if (!pnd) return;
pnd->resize = 1;
pnd->w = w - (bd->client_inset.l + bd->client_inset.r);
pnd->h = h - (bd->client_inset.t + bd->client_inset.b);
pnd->without_border = without_border;
pnd->w = w - bw;
pnd->h = h - bh;
bd->pending_move_resize = eina_list_append(bd->pending_move_resize, pnd);
return;
}
@ -905,8 +990,8 @@ e_border_resize(E_Border *bd, int w, int h)
bd->pre_res_change.valid = 0;
bd->w = w;
bd->h = h;
bd->client.w = bd->w - (bd->client_inset.l + bd->client_inset.r);
bd->client.h = bd->h - (bd->client_inset.t + bd->client_inset.b);
bd->client.w = bd->w - bw;
bd->client.h = bd->h - bh;
bd->changed = 1;
bd->changes.size = 1;
if ((bd->shaped) || (bd->client.shaped))
@ -921,11 +1006,11 @@ e_border_resize(E_Border *bd, int w, int h)
}
if (bd->internal_ecore_evas)
ecore_evas_managed_move(bd->internal_ecore_evas,
bd->x + bd->fx.x + bd->client_inset.l,
bd->y + bd->fx.y + bd->client_inset.t);
bd->x + bd->fx.x + bx,
bd->y + bd->fx.y + by);
ecore_x_icccm_move_resize_send(bd->client.win,
bd->x + bd->fx.x + bd->client_inset.l,
bd->y + bd->fx.y + bd->client_inset.t,
bd->x + bd->fx.x + bx,
bd->y + bd->fx.y + by,
bd->client.w,
bd->client.h);
_e_border_resize_update(bd);
@ -937,19 +1022,77 @@ e_border_resize(E_Border *bd, int w, int h)
_e_border_zone_update(bd);
}
/**
* Resize window to values that already account border decorations.
*
* This call will consider given size already accounts border
* decorations, so it will not be considered later. This will just
* work properly with borders that have being evaluated and border
* decorations are known (border->client_inset).
*
* @parm w horizontal window size.
* @parm h vertical window size.
*
* @see e_border_resize_without_border()
*/
EAPI void
e_border_move_resize(E_Border *bd, int x, int y, int w, int h)
e_border_resize(E_Border *bd, int w, int h)
{
_e_border_resize_internal(bd, w, h, 0);
}
/**
* Resize window to values that do not account border decorations yet.
*
* This call will consider given size does not account border
* decoration, so these values (border->client_inset) will be
* accounted automatically. This is specially useful when it is a new
* client and has not be evaluated yet, in this case
* border->client_inset will be zeroed and no information is known. It
* will mark pending requests so border will be accounted on
* evalutation phase.
*
* @parm w horizontal window size.
* @parm h vertical window size.
*
* @see e_border_resize()
*/
EAPI void
e_border_resize_without_border(E_Border *bd, int w, int h)
{
_e_border_resize_internal(bd, w, h, 1);
}
static void
_e_border_move_resize_internal(E_Border *bd, int x, int y, int w, int h, Eina_Bool without_border)
{
E_Event_Border_Move *mev;
E_Event_Border_Resize *rev;
int bx, by, bw, bh;
E_OBJECT_CHECK(bd);
E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
if ((bd->fullscreen) ||
(((bd->maximized & E_MAXIMIZE_TYPE) == E_MAXIMIZE_FULLSCREEN) && (!e_config->allow_manip)))
return;
return;
ecore_x_window_shadow_tree_flush();
if (!without_border)
{
bx = bd->client_inset.l;
by = bd->client_inset.t;
bw = (bd->client_inset.l + bd->client_inset.r);
bh = (bd->client_inset.t + bd->client_inset.b);
}
else
{
bx = 0;
by = 0;
bw = 0;
bh = 0;
}
if (bd->new_client)
{
E_Border_Pending_Move_Resize *pnd;
@ -958,10 +1101,11 @@ e_border_move_resize(E_Border *bd, int x, int y, int w, int h)
if (!pnd) return;
pnd->move = 1;
pnd->resize = 1;
pnd->without_border = without_border;
pnd->x = x;
pnd->y = y;
pnd->w = w - (bd->client_inset.l + bd->client_inset.r);
pnd->h = h - (bd->client_inset.t + bd->client_inset.b);
pnd->w = w - bw;
pnd->h = h - bh;
bd->pending_move_resize = eina_list_append(bd->pending_move_resize, pnd);
return;
}
@ -971,8 +1115,8 @@ e_border_move_resize(E_Border *bd, int x, int y, int w, int h)
bd->y = y;
bd->w = w;
bd->h = h;
bd->client.w = bd->w - (bd->client_inset.l + bd->client_inset.r);
bd->client.h = bd->h - (bd->client_inset.t + bd->client_inset.b);
bd->client.w = bd->w - bw;
bd->client.h = bd->h - bh;
bd->changed = 1;
bd->changes.pos = 1;
bd->changes.size = 1;
@ -988,11 +1132,11 @@ e_border_move_resize(E_Border *bd, int x, int y, int w, int h)
}
if (bd->internal_ecore_evas)
ecore_evas_managed_move(bd->internal_ecore_evas,
bd->x + bd->fx.x + bd->client_inset.l,
bd->y + bd->fx.y + bd->client_inset.t);
bd->x + bd->fx.x + bx,
bd->y + bd->fx.y + by);
ecore_x_icccm_move_resize_send(bd->client.win,
bd->x + bd->fx.x + bd->client_inset.l,
bd->y + bd->fx.y + bd->client_inset.t,
bd->x + bd->fx.x + bx,
bd->y + bd->fx.y + by,
bd->client.w,
bd->client.h);
_e_border_resize_update(bd);
@ -1010,6 +1154,48 @@ e_border_move_resize(E_Border *bd, int x, int y, int w, int h)
_e_border_zone_update(bd);
}
/**
* Move and resize window to values that already account border decorations.
*
* This call will consider given values already accounts border
* decorations, so it will not be considered later. This will just
* work properly with borders that have being evaluated and border
* decorations are known (border->client_inset).
*
* @parm x horizontal position to place window.
* @parm y vertical position to place window.
* @parm w horizontal window size.
* @parm h vertical window size.
*
* @see e_border_move_resize_without_border()
*/
EAPI void
e_border_move_resize(E_Border *bd, int x, int y, int w, int h)
{
_e_border_move_resize_internal(bd, x, y, w, h, 0);
}
/**
* Move and resize window to values that do not account border decorations yet.
*
* This call will consider given values already accounts border
* decorations, so it will not be considered later. This will just
* work properly with borders that have being evaluated and border
* decorations are known (border->client_inset).
*
* @parm x horizontal position to place window.
* @parm y vertical position to place window.
* @parm w horizontal window size.
* @parm h vertical window size.
*
* @see e_border_move_resize()
*/
EAPI void
e_border_move_resize_without_border(E_Border *bd, int x, int y, int w, int h)
{
_e_border_move_resize_internal(bd, x, y, w, h, 1);
}
EAPI void
e_border_layer_set(E_Border *bd, int layer)
{
@ -5489,8 +5675,11 @@ _e_border_eval(E_Border *bd)
int change_urgent = 0;
int rem_change = 0;
int send_event = 1;
int zx, zy, zw, zh;
_e_border_hook_call(E_BORDER_HOOK_EVAL_PRE_FETCH, bd);
if (bd->zone)
e_zone_useful_geometry_get(bd->zone, &zx, &zy, &zw, &zh);
/* fetch any info queued to be fetched */
if (bd->client.icccm.fetch.client_leader)
{
@ -6054,6 +6243,7 @@ _e_border_eval(E_Border *bd)
zone = e_container_zone_number_get(bd->zone->container, rem->prop.zone);
if (zone)
e_border_zone_set(bd, zone);
e_zone_useful_geometry_get(zone, &zx, &zy, &zw, &zh);
}
if (rem->apply & E_REMEMBER_APPLY_DESKTOP)
{
@ -6535,8 +6725,8 @@ _e_border_eval(E_Border *bd)
#endif
else if (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG)
{
bd->x = bd->zone->x + ((bd->zone->w - bd->w) / 2);
bd->y = bd->zone->y + ((bd->zone->h - bd->h) / 2);
bd->x = zx + ((zw - bd->w) / 2);
bd->y = zy + ((zh - bd->h) / 2);
bd->changes.pos = 1;
bd->placed = 1;
}
@ -6545,14 +6735,14 @@ _e_border_eval(E_Border *bd)
Eina_List *skiplist = NULL;
int new_x, new_y;
if (bd->zone->w > bd->w)
new_x = bd->zone->x + (rand() % (bd->zone->w - bd->w));
if (zw > bd->w)
new_x = zx + (rand() % (zw - bd->w));
else
new_x = bd->zone->x;
if (bd->zone->h > bd->h)
new_y = bd->zone->y + (rand() % (bd->zone->h - bd->h));
new_x = zx;
if (zh > bd->h)
new_y = zy + (rand() % (zh - bd->h));
else
new_y = bd->zone->y;
new_y = zy;
if ((e_config->window_placement_policy == E_WINDOW_PLACEMENT_SMART)||(e_config->window_placement_policy == E_WINDOW_PLACEMENT_ANTIGADGET))
{
@ -6589,6 +6779,11 @@ _e_border_eval(E_Border *bd)
bd->y = pnd->y;
bd->changes.pos = 1;
bd->placed = 1;
if (pnd->without_border)
{
bd->x -= bd->client_inset.l;
bd->y -= bd->client_inset.t;
}
}
if ((!bd->lock_client_size) && (pnd->resize))
{
@ -6611,8 +6806,8 @@ _e_border_eval(E_Border *bd)
((bd->remember) &&
(!(bd->remember->apply & E_REMEMBER_APPLY_POS)))))
{
bd->x = bd->zone->x + (bd->zone->w - bd->w) / 2;
bd->y = bd->zone->y + (bd->zone->h - bd->h) / 2;
bd->x = zx + (zw - bd->w) / 2;
bd->y = zy + (zh - bd->h) / 2;
bd->changes.pos = 1;
bd->placed = 1;
}
@ -6668,7 +6863,10 @@ _e_border_eval(E_Border *bd)
bd->x,
bd->y + bd->h - 1);
if ((zone) && (zone != bd->zone))
e_border_zone_set(bd, zone);
{
e_border_zone_set(bd, zone);
e_zone_useful_geometry_get(zone, &zx, &zy, &zw, &zh);
}
}
}

View File

@ -515,6 +515,7 @@ struct _E_Border_Pending_Move_Resize
int x, y, w, h;
unsigned char move : 1;
unsigned char resize : 1;
unsigned char without_border : 1;
};
struct _E_Border_Hook
@ -563,9 +564,13 @@ EAPI void e_border_desk_set(E_Border *bd, E_Desk *desk);
EAPI void e_border_show(E_Border *bd);
EAPI void e_border_hide(E_Border *bd, int manage);
EAPI void e_border_move(E_Border *bd, int x, int y);
EAPI void e_border_move_without_border(E_Border *bd, int x, int y);
EAPI void e_border_center(E_Border *bd);
EAPI void e_border_fx_offset(E_Border *bd, int x, int y);
EAPI void e_border_resize(E_Border *bd, int w, int h);
EAPI void e_border_resize_without_border(E_Border *bd, int w, int h);
EAPI void e_border_move_resize(E_Border *bd, int x, int y, int w, int h);
EAPI void e_border_move_resize_without_border(E_Border *bd, int x, int y, int w, int h);
EAPI void e_border_layer_set(E_Border *bd, int layer);
EAPI void e_border_raise(E_Border *bd);
EAPI void e_border_lower(E_Border *bd);

View File

@ -592,10 +592,7 @@ if (!bd->lock_client_shade)
/*
if (bd->client.e.state.centered)
{
e_border_move(bd,
bd->zone->x + (bd->zone->w - bd->w) / 2,
bd->zone->y + (bd->zone->h - bd->h) / 2);
e_border_center(bd);
}
*/
/* Update stacking */

View File

@ -1327,8 +1327,7 @@ _e_int_menus_lost_clients_item_cb(void *data, E_Menu *m, E_Menu_Item *mi)
E_OBJECT_CHECK(bd);
if (bd->iconic) e_border_uniconify(bd);
if (bd->desk) e_desk_show(bd->desk);
e_border_move(bd, bd->zone->x + ((bd->zone->w - bd->w) / 2),
bd->zone->y + ((bd->zone->h - bd->h) / 2));
e_border_center(bd);
e_border_raise(bd);
if (!bd->lock_focus_out)
e_border_focus_set(bd, 1, 1);

View File

@ -475,6 +475,7 @@ _advanced_apply_data(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata)
else if (!cfdata->escfg->autohide && cfdata->es->hidden)
e_shelf_toggle(cfdata->es, 1);
e_zone_useful_geometry_dirty(cfdata->es->zone);
e_config_save_queue();
cfdata->es->config_dialog = cfd;
return 1; /* Apply was OK */

View File

@ -105,6 +105,7 @@ e_shelf_zone_new(E_Zone *zone, const char *name, const char *style, int popup, i
es->w = 32;
es->h = 32;
es->zone = zone;
e_zone_useful_geometry_dirty(zone);
if (popup)
{
es->popup = e_popup_new(zone, es->x, es->y, es->w, es->h);
@ -477,6 +478,7 @@ e_shelf_orient(E_Shelf *es, E_Gadcon_Orient orient)
snprintf(buf, sizeof(buf), "e,state,orientation,%s", _e_shelf_orient_string_get(es));
edje_object_signal_emit(es->o_base, buf, "e");
edje_object_message_signal_process(es->o_base);
e_zone_useful_geometry_dirty(es->zone);
}
EAPI void
@ -592,6 +594,7 @@ e_shelf_position_calc(E_Shelf *es)
es->hidden = 0;
e_shelf_toggle(es, 0);
}
e_zone_useful_geometry_dirty(es->zone);
}
EAPI void
@ -726,6 +729,7 @@ e_shelf_config_new(E_Zone *zone, E_Config_Shelf *cf_es)
static void
_e_shelf_free(E_Shelf *es)
{
e_zone_useful_geometry_dirty(es->zone);
E_FREE_LIST(es->handlers, ecore_event_handler_del);
e_object_del(E_OBJECT(es->gadcon));
@ -999,6 +1003,7 @@ _e_shelf_gadcon_size_request(void *data, E_Gadcon *gc, Evas_Coord w, Evas_Coord
break;
}
e_shelf_move_resize(es, nx, ny, nw, nh);
e_zone_useful_geometry_dirty(es->zone);
}
static Evas_Object *

View File

@ -1061,7 +1061,7 @@ e_util_win_auto_resize_fill(E_Win *win)
{
int w, h;
e_zone_useful_geometry_calc(zone, NULL, NULL, &w, &h);
e_zone_useful_geometry_get(zone, NULL, NULL, &w, &h);
w = _win_auto_size_calc(w, win->min_w);
h = _win_auto_size_calc(h, win->min_h);

View File

@ -110,43 +110,68 @@ e_win_hide(E_Win *win)
if (win->border) e_border_hide(win->border, 1);
}
/**
* This will move window to position, automatically accounts border decorations.
*
* Don't need to account win->border->client_inset, it's done
* automatically, so it will work fine with new windows that still
* don't have the border.
*
* @parm x horizontal position to place window.
* @parm y vertical position to place window.
*/
EAPI void
e_win_move(E_Win *win, int x, int y)
{
E_OBJECT_CHECK(win);
E_OBJECT_TYPE_CHECK(win, E_WIN_TYPE);
if (win->border)
e_border_move(win->border,
x - win->border->client_inset.l,
y - win->border->client_inset.t);
e_border_move_without_border(win->border, x, y);
else
ecore_evas_move(win->ecore_evas, x, y);
}
/**
* This will resize window, automatically accounts border decorations.
*
* Don't need to account win->border->client_inset, it's done
* automatically, so it will work fine with new windows that still
* don't have the border.
*
* @parm w horizontal window size.
* @parm h vertical window size.
*/
EAPI void
e_win_resize(E_Win *win, int w, int h)
{
E_OBJECT_CHECK(win);
E_OBJECT_TYPE_CHECK(win, E_WIN_TYPE);
if (win->border)
e_border_resize(win->border,
w + win->border->client_inset.l + win->border->client_inset.r,
h + win->border->client_inset.t + win->border->client_inset.b);
e_border_resize_without_border(win->border, w, h);
else
ecore_evas_resize(win->ecore_evas, w, h);
}
/**
* This will move and resize window to position, automatically
* accounts border decorations.
*
* Don't need to account win->border->client_inset, it's done
* automatically, so it will work fine with new windows that still
* don't have the border.
*
* @parm x horizontal position to place window.
* @parm y vertical position to place window.
* @parm w horizontal window size.
* @parm h vertical window size.
*/
EAPI void
e_win_move_resize(E_Win *win, int x, int y, int w, int h)
{
E_OBJECT_CHECK(win);
E_OBJECT_TYPE_CHECK(win, E_WIN_TYPE);
if (win->border)
e_border_move_resize(win->border,
x - win->border->client_inset.l,
y - win->border->client_inset.t,
w + win->border->client_inset.l + win->border->client_inset.r,
h + win->border->client_inset.t + win->border->client_inset.b);
e_border_move_resize_without_border(win->border, x, y, w, h);
else
ecore_evas_move_resize(win->ecore_evas, x, y, w, h);
}
@ -327,16 +352,7 @@ e_win_centered_set(E_Win *win, int centered)
_e_win_state_update(win);
}
if ((win->border) && (centered))
{
int x, y, w, h;
e_zone_useful_geometry_calc(win->border->zone, &x, &y, &w, &h);
/* The window is visible, move it to the right spot */
e_border_move(win->border,
win->border->zone->x + x + (w - win->border->w) / 2,
win->border->zone->y + y + (h - win->border->h) / 2);
}
e_border_center(win->border);
}
EAPI void

View File

@ -77,6 +77,7 @@ e_zone_new(E_Container *con, int num, int id, int x, int y, int w, int h)
zone->h = h;
zone->num = num;
zone->id = id;
e_zone_useful_geometry_dirty(zone);
cw = w * E_ZONE_CORNER_RATIO;
ch = h * E_ZONE_CORNER_RATIO;
@ -826,11 +827,8 @@ e_zone_flip_win_restore(void)
}
}
/**
* Calculate the useful (or free, without any shelves) area.
*/
EAPI void
e_zone_useful_geometry_calc(const E_Zone *zone, int *x, int *y, int *w, int *h)
static void
_e_zone_useful_geometry_calc(E_Zone *zone)
{
const Eina_List *l;
const E_Shelf *shelf;
@ -891,10 +889,48 @@ e_zone_useful_geometry_calc(const E_Zone *zone, int *x, int *y, int *w, int *h)
}
}
if (x) *x = x0;
if (y) *y = y0;
if (w) *w = x1 - x0;
if (h) *h = y1 - y0;
zone->useful_geometry.x = zone->x + x0;
zone->useful_geometry.y = zone->y + y0;
zone->useful_geometry.w = x1 - x0;
zone->useful_geometry.h = y1 - y0;
zone->useful_geometry.dirty = 0;
}
/**
* Get (or calculate) the useful (or free, without any shelves) area.
*/
EAPI void
e_zone_useful_geometry_get(E_Zone *zone, int *x, int *y, int *w, int *h)
{
E_OBJECT_CHECK(zone);
E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
if (zone->useful_geometry.dirty)
_e_zone_useful_geometry_calc(zone);
if (x) *x = zone->useful_geometry.x;
if (y) *y = zone->useful_geometry.y;
if (w) *w = zone->useful_geometry.w;
if (h) *h = zone->useful_geometry.h;
}
/**
* Mark as dirty so e_zone_useful_geometry_get() will need to recalculate.
*
* Call this function when shelves are added or important properties changed.
*/
EAPI void
e_zone_useful_geometry_dirty(E_Zone *zone)
{
E_OBJECT_CHECK(zone);
E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
zone->useful_geometry.dirty = 1;
zone->useful_geometry.x = -1;
zone->useful_geometry.y = -1;
zone->useful_geometry.w = -1;
zone->useful_geometry.h = -1;
}
/* local subsystem functions */

View File

@ -78,6 +78,11 @@ struct _E_Zone
Evas *black_evas;
Ecore_X_Window black_win;
int id;
struct {
int x, y, w, h;
Eina_Bool dirty : 1;
} useful_geometry;
};
struct _E_Event_Zone_Desk_Count_Set
@ -138,7 +143,8 @@ EAPI void e_zone_desk_linear_flip_to(E_Zone *zone, int x);
EAPI void e_zone_flip_win_disable(void);
EAPI void e_zone_flip_win_restore(void);
EAPI void e_zone_useful_geometry_calc(const E_Zone *zone, int *x, int *y, int *w, int *h);
EAPI void e_zone_useful_geometry_dirty(E_Zone *zone);
EAPI void e_zone_useful_geometry_get(E_Zone *zone, int *x, int *y, int *w, int *h);
extern EAPI int E_EVENT_ZONE_DESK_COUNT_SET;
extern EAPI int E_EVENT_ZONE_MOVE_RESIZE;

View File

@ -183,37 +183,39 @@ e_fwin_new(E_Container *con, const char *dev, const char *path)
cf = e_fm2_custom_file_get(buf);
if ((cf) && (cf->geom.valid))
{
int zx, zy, zw, zh;
x = cf->geom.x;
y = cf->geom.y;
w = cf->geom.w;
h = cf->geom.h;
e_zone_useful_geometry_get(fwin->win->border->zone,
&zx, &zy, &zw, &zh);
/* checking width and height */
if (w < 24)
w = 280 * e_scale;
else if (w > fwin->win->border->zone->w)
w = fwin->win->border->zone->w;
else if (w > zw)
w = zw;
if (h < 24)
h = 200 * e_scale;
else if (h > fwin->win->border->zone->h)
h = fwin->win->border->zone->h;
else if (h > zh)
h = zh;
/* checking left-top corner */
if (x < fwin->win->border->zone->x)
x = fwin->win->border->zone->x + fwin->win->border->client_inset.l;
if (y < fwin->win->border->zone->y)
y = fwin->win->border->zone->y + fwin->win->border->client_inset.t;
if (x < zx)
x = zx;
if (y < zy)
y = zy;
/* checking right-bottom corner */
if ((fwin->win->border->zone->x + fwin->win->border->zone->w) < (x + w))
x = fwin->win->border->zone->x + fwin->win->border->zone->w - w - fwin->win->border->client_inset.l;
if ((fwin->win->border->zone->y + fwin->win->border->zone->h) < (y + h))
y = fwin->win->border->zone->y + fwin->win->border->zone->h - h - fwin->win->border->client_inset.t;
if ((zx + zw) < (x + w))
x = zx + zw - w;
if ((zy + zh) < (y + h))
y = zy + zh - h;
e_win_move_resize(fwin->win,
x - fwin->win->border->client_inset.l,
y - fwin->win->border->client_inset.t,
w, h);
e_win_move_resize(fwin->win, x, y, w, h);
}
fwin->geom_save_ready = 1;
@ -1041,8 +1043,8 @@ _e_fwin_geom_save(E_Fwin *fwin)
cf = alloca(sizeof(E_Fm2_Custom_File));
memset(cf, 0, sizeof(E_Fm2_Custom_File));
}
cf->geom.x = fwin->win->x - fwin->win->border->client_inset.l;
cf->geom.y = fwin->win->y - fwin->win->border->client_inset.t;
cf->geom.x = fwin->win->x;
cf->geom.y = fwin->win->y;
cf->geom.w = fwin->win->w;
cf->geom.h = fwin->win->h;
cf->geom.valid = 1;
@ -1611,36 +1613,25 @@ _e_fwin_file_open_dialog(E_Fwin *fwin, Eina_List *files, int always)
/* if it ended up too small - fix to a decent size */
if (nw < 24) nw = 200 * e_scale;
if (nh < 24) nh = 280 * e_scale;
printf("load @ %i %i, %ix%i inset %i %i\n",
nx, ny, nw, nh,
fwin2->win->border->client_inset.l,
fwin2->win->border->client_inset.t);
/* if it ended up out of the zone */
if (nx < fwin2->win->border->zone->x)
nx = fwin2->win->border->zone->x +
fwin2->win->border->client_inset.l;
nx = fwin2->win->border->zone->x;
if (ny < fwin2->win->border->zone->y)
ny = fwin2->win->border->zone->y +
fwin2->win->border->client_inset.t;
ny = fwin2->win->border->zone->y;
if ((fwin2->win->border->zone->x +
fwin2->win->border->zone->w) <
(fwin2->win->border->w + nx))
nx = fwin2->win->border->zone->x +
fwin2->win->border->zone->w -
fwin2->win->border->w -
fwin2->win->border->client_inset.l;
fwin2->win->border->w;
if ((fwin2->win->border->zone->y +
fwin2->win->border->zone->h) <
(fwin2->win->border->h + ny))
ny = fwin2->win->border->zone->y +
fwin2->win->border->zone->h -
fwin2->win->border->h -
fwin2->win->border->client_inset.t;
e_win_move_resize
(fwin2->win,
nx - fwin2->win->border->client_inset.l,
ny - fwin2->win->border->client_inset.t,
nw, nh);
fwin2->win->border->h;
e_win_move_resize(fwin2->win, nx, ny, nw, nh);
}
else
{

View File

@ -33,10 +33,8 @@ _e_module_layout_cb_hook(void *data, E_Border *bd)
else
{
e_border_unmaximize(bd, E_MAXIMIZE_BOTH);
e_border_move(bd,
bd->zone->x + (bd->zone->w / 2),
bd->zone->y + (bd->zone->h / 2));
e_border_resize(bd, 1, 1);
e_border_center(bd);
if (bd->bordername) eina_stringshare_del(bd->bordername);
bd->bordername = eina_stringshare_add("borderless");
bd->client.icccm.base_w = 1;

View File

@ -642,9 +642,9 @@ _pager_window_free(Pager_Win *pw)
static void
_pager_window_move(Pager_Win *pw)
{
e_layout_child_move(pw->o_window,
pw->border->x - pw->desk->desk->zone->x,
pw->border->y - pw->desk->desk->zone->y);
int zx, zy;
e_zone_useful_geometry_get(pw->desk->desk->zone, &zx, &zy, NULL, NULL);
e_layout_child_move(pw->o_window, pw->border->x - zx, pw->border->y - zy);
e_layout_child_resize(pw->o_window, pw->border->w, pw->border->h);
}
@ -684,7 +684,7 @@ static Pager_Popup *
_pager_popup_new(E_Zone *zone, int keyaction)
{
Pager_Popup *pp;
Evas_Coord w, h;
Evas_Coord w, h, zx, zy, zw, zh;
int x, y, height, width;
E_Desk *desk;
@ -734,8 +734,12 @@ _pager_popup_new(E_Zone *zone, int keyaction)
evas_object_resize(pp->o_bg, w, h);
e_popup_edje_bg_object_set(pp->popup, pp->o_bg);
//e_popup_ignore_events_set(pp->popup, 1);
e_popup_move_resize(pp->popup, ((zone->w - w) / 2),
((zone->h - h) / 2), w, h);
e_zone_useful_geometry_get(zone, &zx, &zy, &zw, &zh);
zx -= zone->x;
zy -= zone->y;
e_popup_move_resize(pp->popup,
zx + ((zw - w) / 2), zy + ((zh - h) / 2),
w, h);
e_bindings_mouse_grab(E_BINDING_CONTEXT_POPUP, pp->popup->evas_win);
e_bindings_wheel_grab(E_BINDING_CONTEXT_POPUP, pp->popup->evas_win);
@ -1847,14 +1851,14 @@ _pager_window_cb_mouse_move(void *data, Evas *e, Evas_Object *obj, void *event_i
pd = _pager_desk_at_coord(pw->desk->pager, mx, my);
if ((pd) && (!pw->drag.no_place))
{
int zx, zy;
e_zone_useful_geometry_get(pd->desk->zone, &zx, &zy, NULL, NULL);
e_layout_coord_canvas_to_virtual(pd->o_layout,
mx + pw->drag.dx,
my + pw->drag.dy, &vx, &vy);
if (pd != pw->desk)
e_border_desk_set(pw->border, pd->desk);
e_border_move(pw->border,
vx + pd->desk->zone->x,
vy + pd->desk->zone->y);
e_border_move(pw->border, vx + zx, vy + zy);
}
else
{
@ -1915,6 +1919,8 @@ _pager_window_cb_drag_finished(E_Drag *drag, int dropped)
evas_object_show(pw->o_window);
if (!dropped)
{
int zx, zy, zw, zh;
/* wasn't dropped (on pager). move it to position of mouse on screen */
cont = e_container_current_get(e_manager_current_get());
zone = e_zone_current_get(cont);
@ -1928,22 +1934,24 @@ _pager_window_cb_drag_finished(E_Drag *drag, int dropped)
dx = (pw->border->w / 2);
dy = (pw->border->h / 2);
e_zone_useful_geometry_get(zone, &zx, &zy, &zw, &zh);
/* offset so that center of window is on mouse, but keep within desk bounds */
if (dx < x)
{
x -= dx;
if ((pw->border->w < zone->w) &&
(x + pw->border->w > zone->x + zone->w))
x -= x + pw->border->w - (zone->x + zone->w);
if ((pw->border->w < zw) &&
(x + pw->border->w > zx + zw))
x -= x + pw->border->w - (zx + zw);
}
else x = 0;
if (dy < y)
{
y -= dy;
if ((pw->border->h < zone->h) &&
(y + pw->border->h > zone->y + zone->h))
y -= y + pw->border->h - (zone->y + zone->h);
if ((pw->border->h < zh) &&
(y + pw->border->h > zy + zh))
y -= y + pw->border->h - (zy + zh);
}
else y = 0;
e_border_move(pw->border, x, y);
@ -2128,11 +2136,16 @@ _pager_drop_cb_drop(void *data, const char *type, void *event_info)
e_border_desk_set(bd, pd->desk);
if ((!pw) || ((pw) && (!pw->drag.no_place)))
{
int zx, zy;
e_layout_coord_canvas_to_virtual(pd->o_layout,
ev->x + xx + x + dx,
ev->y + yy + y + dy,
&nx, &ny);
e_border_move(bd, nx + pd->desk->zone->x, ny + pd->desk->zone->y);
e_zone_useful_geometry_get(pd->desk->zone,
&zx, &zy, NULL, NULL);
e_border_move(bd, nx + zx, ny + zy);
}
}
}
@ -2263,6 +2276,7 @@ _pager_desk_cb_mouse_move(void *data, Evas *e, Evas_Object *obj, void *event_inf
for (l = pd->wins; l; l = l->next)
{
int zx, zy;
pw = l->data;
if (!pw || pw->border->iconic
|| pw->border->client.netwm.state.skip_pager)
@ -2273,9 +2287,9 @@ _pager_desk_cb_mouse_move(void *data, Evas *e, Evas_Object *obj, void *event_inf
"e/modules/pager/window");
e_layout_pack(oo, o);
e_layout_child_raise(o);
e_layout_child_move(o,
pw->border->x - pw->desk->desk->zone->x,
pw->border->y - pw->desk->desk->zone->y);
e_zone_useful_geometry_get(pw->desk->desk->zone,
&zx, &zy, NULL, NULL);
e_layout_child_move(o, pw->border->x - zx, pw->border->y - zy);
e_layout_child_resize(o, pw->border->w, pw->border->h);
evas_object_show(o);

View File

@ -47,7 +47,7 @@ e_syscon_show(E_Zone *zone, const char *defact)
{
Evas_Object *o, *o2;
Evas_Coord mw, mh;
int x, y, w, h;
int x, y, w, h, zx, zy, zw, zh;
int iw, ih;
Eina_List *l;
@ -239,7 +239,8 @@ e_syscon_show(E_Zone *zone, const char *defact)
e_flowlayout_fill_set(o_flow_extra, 1);
edje_object_part_swallow(o_bg, "e.swallow.extra", o_flow_extra);
evas_object_resize(o_bg, zone->w, zone->h);
e_zone_useful_geometry_get(zone, &zx, &zy, &zw, &zh);
evas_object_resize(o_bg, zw, zh);
edje_object_calc_force(o_bg);
e_flowlayout_min_size_get(o_flow_main, &mw, &mh);
@ -253,12 +254,13 @@ e_syscon_show(E_Zone *zone, const char *defact)
edje_object_part_swallow(o_bg, "e.swallow.extra", o_flow_extra);
edje_object_size_min_calc(o_bg, &mw, &mh);
w = mw;
if (w > zone->w) w = zone->w;
x = (zone->w - w) / 2;
if (w > zw) w = zw;
x = zx - zone->x + (zw - w) / 2;
h = mh;
if (h > zone->h) h = zone->h;
y = (zone->h - h) / 2;
if (h > zh) h = zh;
y = zy - zone->y + (zh - h) / 2;
e_popup_move_resize(popup, x, y, w, h);
evas_object_move(o_bg, 0, 0);