raster pushed a commit to branch master.

http://git.enlightenment.org/core/enlightenment.git/commit/?id=835221e29a58088b66a153007381b958eb924056

commit 835221e29a58088b66a153007381b958eb924056
Author: Jos Romildo Malaquias <malaqu...@gmail.com>
Date:   Mon May 3 14:04:11 2021 +0100

    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
---
 src/bin/e_actions.c | 164 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 164 insertions(+)

diff --git a/src/bin/e_actions.c b/src/bin/e_actions.c
index 002396901..3bdc26d47 100644
--- a/src/bin/e_actions.c
+++ b/src/bin/e_actions.c
@@ -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..."),

-- 


Reply via email to