This is an automated email from the git hooks/post-receive script.

git pushed a commit to branch master
in repository enlightenment.

View the commit online.

commit 19d7bc0d1e19b0f004695d8de47d89fb572dfebe
Author: Alastair Poole <[email protected]>
AuthorDate: Sat Apr 18 16:12:55 2026 +0100

    gadgetsL Fix gadget crash, shelf->desktop drop jump,unintended resize
    
    Preserve gadget geometry when dragging from a shelf/layout gadcon to
    desktop (gadman) so release position and size match the drag preview.
    
    Changes:
    - e_gadcon: stop re-centering desktop drops under pointer
      - Use preserved drag offset (`drag.x`/`drag.y`) for desktop enter/move/drop.
      - Save drop position from current preview object geometry instead of
        recomputing from raw drop event coordinates on mouse-up.
    - e_gadcon: remove shelf->desktop forced minimum scale-up during DnD
      preview, which caused gadgets to grow after drop.
    - gadman: initialize `dx`/`dy` on DnD enter from current pointer-to-gadget
      offset so mover logic keeps exact grab point and avoids late jump.
    - cleanup: mark unused drop event parameter as `EINA_UNUSED`.
    - fix many geometry issues and move across screens.
    - fix potential crashes.
    
    This is not perfect but it's MUCH better.
    Result:
    - Gadget no longer jumps on mouse release when dropped to desktop.
    - Gadget keeps expected size instead of being auto-enlarged.
    - Existing in-container shelf reorder behavior remains unchanged.
---
 src/bin/e_gadcon.c                | 195 ++++++++++++++++++++++++++++++--------
 src/modules/gadman/e_mod_gadman.c | 113 ++++++++++++++--------
 2 files changed, 228 insertions(+), 80 deletions(-)

diff --git a/src/bin/e_gadcon.c b/src/bin/e_gadcon.c
index 045b556b2..2681a2f96 100644
--- a/src/bin/e_gadcon.c
+++ b/src/bin/e_gadcon.c
@@ -2998,7 +2998,8 @@ _e_gadcon_cb_dnd_enter(void *data, const char *type EINA_UNUSED, void *event)
    if ((!gcc->hidden) && (gcc->gadcon == gc))
      {
         if (gc->dnd_enter_cb) gc->dnd_enter_cb(gc, gc->drag_gcc);
-        e_drag_hide(gc->drag_gcc->drag.drag);
+        if (gc->drag_gcc->drag.drag)
+          e_drag_hide(gc->drag_gcc->drag.drag);
         return;
      }
    if (gcc->gadcon != gc)
@@ -3006,7 +3007,8 @@ _e_gadcon_cb_dnd_enter(void *data, const char *type EINA_UNUSED, void *event)
    else if (e_gadcon_site_is_desktop(gcc->gadcon->location->site))
      {
         e_gadcon_client_show(gc->drag_gcc);
-        e_drag_hide(gc->drag_gcc->drag.drag);
+        if (gc->drag_gcc->drag.drag)
+          e_drag_hide(gc->drag_gcc->drag.drag);
         if (gc->dnd_enter_cb) gc->dnd_enter_cb(gc, gc->drag_gcc);
         return;
      }
@@ -3058,25 +3060,59 @@ _e_gadcon_cb_dnd_enter(void *data, const char *type EINA_UNUSED, void *event)
                   gc->new_gcc->cf->orient = gc->orient;
                }
           }
