yakov pushed a commit to branch master.

http://git.enlightenment.org/tools/erigo.git/commit/?id=36759bb7f1012aaa5afea7db2aea2ad1b6476e68

commit 36759bb7f1012aaa5afea7db2aea2ad1b6476e68
Author: Yakov Goldberg <yako...@samsung.com>
Date:   Tue Dec 1 19:05:13 2015 +0200

    Fixing segv when dragging between factory and window
    
    The bug was: segv in _obj_remove_from_session() because widget did not
    exist. It happened because: in _drop_target_leave() we were deleting
    eo_cur and deleting _dragged_wdg right after that.
    Because of delay in callback call, widget was already deleted in
    _obj_remove_from_session(), which is called by eo_del(eo_cur).
    
    I added _factory_dragdone_post_cb(), which deletes _dragged_wdg if it
    was not accepted or accepted outside Erigo.
    
    Virtually crash still can happen if _drop_target_leave() will be called
    and _dragdone will happen right after this. But practically this is
    almost impossible.
---
 src/bin/gui/dnd.c                | 10 ++++++----
 src/bin/gui/dnd.h                |  3 +--
 src/bin/gui/editor.c             | 27 ++++++++++++++++-----------
 src/bin/gui/egui_logic.c         |  4 ++--
 src/bin/gui/egui_logic_private.h |  1 +
 5 files changed, 26 insertions(+), 19 deletions(-)

diff --git a/src/bin/gui/dnd.c b/src/bin/gui/dnd.c
index 078716b..1eb9dc6 100644
--- a/src/bin/gui/dnd.c
+++ b/src/bin/gui/dnd.c
@@ -31,9 +31,10 @@ typedef struct
    Eid *wdg_id; /*Widget id*/
    char *image_path; /* image for DnD icon. */
    Eo *obj; /*object, where drag starts. Used to call cb on delete.  */
+   void (*_factory_dragdone_post_cb)(Eina_Bool accept, const Eo *wdg_eo, const 
Gui_Widget * drag_start_wdg);
 } Factory_Drag_Info;
 
-Factory_Drag_Info _wdg_drag = {NULL, NULL, NULL};
+Factory_Drag_Info _wdg_drag = {NULL, NULL, NULL, NULL};
 
 /* Information about Drop Target*/
 typedef struct
