improvements to e_border positioning.
authorGustavo Sverzut Barbieri <barbieri@gmail.com>
Thu, 23 Apr 2009 02:24:59 +0000 (02:24 +0000)
committerGustavo Sverzut Barbieri <barbieri@gmail.com>
Thu, 23 Apr 2009 02:24:59 +0000 (02:24 +0000)
 * 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

14 files changed:
src/bin/e_border.c
src/bin/e_border.h
src/bin/e_hints.c
src/bin/e_int_menus.c
src/bin/e_int_shelf_config.c
src/bin/e_shelf.c
src/bin/e_utils.c
src/bin/e_win.c
src/bin/e_zone.c
src/bin/e_zone.h
src/modules/fileman/e_fwin.c
src/modules/layout/e_mod_main.c
src/modules/pager/e_mod_main.c
src/modules/syscon/e_syscon.c

index 108a3f9..5b66028 100644 (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);
+              }
          }
      }
    
index 6d899a2..1de9fa0 100644 (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);
index 4d5eefb..e9148c0 100644 (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 */
index 16a2d3b..5e3769b 100644 (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);
index 031c487..f792d02 100644 (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 */
index ebdad1c..3c29ac4 100644 (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 *
index e5e83ea..f99280b 100644 (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);
index abb9612..685d96f 100644 (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
index c939920..094796c 100644 (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 */
index 1681855..90f66c0 100644 (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;
index 8495b2f..2e768f1 100644 (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;
-
-       e_win_move_resize(fwin->win,
-                         x - fwin->win->border->client_inset.l,
-                         y - fwin->win->border->client_inset.t,
-                         w, h);
+       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, 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
                              {
index 94c621a..619a414 100644 (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;
index 4925aef..a10a41a 100644 (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);
 
index d82da53..fcc9fde 100644 (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);