-        if (gc->new_gcc->o_frame)
-          e_gadcon_layout_pack_options_set(gc->new_gcc->o_frame, gc->new_gcc);
-        else if (gc->new_gcc->o_base)
-          {
-             e_gadcon_layout_pack_options_set(gc->new_gcc->o_base, gc->new_gcc);
-             if (!gc->o_container)
-               {
-                  int w, h, gw, gh;
+        {
+           Evas_Object *dst_o;
 
+           dst_o = gc->new_gcc->o_frame ? gc->new_gcc->o_frame : gc->new_gcc->o_base;
+           if (dst_o)
+             e_gadcon_layout_pack_options_set(dst_o, gc->new_gcc);
+           if (!dst_o) break;
+           if (!gc->o_container)
+          {
+                  int x, y, w, h, gw, gh;
+                  Eina_Bool size_invalid = EINA_FALSE;
+                  Eina_Bool source_is_layout = EINA_FALSE;
+                  Eina_Bool zone_changed = EINA_FALSE;
+                  Evas_Object *src_o;
+                  E_Zone *src_zone, *dst_zone;
+
+                  x = ev->x + gcc->drag.x - gc->zone->x;
+                  y = ev->y + gcc->drag.y - gc->zone->y;
                   w = gc->zone->w;
                   h = gc->zone->h;
-                  if ((!EINA_DBL_NONZERO(gc->new_gcc->config.pos_x)) && (!EINA_DBL_NONZERO(gc->new_gcc->config.pos_y)))
+                  if (w < 1) w = 1;
+                  if (h < 1) h = 1;
+                  if (x < 0) x = 0;
+                  else if (x > w) x = w;
+                  if (y < 0) y = 0;
+                  else if (y > h) y = h;
+                  gc->new_gcc->config.pos_x = (double)x / (double)w;
+                  gc->new_gcc->config.pos_y = (double)y / (double)h;
+                  if (gc->new_gcc->config.pos_x < 0.0) gc->new_gcc->config.pos_x = 0.0;
+                  else if (gc->new_gcc->config.pos_x > 1.0) gc->new_gcc->config.pos_x = 1.0;
+                  if (gc->new_gcc->config.pos_y < 0.0) gc->new_gcc->config.pos_y = 0.0;
+                  else if (gc->new_gcc->config.pos_y > 1.0) gc->new_gcc->config.pos_y = 1.0;
+                  gc->new_gcc->drag.x = gcc->drag.x;
+                  gc->new_gcc->drag.y = gcc->drag.y;
+
+                  if ((!EINA_DBL_NONZERO(gc->new_gcc->config.size_w)) ||
+                      (!EINA_DBL_NONZERO(gc->new_gcc->config.size_h)) ||
+                      (gc->new_gcc->config.size_w > 1.0) ||
+                      (gc->new_gcc->config.size_h > 1.0))
+                    size_invalid = EINA_TRUE;
+                  source_is_layout = !!gcc->gadcon->o_container;
+                  src_zone = e_gadcon_zone_get(gcc->gadcon);
+                  dst_zone = e_gadcon_zone_get(gc);
+                  zone_changed = !!(src_zone && dst_zone && (src_zone != dst_zone));
+                  if (size_invalid || source_is_layout || zone_changed)
                     {
-                       gc->new_gcc->config.pos_x = (double)ev->x / (double)w;
-                       gc->new_gcc->config.pos_y = (double)ev->y / (double)h;
-                    }
-                  if ((!EINA_DBL_NONZERO(gc->new_gcc->config.size_w)) && (!EINA_DBL_NONZERO(gc->new_gcc->config.size_h)))
-                    {
-                       evas_object_geometry_get(gcc->o_frame ? : gcc->o_base, NULL, NULL, &gw, &gh);
+                       src_o = gcc->o_frame ? gcc->o_frame : gcc->o_base;
+                       if (src_o)
+                         evas_object_geometry_get(src_o, NULL, NULL, &gw, &gh);
+                       else
+                         gw = gh = 1;
+                       if (gw < 1) gw = 1;
+                       if (gh < 1) gh = 1;
                        gc->new_gcc->config.size_w = (double)gw / (double)w;
                        gc->new_gcc->config.size_h = (double)gh / (double)h;
                     }
@@ -3085,12 +3121,25 @@ _e_gadcon_cb_dnd_enter(void *data, const char *type EINA_UNUSED, void *event)
                        gw = gc->new_gcc->config.size_w * w;
                        gh = gc->new_gcc->config.size_h * h;
                     }
-                  evas_object_resize(gc->new_gcc->o_base, gw, gh);
-                  evas_object_move(gc->new_gcc->o_base, ev->x, ev->y);
-               }
+                  if (gc->new_gcc->config.size_w < 0.0) gc->new_gcc->config.size_w = 0.0;
+                  else if (gc->new_gcc->config.size_w > 1.0) gc->new_gcc->config.size_w = 1.0;
+                  if (gc->new_gcc->config.size_h < 0.0) gc->new_gcc->config.size_h = 0.0;
+                  else if (gc->new_gcc->config.size_h > 1.0) gc->new_gcc->config.size_h = 1.0;
+                  if (gw > w) gw = w;
+                  if (gh > h) gh = h;
+                  if (x < 0) x = 0;
+                  else if (x > (w - gw)) x = w - gw;
+                  if (y < 0) y = 0;
+                  else if (y > (h - gh)) y = h - gh;
+                  gc->new_gcc->config.pos_x = (double)x / (double)w;
+                  gc->new_gcc->config.pos_y = (double)y / (double)h;
+                  evas_object_resize(dst_o, gw, gh);
+                  evas_object_move(dst_o, gc->zone->x + x, gc->zone->y + y);
           }
+        }
 
