yakov pushed a commit to branch master.

http://git.enlightenment.org/tools/erigo.git/commit/?id=7eaa75641d59abf9b0e934a792e288f94fbc4881

commit 7eaa75641d59abf9b0e934a792e288f94fbc4881
Author: Yakov Goldberg <yako...@samsung.com>
Date:   Thu Dec 3 10:16:12 2015 +0200

    Fixing segv when dragging between factory and window
    
    Add reference counting for enter/leave on Editor's level to properly
    delete Eo and Gui_Widget instances in DnD.
---
 src/bin/gui/dnd.c    | 45 +++++++++++++++++++++------------------------
 src/bin/gui/editor.c | 16 +++++++++++++++-
 2 files changed, 36 insertions(+), 25 deletions(-)

diff --git a/src/bin/gui/dnd.c b/src/bin/gui/dnd.c
index f6a169b..57590db 100644
--- a/src/bin/gui/dnd.c
+++ b/src/bin/gui/dnd.c
@@ -220,21 +220,23 @@ _dropleave(void *data, Evas_Object *obj)
      {
         Drop_Target_Info *main_wdg_ti = data;
 
-        /* if ti->drop_target is not current main widget, then it means,
-         * that prev drop target, box for example wasn't leaved properly.
-         * For example moving mouse fast from one window to another will cause 
"jump".
-         * So need to call leave properly.
-         * */
-        if (main_wdg_ti->drop_target != main_wdg_ti->wdg)
+        /* Main object can be leaved straight from internal container.
+         * T.e. not from window, but from the box
+         * In this case callback for this cantainer will be called.
+         *
+         * Else callback for main wdg will be called. */
+        if (main_wdg_ti->drop_target)
           {
              Drop_Target_Info *ti = wdg_data_get(main_wdg_ti->drop_target, 
DROP_TARGET);
              if (ti->drop_target_leave)
                ti->drop_target_leave(ti->leavedata, obj);
+             main_wdg_ti->drop_target = NULL;
+          }
+        else
+          {
+             if (main_wdg_ti->drop_target_leave)
+               main_wdg_ti->drop_target_leave(main_wdg_ti->leavedata, obj);
           }
-        main_wdg_ti->drop_target = NULL;
-
-        if (main_wdg_ti->drop_target_leave)
-          main_wdg_ti->drop_target_leave(main_wdg_ti->leavedata, obj);
      }
 
    if (!_drop_info_global._enter_leave_counter)
@@ -355,34 +357,29 @@ _droppos(void *data, Eo *obj, Evas_Coord x, Evas_Coord y, 
Elm_Xdnd_Action action
 
    Gui_Session *session = (Gui_Session *) gui_context_editor_session_get(ctx);
    _drop_target_iterate(&drop_candidate, session, x / scale, y / scale);
+   dnd_debug("--->Drop Candidate: %s; Coords within: %d %d", 
wdg_name_get(drop_candidate), x, y);
 
    if (main_wdg_ti->drop_target != drop_candidate)
      {
-        /* Call leave callback for previous target widget.
-         * If prev wdg is MainWdg, don't call leave. */
-        //if (main_wdg_ti->drop_target != wdg)
+        /* Call enter callback for new target widget. */
           {
-             Drop_Target_Info *ti = wdg_data_get(main_wdg_ti->drop_target, 
DROP_TARGET);
-             if (ti->drop_target_leave)
+             Drop_Target_Info *ti = wdg_data_get(drop_candidate, DROP_TARGET);
+             if (ti->drop_target_enter)
                {
-                  ti->drop_target_leave(ti->leavedata, NULL);
+                  ti->drop_target_enter(ti->enterdata, NULL);
                }
           }
-        /* Call enter callback for new target widget.
-         * If new wdg is MainWdg, don't call enter. */
-        //if (drop_candidate != wdg)
+        /* Call leave callback for previous target widget. */
           {
-             Drop_Target_Info *ti = wdg_data_get(drop_candidate, DROP_TARGET);
-             if (ti->drop_target_enter)
+             Drop_Target_Info *ti = wdg_data_get(main_wdg_ti->drop_target, 
DROP_TARGET);
+             if (ti->drop_target_leave)
                {
-                  ti->drop_target_enter(ti->enterdata, NULL);
+                  ti->drop_target_leave(ti->leavedata, NULL);
                }
           }
         main_wdg_ti->drop_target = drop_candidate;
      }
 
-   dnd_debug("--->Drop Candidate: %s; Coords within: %d %d", 
wdg_name_get(drop_candidate), x, y);
-
    /* Simulate poscb inside drop candidate.
     * Get callbacks from drop candidate and call. */
    Drop_Target_Info *ti = wdg_data_get(drop_candidate, DROP_TARGET);
diff --git a/src/bin/gui/editor.c b/src/bin/gui/editor.c
index 68bf2ac..a5eb8f9 100644
--- a/src/bin/gui/editor.c
+++ b/src/bin/gui/editor.c
@@ -41,6 +41,7 @@
 typedef struct
 {
    Eo *eo_cur;
+   int  eo_ref_count;
    Eina_Bool packed; /* Need this, because no API to check if object is packed 
into table
                         and unpack causes error message. */
    /* Box packing data. */
@@ -1506,6 +1507,7 @@ _drop_target_enter(void *data, Evas_Object *obj)
              di = wdg_data_get(main_wdg, EDITOR_DND_DATA);
           }
         _wdg_border_draw(drop_target_wdg, EINA_TRUE, BORDER_DROP_TARGET);
+        di->eo_ref_count++;
      }
    else if (canvas_drop_target != NULL)
      {
@@ -1561,6 +1563,7 @@ _drop_target_leave(void *data, Evas_Object *obj)
         else
            di = wdg_data_get(wdg_main_wdg_get(drop_target_wdg), 
EDITOR_DND_DATA);
         drop_target_wdg_eo = session_eo_get(session, drop_target_wdg);
+        di->eo_ref_count--;
      }
    else if (canvas_drop_target != NULL)
      {
@@ -1623,7 +1626,7 @@ _drop_target_leave(void *data, Evas_Object *obj)
         di->drop_instead_item_obj = NULL;
      }
 
-   if (di->eo_cur && IS_MAIN(drop_target_wdg) && (di->eo_cur != 
session_eo_get(session, dnd_drag_wdg_get())))
+   if (drop_target_wdg && !di->eo_ref_count && di->eo_cur && (di->eo_cur != 
session_eo_get(session, dnd_drag_wdg_get())))
      {
         eo_del(di->eo_cur);
         di->eo_cur = NULL;
@@ -1632,6 +1635,17 @@ _drop_target_leave(void *data, Evas_Object *obj)
      {
         if (di->eo_cur) eo_do(di->eo_cur, efl_gfx_visible_set(EINA_FALSE));
      }
+
+   if (!dnd_counter_get())
+     {
+        /* If drag was started in factory or outside Erigo - delete widget */
+        if (!dnd_is_source() && _dragged_wdg)
+          {
+             wdg_del(_dragged_wdg);
+          }
+        /* ... if started on canvas - NULL pointer */
+        _dragged_wdg = NULL;
+     }
 }
 
 /* In the beginning of drop handler we want to determine,

-- 


Reply via email to