summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChunEon Park <hermet@hermet.pe.kr>2015-01-15 22:36:28 +0900
committerChunEon Park <hermet@hermet.pe.kr>2015-01-15 22:36:28 +0900
commit493ea8f2264e72b95cc36eafa639eb809d382d3d (patch)
tree8826b9737c4ea46d47cadaa9bae0e52523aa115f
parent741698256474e589a7cf6cb19aed1292c9b12583 (diff)
genlist: guard the item deletion problem.
this exceptional code prevents the deletion of the item in the middle of the callback.
-rw-r--r--src/lib/elm_genlist.c37
1 files changed, 25 insertions, 12 deletions
diff --git a/src/lib/elm_genlist.c b/src/lib/elm_genlist.c
index 1168f3ec0..df17eaf5e 100644
--- a/src/lib/elm_genlist.c
+++ b/src/lib/elm_genlist.c
@@ -3567,7 +3567,9 @@ _elm_genlist_item_del_serious(Elm_Gen_Item *it)
3567 3567
3568 _elm_genlist_item_del_not_serious(it); 3568 _elm_genlist_item_del_not_serious(it);
3569 3569
3570 sd->items = eina_inlist_remove(sd->items, EINA_INLIST_GET(it)); 3570 //(it->walking == -1) means it's already removed from the list.
3571 if (it->walking != -1)
3572 sd->items = eina_inlist_remove(sd->items, EINA_INLIST_GET(it));
3571 if (it->tooltip.del_cb) 3573 if (it->tooltip.del_cb)
3572 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it); 3574 it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
3573 ELM_SAFE_FREE(it->long_timer, ecore_timer_del); 3575 ELM_SAFE_FREE(it->long_timer, ecore_timer_del);
@@ -5686,17 +5688,12 @@ _item_select(Elm_Gen_Item *it)
5686 evas_object_ref(obj); 5688 evas_object_ref(obj);
5687 it->walking++; 5689 it->walking++;
5688 if (it->func.func) it->func.func((void *)it->func.data, WIDGET(it), eo_it); 5690 if (it->func.func) it->func.func((void *)it->func.data, WIDGET(it), eo_it);
5691 // delete item if it's requested deletion in the above callbacks.
5692 if ((it->base)->on_deletion) goto item_deleted;
5689 evas_object_smart_callback_call(WIDGET(it), SIG_SELECTED, eo_it); 5693 evas_object_smart_callback_call(WIDGET(it), SIG_SELECTED, eo_it);
5690 it->walking--;
5691
5692 // delete item if it's requested deletion in the above callbacks. 5694 // delete item if it's requested deletion in the above callbacks.
5693 if ((it->base)->on_deletion) 5695 if ((it->base)->on_deletion) goto item_deleted;
5694 { 5696 it->walking--;
5695 _item_del(it);
5696 eo_del(eo_it);
5697 evas_object_unref(obj);
5698 return EINA_TRUE;
5699 }
5700 5697
5701 elm_object_item_focus_set(eo_it, EINA_TRUE); 5698 elm_object_item_focus_set(eo_it, EINA_TRUE);
5702 _elm_genlist_item_content_focus_set(it, ELM_FOCUS_PREVIOUS); 5699 _elm_genlist_item_content_focus_set(it, ELM_FOCUS_PREVIOUS);
@@ -5719,8 +5716,14 @@ _item_select(Elm_Gen_Item *it)
5719 } 5716 }
5720 5717
5721 evas_object_unref(obj); 5718 evas_object_unref(obj);
5722
5723 return EINA_FALSE; 5719 return EINA_FALSE;
5720
5721item_deleted:
5722 it->walking = -1; //This item was removed from it's item list.
5723 _item_del(it);
5724 eo_del(eo_it);
5725 evas_object_unref(obj);
5726 return EINA_TRUE;
5724} 5727}
5725 5728
5726EOLIAN static Evas_Object * 5729EOLIAN static Evas_Object *
@@ -5796,7 +5799,17 @@ EOLIAN static Eina_Bool
5796_elm_genlist_item_elm_widget_item_del_pre(Eo *eo_it EINA_UNUSED, 5799_elm_genlist_item_elm_widget_item_del_pre(Eo *eo_it EINA_UNUSED,
5797 Elm_Gen_Item *it) 5800 Elm_Gen_Item *it)
5798{ 5801{
5799 if (it->walking > 0) return EINA_FALSE; 5802 /* This item is getting removed from a callback that triggered in the
5803 _item_select(). Just pend removing. Because this will be removed right
5804 after in the _item_select(). So pratically, this item won't be
5805 dangled. */
5806 if (it->walking > 0)
5807 {
5808 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
5809 sd->items = eina_inlist_remove(sd->items, EINA_INLIST_GET(it));
5810 return EINA_FALSE;
5811 }
5812
5800 _item_del(it); 5813 _item_del(it);
5801 return EINA_TRUE; 5814 return EINA_TRUE;
5802} 5815}