-        e_drag_hide(gc->drag_gcc->drag.drag);
+        if (gc->drag_gcc->drag.drag)
+          e_drag_hide(gc->drag_gcc->drag.drag);
         e_gadcon_client_edit_begin(gc->new_gcc);
         e_gadcon_client_autoscroll_set(gc->new_gcc, gcc->autoscroll);
 /*		  e_gadcon_client_resizable_set(gc->new_gcc, gcc->resizable);*/
@@ -3109,7 +3158,6 @@ _e_gadcon_cb_dnd_move(void *data, const char *type EINA_UNUSED, void *event)
    E_Event_Dnd_Move *ev;
    E_Gadcon *gc;
    E_Gadcon_Client *gcc = NULL;
-   int dx = 0, dy = 0;
    Evas_Object *o;
 
    ev = event;
@@ -3131,16 +3179,33 @@ _e_gadcon_cb_dnd_move(void *data, const char *type EINA_UNUSED, void *event)
      gcc->config.pos = ev->y - gcc->config.size / 2;
    if (!gcc->gadcon->o_container)
      {
-        int w, h;
+        int x, y, w, h, ow, oh;
+        x = ev->x + gcc->drag.x - gc->zone->x;
+        y = ev->y + gcc->drag.y - gc->zone->y;
         w = gc->zone->w;
         h = gc->zone->h;
-        gcc->config.pos_x = (double)ev->x / (double)w;
-        gcc->config.pos_y = (double)ev->y / (double)h;
-        if (gcc->o_frame) evas_object_move(gcc->o_frame, ev->x, ev->y);
+        if (w < 1) w = 1;
+        if (h < 1) h = 1;
+        if (gcc->o_frame) evas_object_geometry_get(gcc->o_frame, NULL, NULL, &ow, &oh);
+        else if (gcc->o_base) evas_object_geometry_get(gcc->o_base, NULL, NULL, &ow, &oh);
+        else ow = oh = 1;
+        if (ow < 1) ow = 1;
+        if (oh < 1) oh = 1;
+        if (x < 0) x = 0;
+        else if (x > (w - ow)) x = w - ow;
+        if (y < 0) y = 0;
+        else if (y > (h - oh)) y = h - oh;
+        gcc->config.pos_x = (double)x / (double)w;
+        gcc->config.pos_y = (double)y / (double)h;
+        if (gcc->config.pos_x < 0.0) gcc->config.pos_x = 0.0;
+        else if (gcc->config.pos_x > 1.0) gcc->config.pos_x = 1.0;
+        if (gcc->config.pos_y < 0.0) gcc->config.pos_y = 0.0;
+        else if (gcc->config.pos_y > 1.0) gcc->config.pos_y = 1.0;
+        if (gcc->o_frame) evas_object_move(gcc->o_frame, gc->zone->x + x, gc->zone->y + y);
         else if (gcc->o_base)
-          evas_object_move(gcc->o_base, ev->x, ev->y);
+          evas_object_move(gcc->o_base, gc->zone->x + x, gc->zone->y + y);
      }
