actions: Add 'Grow in Direction...' action

Summary:
Add an action to grow a window until it touches the nearest edge in
the direction specified. Edges are the outer edges of other windows,
or the desktop boundaries.
@feature

Reviewers: devilhorns, raster

Subscribers: cedric, zmike

Tags: #enlightenment-git

Differential Revision: https://phab.enlightenment.org/D12260
This commit is contained in:
José Romildo Malaquias 2021-05-03 14:04:11 +01:00 committed by Carsten Haitzler (Rasterman)
parent 8e00e808db
commit 835221e29a
1 changed files with 164 additions and 0 deletions

View File

@ -1114,6 +1114,164 @@ ACT_FN_GO(window_push, )
}
}
/***************************************************************************/
ACT_FN_GO(window_grow, )
{
if ((!obj) || (obj->type != E_CLIENT_TYPE))
obj = E_OBJECT(e_client_focused_get());
if (!obj) return;
if (params)
{
E_Client *ec = (E_Client *)obj, *cur;
E_Desk *desk_current;
int hdir = 0, vdir = 0;
int x1, y1, x2, y2, zx, zy, zw, zh;
int w, h, nw, nh, try_h = 2, try_v = 2, offset_x = 0, offset_y = 0;
if (!strcmp(params, "left"))
hdir = -1;
else if (!strcmp(params, "right"))
hdir = 1;
else if (!strcmp(params, "up"))
vdir = -1;
else if (!strcmp(params, "down"))
vdir = 1;
else if (!strcmp(params, "up-left"))
{
hdir = -1;
vdir = -1;
}
else if (!strcmp(params, "up-right"))
{
hdir = 1;
vdir = -1;
}
else if (!strcmp(params, "down-left"))
{
hdir = -1;
vdir = 1;
}
else if (!strcmp(params, "down-right"))
{
hdir = 1;
vdir = 1;
}
else
return;
e_zone_useful_geometry_get(ec->zone, &zx, &zy, &zw, &zh);
x1 = ec->x;
y1 = ec->y;
x2 = ec->x + ec->w;
y2 = ec->y + ec->h;
desk_current = e_desk_current_get(ec->zone);
while ((try_h + try_v) > 0)
{
if (hdir < 0)
x1 = zx;
else if (hdir > 0)
x2 = zx + zw;
if (vdir < 0)
y1 = zy;
else if (vdir > 0)
y2 = zy + zh;
E_CLIENT_FOREACH(cur)
{
if (((cur->desk == desk_current) || (cur->sticky)) && (ec != cur) && (!cur->iconic))
{
if ((hdir < 0)
&& ((cur->x + cur->w) < (ec->x + offset_x))
&& (E_SPANS_COMMON(ec->y, ec->h, cur->y, cur->h)))
x1 = MAX(x1, cur->x + cur->w);
else if ((hdir > 0)
&& (cur->x > (ec->x + ec->w + offset_x))
&& (E_SPANS_COMMON(ec->y, ec->h, cur->y, cur->h)))
x2 = MIN(x2, cur->x);
if ((vdir < 0)
&& ((cur->y + cur->h) < (ec->y + offset_y))
&& (E_SPANS_COMMON(ec->x, ec->w, cur->x, cur->w)))
y1 = MAX(y1, cur->y + cur->h);
else if ((vdir > 0)
&& (cur->y > (ec->y + ec->h + offset_y))
&& (E_SPANS_COMMON(ec->x, ec->w, cur->x, cur->w)))
y2 = MIN(y2, cur->y);
if (x1 < zx) x1 = zx;
else if (x2 > (zx + zw)) x2 = zx + zw;
if (y1 < zy) y1 = zy;
else if (y2 > (zy + zh)) y2 = zy + zh;
}
}
w = nw = x2 - x1;
h = nh = y2 - y1;
e_client_resize_limit(ec, &w, &h);
if (hdir < 0)
x1 += (nw - w);
if (vdir < 0)
y1 += (nh - h);
// grow right but can't & not at screen edge & steps are limited
if ((hdir > 0) && (ec->w == w) && (x2 != (zx + zw))
&& (ec->icccm.step_w > 1))
{
nw = ec->w;
w = ec->w + ec->icccm.step_w;
e_client_resize_limit(ec, &w, &h);
offset_x = w - nw;
try_h--;
}
// grow left but can't & not at screen edge & steps are limited
else if ((hdir < 0) && (ec->w == w) && (x1 != zx)
&& (ec->icccm.step_w > 1))
{
nw = ec->w;
w = ec->w + ec->icccm.step_w;
e_client_resize_limit(ec, &w, &h);
offset_x = -(w - nw);
try_h--;
}
else try_h = 0;
// grow right but can't & not at screen edge & steps are limited
if ((vdir > 0) && (ec->h == h) && (y2 != (zy + zh))
&& (ec->icccm.step_h > 1))
{
nh = ec->h;
h = ec->w + ec->icccm.step_h;
e_client_resize_limit(ec, &w, &h);
offset_y = h - nh;
try_v--;
}
// grow left but can't & not at screen edge & steps are limited
else if ((vdir < 0) && (ec->h == h) && (y1 != zy)
&& (ec->icccm.step_h > 1))
{
nh = ec->h;
h = ec->h + ec->icccm.step_h;
e_client_resize_limit(ec, &w, &h);
offset_y = -(h - nh);
try_v--;
}
else try_v = 0;
}
if ((x1 != ec->x) || (y1 != ec->y) ||
(w != ec->w) || (h != ec->h))
{
evas_object_move(ec->frame, x1, y1);
evas_object_resize(ec->frame, w, h);
if (!e_client_focus_policy_click(ec))
e_client_pointer_warp_to_center_now(ec);
}
}
}
/*
* These actions jump to a window with the given name. It uses the last focused
* window it finds (going through e_client_focus_stack_get), so the name should
@ -3726,6 +3884,12 @@ e_actions_init(void)
"window_push", NULL,
"syntax: direction, example: up, down, left, right, up-left, up-right, down-left, down-right", 1);
/* window_grow */
ACT_GO(window_grow);
e_action_predef_name_set(N_("Window : Actions"), N_("Grow in Direction..."),
"window_grow", NULL,
"syntax: direction, example: up, down, left, right, up-left, up-right, down-left, down-right", 1);
/* window_drag_icon */
ACT_GO(window_drag_icon);
e_action_predef_name_set(N_("Window : Actions"), N_("Drag Icon..."),