@@ -177,8 +178,7 @@ static void
 _dragdone(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED)
 {
    dnd_debug("In");
-
-   if (_drag_info_global.canvas_is_source)
+   if (_drag_info_global._wdg_dragdone_post_cb)
      {
         _drag_info_global._wdg_dragdone_post_cb(_drag_info_global.drag_accept, 
_drag_info_global.obj, _drag_info_global.drag_start_wdg);
      }
@@ -488,6 +488,7 @@ _drag_start_from_factory(void *data)
    char *wdg_data = json_widget_generate(fdi->wdg_id);
    dnd_debug("Data %s", wdg_data);
    _drag_info_global._drag_data = wdg_data;
+   _drag_info_global._wdg_dragdone_post_cb = fdi->_factory_dragdone_post_cb;
    elm_drag_start(fdi->obj, ELM_SEL_FORMAT_TEXT,
                   wdg_data, ELM_XDND_ACTION_COPY,
                   image_create_icon_f, fdi,
@@ -534,13 +535,14 @@ _factory_drag_info_free(void *data, Eo *obj EINA_UNUSED, 
const Eo_Event_Descript
 /* Function to make Eo object draggable, when mouse down/up are handled inside.
  * Dragging from factory. */
 void
-drag_add(Eo *obj, const char *image_path, Eid *wdg_id)
+drag_add(Eo *obj, const char *image_path, Eid *wdg_id, void 
(*_factory_dragdone_post_cb)(Eina_Bool accept, const Eo *wdg_eo, const 
Gui_Widget * drag_start_wdg))
 {
    Factory_Drag_Info *fdi = calloc(1, sizeof(Factory_Drag_Info));
    if (image_path)
      fdi->image_path = strdup(image_path);
    fdi->wdg_id = wdg_id;
    fdi->obj = obj;
+   fdi->_factory_dragdone_post_cb = _factory_dragdone_post_cb;
    eo_do(obj, eo_event_callback_add(EVAS_OBJECT_EVENT_MOUSE_DOWN, 
_factory_drag_mouse_down, fdi));
    eo_do(obj, eo_event_callback_add(EVAS_OBJECT_EVENT_DEL, 
_factory_drag_info_free, fdi));
 }
diff --git a/src/bin/gui/dnd.h b/src/bin/gui/dnd.h
index 884bb3e..63e4518 100644
--- a/src/bin/gui/dnd.h
+++ b/src/bin/gui/dnd.h
@@ -2,8 +2,7 @@
 #define _DND_H
 
 void
-drag_add(Eo *obj, const char *image_path, Eid *wdg_id);
-
+drag_add(Eo *obj, const char *image_path, Eid *wdg_id, void 
(*_factory_dragdone_post_cb)(Eina_Bool accept, const Eo *wdg_eo, const 
Gui_Widget * drag_start_wdg));
 void
 drag_start(Eo *obj, Eid *wdg_id, void (*_dragdone_post_cb)(Eina_Bool accept, 
const Eo *wdg_eo, const Gui_Widget *drag_start_wdg));
 
diff --git a/src/bin/gui/editor.c b/src/bin/gui/editor.c
index 84e6af8..f32e3fb 100644
--- a/src/bin/gui/editor.c
+++ b/src/bin/gui/editor.c
@@ -1632,17 +1632,6 @@ _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,
@@ -2794,6 +2783,21 @@ _drag_start_post(const Gui_Widget *wdg, const Eo 
*_wdg_eo)
    wdg_parent_set((Gui_Widget *) wdg, NULL);
 }
 
+/* This callback is added for dragging object from factory. */
+static void
+_factory_dragdone_post_cb(Eina_Bool accept, const Eo *wdg_eo EINA_UNUSED, 
const Gui_Widget *drag_start_wdg EINA_UNUSED)
+{
+   if (!accept ||
+       (accept && !dnd_is_destination()))
+     {
+        if (_dragged_wdg)
+          {
+             wdg_del(_dragged_wdg);
+             _dragged_wdg = NULL;
+          }
+     }
+}
+
 /* This callback is added only for dragging of objects on canvas. */
 static void
 _dragdone_post_cb(Eina_Bool accept, const Eo *wdg_eo, const Gui_Widget 
*drag_start_wdg)
@@ -4863,6 +4867,7 @@ editor_init(GuiLogicCbs *_guilogic_cbs)
    _guilogic_cbs->_project_close = _project_close;
    _guilogic_cbs->_project_new = _project_new;
    _guilogic_cbs->_theme_hoversel_fill = _theme_hoversel_fill;
+   _guilogic_cbs->_factory_dragdone_post_cb = _factory_dragdone_post_cb;
 
    updater_completion_callback_add(_context_changed_cb, NULL);
 
diff --git a/src/bin/gui/egui_logic.c b/src/bin/gui/egui_logic.c
index 78bcfcf..b89401c 100644
--- a/src/bin/gui/egui_logic.c
+++ b/src/bin/gui/egui_logic.c
@@ -1066,7 +1066,7 @@ egui_start(const char *filename)
               eo_event_callback_add(EVAS_OBJECT_EVENT_MOUSE_DOWN, 
_factory_tt_mouse_down, NULL)); \
         elm_object_tooltip_text_set(box, #widget); \
         eo_do(eo_parent, elm_obj_table_pack(box, x, y, w, h)); \
-        drag_add(box, NULL, obj_id); \
+        drag_add(box, NULL, obj_id, _guilogic_cbs->_factory_dragdone_post_cb); 
\
         _factory_widgets_list = eina_list_append(_factory_widgets_list, box); \
      }
 #define FACTORY_IMG_CREATE(widget, image_path, parent, x, y, w, h) \
@@ -1082,7 +1082,7 @@ egui_start(const char *filename)
         eo_do(o, eo_event_callback_add(EVAS_OBJECT_EVENT_MOUSE_DOWN, 
_factory_tt_mouse_down, NULL)); \
         eo_do(eo_parent, elm_obj_table_pack(o, x, y, w, h)); \
         wdg_id = gui_context_eid_get_by_name(global_context_get(), #widget); \
-        drag_add(o, path, wdg_id); \
+        drag_add(o, path, wdg_id, _guilogic_cbs->_factory_dragdone_post_cb); \
      }
 
    gui_parser_json_file_read((Gui_Context *)global_context_get(), 
PACKAGE_DATA_DIR"/layouts/factory.json");
diff --git a/src/bin/gui/egui_logic_private.h b/src/bin/gui/egui_logic_private.h
index 84a0e77..2c856c9 100644
--- a/src/bin/gui/egui_logic_private.h
+++ b/src/bin/gui/egui_logic_private.h
@@ -16,6 +16,7 @@ typedef struct
    void (*_project_close)(const Gui_Context *ctx);
    Gui_Context* (*_project_new)(const char *filename);
    void (*_theme_hoversel_fill)();
+   void (*_factory_dragdone_post_cb)(Eina_Bool accept, const Eo *wdg_eo, const 
Gui_Widget * drag_start_wdg);
 } GuiLogicCbs;
 
 Eina_Bool

-- 


Reply via email to