-   _e_gadcon_client_inject(gc, gcc, ev->x + dx, ev->y + dy);
+   _e_gadcon_client_inject(gc, gcc, ev->x, ev->y);
 
    o = gcc->o_frame ? gcc->o_frame : gcc->o_base;
    if (o)
@@ -3154,25 +3219,37 @@ static void
 _e_gadcon_cb_dnd_leave(void *data, const char *type EINA_UNUSED, void *event EINA_UNUSED)
 {
    E_Gadcon *gc;
+   E_Gadcon_Client *drag_gcc;
 
    gc = data;
    //INF("DND LEAVE");
+   drag_gcc = gc->drag_gcc;
+   if (!drag_gcc)
+     {
+        if (gc->new_gcc)
+          {
+             e_object_del(E_OBJECT(gc->new_gcc));
+             gc->new_gcc = NULL;
+          }
+        return;
+     }
 
    /* If we exit the starting container hide the gadcon visual */
-   if (gc->drag_gcc->gadcon == gc) e_gadcon_client_hide(gc->drag_gcc);
+   if (drag_gcc->gadcon == gc) e_gadcon_client_hide(drag_gcc);
 
    /* Delete temporary object */
    if (!gc->new_gcc)
      {
-        if (gc->dnd_leave_cb) gc->dnd_leave_cb(gc, gc->drag_gcc);
+        if (gc->dnd_leave_cb) gc->dnd_leave_cb(gc, drag_gcc);
         return;
      }
 
    //INF("DELETING new_gcc");
    e_object_del(E_OBJECT(gc->new_gcc));
    gc->new_gcc = NULL;
-   e_drag_show(gc->drag_gcc->drag.drag);
-   if (gc->dnd_leave_cb) gc->dnd_leave_cb(gc, gc->drag_gcc);
+   if (drag_gcc->drag.drag)
+     e_drag_show(drag_gcc->drag.drag);
+   if (gc->dnd_leave_cb) gc->dnd_leave_cb(gc, drag_gcc);
 }
 
 static void
@@ -3180,18 +3257,29 @@ _e_gadcon_cb_dnd_drop(void *data, const char *type EINA_UNUSED, void *event EINA
 {
    E_Gadcon *gc;
    E_Gadcon_Client *gcc = NULL;
+   E_Gadcon_Client *drag_gcc;
 
    gc = data;
+   drag_gcc = gc->drag_gcc;
+   if (!drag_gcc)
+     {
+        if (gc->new_gcc)
+          {
+             e_object_del(E_OBJECT(gc->new_gcc));
+             gc->new_gcc = NULL;
+          }
+        return;
+     }
    //INF("DND DROP");
-   gc->cf->clients = eina_list_append(gc->cf->clients, gc->drag_gcc->cf);
+   gc->cf->clients = eina_list_append(gc->cf->clients, drag_gcc->cf);
    if (!gc->new_gcc)
      {
         /* using drag_gcc, so do things a bit differently
          * this only happens with gadman dnd, broken on shelves
          */
-        _e_gadcon_client_save(gc->drag_gcc);
-        e_gadcon_client_show(gc->drag_gcc);
-        if (gc->dnd_drop_cb) gc->dnd_drop_cb(gc, gc->drag_gcc);
+        _e_gadcon_client_save(drag_gcc);
+        e_gadcon_client_show(drag_gcc);
+        if (gc->dnd_drop_cb) gc->dnd_drop_cb(gc, drag_gcc);
         return;
      }
 
@@ -3199,28 +3287,53 @@ _e_gadcon_cb_dnd_drop(void *data, const char *type EINA_UNUSED, void *event EINA
 
    if (!gc->o_container)
      {
+        Evas_Object *o;
+        int x, y, w, h, ow, oh;
+        o = gc->new_gcc->o_frame ? gc->new_gcc->o_frame : gc->new_gcc->o_base;
+        if (o)
+          {
+             evas_object_geometry_get(o, &x, &y, &ow, &oh);
+             x -= gc->zone->x;
+             y -= gc->zone->y;
+             w = gc->zone->w;
+             h = gc->zone->h;
+             if (w < 1) w = 1;
+             if (h < 1) h = 1;
+             if (ow < 1) ow = 1;
+             if (oh < 1) oh = 1;
+             if (x < 0) x = 0;
+             else if (x > (w - ow)) x = w - ow;
+             if (y < 0) y = 0;
+             else if (y > (h - oh)) y = h - oh;
+             gc->new_gcc->config.pos_x = (double)x / (double)w;
+             gc->new_gcc->config.pos_y = (double)y / (double)h;
+             if (gc->new_gcc->o_frame) evas_object_move(gc->new_gcc->o_frame, gc->zone->x + x, gc->zone->y + y);
+             else if (gc->new_gcc->o_base)
+               evas_object_move(gc->new_gcc->o_base, gc->zone->x + x, gc->zone->y + y);
+          }
+
         /* FIXME: gadman sucks and should probably use a regular gadcon layout, but it doesn't
          * so we need to repop here
          */
-        gcc->cf = gc->drag_gcc->cf;
+        gcc->cf = drag_gcc->cf;
         _e_gadcon_client_save(gc->new_gcc);
         e_object_del(E_OBJECT(gc->new_gcc));
         gc->new_gcc = NULL;
         /* this little hack prevents the dead gcc from overwriting our config */
-        gc->drag_gcc->moving = 0;
+        drag_gcc->moving = 0;
         e_gadcon_custom_populate_request(gc);
         e_config_save_queue();
-        if (gc->dnd_drop_cb) gc->dnd_drop_cb(gc, gc->drag_gcc);
+        if (gc->dnd_drop_cb) gc->dnd_drop_cb(gc, gcc);
         goto cleanup;
      }
    if (gc->editing) e_gadcon_client_edit_begin(gc->new_gcc);
    gc->new_gcc = NULL;
    e_config_save_queue();
-   if (gc->dnd_drop_cb) gc->dnd_drop_cb(gc, gc->drag_gcc);
+   if (gc->dnd_drop_cb) gc->dnd_drop_cb(gc, gcc);
 
 cleanup:
    /* still has refcount from drag */
-   e_object_del(E_OBJECT(gc->drag_gcc));
+   e_object_del(E_OBJECT(drag_gcc));
    gc->drag_gcc = NULL;
 }
 
diff --git a/src/modules/gadman/e_mod_gadman.c b/src/modules/gadman/e_mod_gadman.c
index f30bf5d5f..8fcb61c48 100644
--- a/src/modules/gadman/e_mod_gadman.c
+++ b/src/modules/gadman/e_mod_gadman.c
@@ -3,6 +3,7 @@
 /* local protos */
 static void             _attach_menu(void *data, E_Gadcon_Client *gcc, E_Menu *menu);
 static void             _save_widget_position(E_Gadcon_Client *gcc);
+static void             _save_widget_position_for_zone(E_Gadcon_Client *gcc, E_Zone *zone);
 static void             _apply_widget_position(E_Gadcon_Client *gcc);
 static E_Gadcon_Client *_gadman_gadget_add(const E_Gadcon_Client_Class *cc, Gadman_Layer_Type layer, E_Config_Gadcon_Client *src_cf);
 static Eina_Bool _gadman_module_init_end_cb(void *d EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSED);
@@ -33,6 +34,7 @@ static void             on_menu_add(void *data, E_Menu *m, E_Menu_Item *mi);
 static Eina_Bool       _gadman_module_cb(void *d EINA_UNUSED, int type EINA_UNUSED, E_Event_Module_Update *ev);
 static int              _e_gadman_client_add(void *data EINA_UNUSED, E_Gadcon_Client *, const E_Gadcon_Client_Class *cc);
 static void             _e_gadman_client_remove(void *data EINA_UNUSED, E_Gadcon_Client *gcc);
+static E_Gadcon_Client *_active_drag_gcc_get(void);
 
 static void             _e_gadman_handlers_add(void);
 static void             _e_gadman_handler_del(void);
@@ -255,7 +257,6 @@ _gadman_gadget_size_hints_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj,
         h = MAX(h, gcc->aspect.h);
      }
    evas_object_resize(gcc->o_frame, w, h);
-   _save_widget_position(gcc);
 }
 
 static E_Gadcon_Client *
@@ -682,12 +683,25 @@ _gadman_gadcon_free(E_Gadcon *gc)
 static void
 _gadman_gadcon_dnd_enter_cb(E_Gadcon *gc, E_Gadcon_Client *gcc)
 {
+   Evas_Object *o;
+   int ox, oy, mx, my;
 
    /* only use this for dragging gadcons around the desktop */
    if ((!eina_list_data_find(Man->gadcons[GADMAN_LAYER_BG], gc)) &&
        (!eina_list_data_find(Man->gadcons[GADMAN_LAYER_TOP], gc)))
      return;
    if (gc != gcc->gadcon) return;
+
+   /* Keep mover and widget aligned to the existing grab point for all DnD sources. */
+   o = gcc->o_frame ? gcc->o_frame : gcc->o_base;
+   if (o)
+     {
+        evas_pointer_output_xy_get(gc->evas, &mx, &my);
+        evas_object_geometry_get(o, &ox, &oy, NULL, NULL);
+        gcc->dx = mx - ox;
+        gcc->dy = my - oy;
+     }
+
    //INF("ENTER: %u", e_object_ref_get((void*)gcc));
    gadman_gadget_edit_start(gcc);
 }
@@ -729,43 +743,40 @@ _gadman_gadcon_dnd_move_cb(E_Gadcon *gc, E_Gadcon_Client *gcc)
    Evas_Object *mover;
    E_Zone *zone;
    int x, y, mx, my;
-   int ox, oy, ow, oh;
+   int ow, oh;
 
-   if (gc != gcc->gadcon) return;
    /* only use this for dragging gadcons around the desktop */
    if ((!eina_list_data_find(Man->gadcons[GADMAN_LAYER_BG], gc)) &&
        (!eina_list_data_find(Man->gadcons[GADMAN_LAYER_TOP], gc)))
      return;
 
    mover = _get_mover(gcc);
-   evas_object_geometry_get(gcc->o_frame, &x, &y, NULL, NULL);
-   evas_object_geometry_get(mover, &ox, &oy, &ow, &oh);
+   evas_pointer_output_xy_get(gc->evas, &x, &y);
+   evas_object_geometry_get(mover, NULL, NULL, &ow, &oh);
 
-   /* don't go out of the screen */
-   x = MAX(x, gcc->dx), y = MAX(y, gcc->dy);
-
-   /* adjust in case one screen is larger than another */
-   zone = e_gadcon_zone_get(gc);
+   /* keep drag origin under pointer and clamp to active zone */
+   zone = e_comp_zone_xy_get(x, y);
+   if (!zone) zone = e_gadcon_zone_get(gc);
    mx = MIN(Man->width, zone->x + zone->w), my = MIN(Man->height, zone->y + zone->h);
-   x = MIN(x, mx - ow + gcc->dx), y = MIN(y, my - oh + gcc->dy);
+   x = MAX(x, zone->x + gcc->dx);
+   y = MAX(y, zone->y + gcc->dy);
+   x = MIN(x, mx - ow + gcc->dx);
+   y = MIN(y, my - oh + gcc->dy);
 
    evas_object_move(gcc->o_frame, x - gcc->dx, y - gcc->dy);
    evas_object_move(mover, x - gcc->dx, y - gcc->dy);
    evas_object_raise(gcc->o_frame);
    evas_object_raise(mover);
-   _save_widget_position(gcc);
+   _save_widget_position_for_zone(gcc, zone);
 }
 
 static void
 _gadman_gadcon_dnd_drop_cb(E_Gadcon *gc, E_Gadcon_Client *gcc)
 {
    E_Config_Gadcon_Client *cf;
-   E_Zone *dst_zone = NULL;
+   E_Zone *dst_zone = NULL, *src_zone = NULL;
    E_Gadcon *dst_gadcon;
-   Evas_Object *mover;
-   int gx, gy;
 
-   if (gc != gcc->gadcon) return;
    /* only use this for dragging gadcons around the desktop */
    if ((!eina_list_data_find(Man->gadcons[GADMAN_LAYER_BG], gc)) &&
        (!eina_list_data_find(Man->gadcons[GADMAN_LAYER_TOP], gc)))
@@ -774,22 +785,21 @@ _gadman_gadcon_dnd_drop_cb(E_Gadcon *gc, E_Gadcon_Client *gcc)
    gcc->moving = 0;
    gcc->dx = gcc->dy = 0;
 
-   /* checking if zone was changed for dragged gadget */
-   mover = _get_mover(gcc);
-   evas_object_geometry_get(mover, &gx, &gy, NULL, NULL);
-   dst_zone = e_comp_zone_xy_get(gx, gy);
-   if (dst_zone && (gcc->gadcon->zone != dst_zone))
+   /* Use the drop target zone from the receiving gadcon.
+    * Using mover geometry can pick the old zone while crossing screen edges.
+    */
+   dst_zone = e_gadcon_zone_get(gc);
+   src_zone = e_gadcon_zone_get(gcc->gadcon);
+   if (dst_zone && src_zone && (src_zone != dst_zone))
      {
         unsigned int layer = gcc->gadcon->id - ID_GADMAN_LAYER_BASE;
         cf = gcc->cf;
         gcc->gadcon->cf->clients = eina_list_remove(gcc->gadcon->cf->clients, cf);
         dst_gadcon = gadman_gadcon_get(dst_zone, layer);
         if (dst_gadcon)
-          {
-             dst_gadcon->cf->clients = eina_list_append(dst_gadcon->cf->clients, cf);
-          }
+          dst_gadcon->cf->clients = eina_list_append(dst_gadcon->cf->clients, cf);
      }
-   _save_widget_position(gcc);
+   _save_widget_position_for_zone(gcc, dst_zone ?: src_zone);
    e_config_save_queue();
 }
 
@@ -959,17 +969,46 @@ _get_mover(E_Gadcon_Client *gcc)
    return Man->movers[gcc->gadcon->id - ID_GADMAN_LAYER_BASE];
 }
 
+static E_Gadcon_Client *
+_active_drag_gcc_get(void)
+{
+   unsigned int layer;
+   E_Gadcon_Client *gcc;
+
+   for (layer = 0; layer < GADMAN_LAYER_COUNT; layer++)
+     {
+        gcc = Man->drag_gcc[layer];
+        if (!gcc) continue;
+        if (gcc->moving || gcc->resizing || (gcc->gadcon->drag_gcc == gcc))
+          return gcc;
+     }
+   for (layer = 0; layer < GADMAN_LAYER_COUNT; layer++)
+     if (Man->drag_gcc[layer]) return Man->drag_gcc[layer];
+   return NULL;
+}
+
 static void
 _save_widget_position(E_Gadcon_Client *gcc)
+{
+   _save_widget_position_for_zone(gcc, gcc->gadcon->zone);
+}
+
+static void
+_save_widget_position_for_zone(E_Gadcon_Client *gcc, E_Zone *zone)
 {
    int x, y, w, h;
+   int zw, zh;
+
+   if (!zone) return;
+   zw = MAX(zone->w, 1);
+   zh = MAX(zone->h, 1);
 
    evas_object_geometry_get(gcc->o_frame, &x, &y, &w, &h);
-   x -= gcc->gadcon->zone->x, y -= gcc->gadcon->zone->y;
-   gcc->config.pos_x = (double)x / (double)gcc->gadcon->zone->w;
-   gcc->config.pos_y = (double)y / (double)gcc->gadcon->zone->h;
-   gcc->config.size_w = (double)w / (double)gcc->gadcon->zone->w;
-   gcc->config.size_h = (double)h / (double)gcc->gadcon->zone->h;
+   x -= zone->x, y -= zone->y;
+   gcc->config.pos_x = (double)x / (double)zw;
+   gcc->config.pos_y = (double)y / (double)zh;
+   gcc->config.size_w = (double)w / (double)zw;
+   gcc->config.size_h = (double)h / (double)zh;
    if (gcc->cf)
      {
         gcc->cf->geom.pos_x = gcc->config.pos_x;
@@ -1281,9 +1320,8 @@ on_top(void *data, Evas_Object *o EINA_UNUSED, const char *em EINA_UNUSED, const
    int action = ""
    Evas_Object *mover;
    E_Gadcon_Client *drag_gcc;
-   int layer = Man->visible;
 
-   drag_gcc = Man->drag_gcc[layer];
+   drag_gcc = _active_drag_gcc_get();
    if (!drag_gcc) return;
 
    mover = _get_mover(drag_gcc);
@@ -1347,9 +1385,8 @@ on_right(void *data, Evas_Object *o EINA_UNUSED, const char *em EINA_UNUSED, con
    int mx, my; //Mouse coord
    int action;
    E_Gadcon_Client *drag_gcc;
-   int layer = Man->visible;
 
-   drag_gcc = Man->drag_gcc[layer];
+   drag_gcc = _active_drag_gcc_get();
    if (!drag_gcc) return;
 
    mover = _get_mover(drag_gcc);
@@ -1401,9 +1438,8 @@ on_down(void *data, Evas_Object *o EINA_UNUSED, const char *em EINA_UNUSED, cons
    int mx, my; //Mouse coord
    int action = ""
    E_Gadcon_Client *drag_gcc;
-   int layer = Man->visible;
 
-   drag_gcc = Man->drag_gcc[layer];
+   drag_gcc = _active_drag_gcc_get();
    if (!drag_gcc) return;
 
    mover = _get_mover(drag_gcc);
@@ -1453,9 +1489,8 @@ on_left(void *data, Evas_Object *o EINA_UNUSED, const char *em EINA_UNUSED, cons
    int mx, my; //Mouse coord
    int action = ""
    E_Gadcon_Client *drag_gcc;
-   int layer = Man->visible;
 
-   drag_gcc = Man->drag_gcc[layer];
+   drag_gcc = _active_drag_gcc_get();
    if (!drag_gcc) return;
 
    mover = _get_mover(drag_gcc);
@@ -1523,7 +1558,7 @@ on_move(void *data, Evas_Object *o EINA_UNUSED, const char *em EINA_UNUSED, cons
 
    /* DRAG_START */
    if (action != DRAG_START) return;
-   drag_gcc = Man->drag_gcc[Man->visible];
+   drag_gcc = _active_drag_gcc_get();
    if (!drag_gcc) return;
    gc = drag_gcc->gadcon;
    mover = _get_mover(drag_gcc);

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.

Reply via email to