summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChunEon Park <hermet@hermet.pe.kr>2015-01-15 16:12:37 +0900
committerChunEon Park <hermet@hermet.pe.kr>2015-01-15 16:12:37 +0900
commit8ae155955e0e2774613373ae42259e1a4cac135c (patch)
tree9b002109ad14cd5334d2e0c893349dfddd9caa1b
parente5b56cfb392b153e0bc3354f468c0a0af5218818 (diff)
genlist: fix the access of the invalid items.
still, there were case item or genlist is cleared in the user callback. don't access the cleared items if they are requested deletion.
-rw-r--r--src/lib/elm_genlist.c47
1 files changed, 33 insertions, 14 deletions
diff --git a/src/lib/elm_genlist.c b/src/lib/elm_genlist.c
index 64fc0d78c..6caa05ef7 100644
--- a/src/lib/elm_genlist.c
+++ b/src/lib/elm_genlist.c
@@ -142,7 +142,7 @@ static const char SIGNAL_GROUP_LAST[] = "elm,state,group,last";
142static const char SIGNAL_GROUP_MIDDLE[] = "elm,state,group,middle"; 142static const char SIGNAL_GROUP_MIDDLE[] = "elm,state,group,middle";
143 143
144static void _item_unrealize(Elm_Gen_Item *it); 144static void _item_unrealize(Elm_Gen_Item *it);
145static void _item_select(Elm_Gen_Item *it); 145static Eina_Bool _item_select(Elm_Gen_Item *it);
146static Eina_Bool _key_action_move(Evas_Object *obj, const char *params); 146static Eina_Bool _key_action_move(Evas_Object *obj, const char *params);
147static Eina_Bool _key_action_select(Evas_Object *obj, const char *params); 147static Eina_Bool _key_action_select(Evas_Object *obj, const char *params);
148static Eina_Bool _key_action_escape(Evas_Object *obj, const char *params); 148static Eina_Bool _key_action_escape(Evas_Object *obj, const char *params);
@@ -4781,6 +4781,8 @@ _item_mouse_up_cb(void *data,
4781 4781
4782 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return; 4782 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
4783 4783
4784 evas_object_ref(sd->obj);
4785
4784 if (sd->multi && 4786 if (sd->multi &&
4785 ((sd->multi_select_mode != ELM_OBJECT_MULTI_SELECT_MODE_WITH_CONTROL) || 4787 ((sd->multi_select_mode != ELM_OBJECT_MULTI_SELECT_MODE_WITH_CONTROL) ||
4786 (evas_key_modifier_is_set(ev->modifiers, "Control")))) 4788 (evas_key_modifier_is_set(ev->modifiers, "Control"))))
@@ -4788,7 +4790,7 @@ _item_mouse_up_cb(void *data,
4788 if (!it->selected) 4790 if (!it->selected)
4789 { 4791 {
4790 _item_highlight(it); 4792 _item_highlight(it);
4791 _item_select(it); 4793 if (_item_select(it)) goto deleted;
4792 } 4794 }
4793 else 4795 else
4794 _item_unselect(it); 4796 _item_unselect(it);
@@ -4817,11 +4819,14 @@ _item_mouse_up_cb(void *data,
4817 } 4819 }
4818 } 4820 }
4819 _item_highlight(it); 4821 _item_highlight(it);
4820 _item_select(it); 4822 if (_item_select(it)) goto deleted;
4821 } 4823 }
4822 4824
4823 if (sd->focused_item != EO_OBJ(it)) 4825 if (sd->focused_item != EO_OBJ(it))
4824 elm_object_item_focus_set(EO_OBJ(it), EINA_TRUE); 4826 elm_object_item_focus_set(EO_OBJ(it), EINA_TRUE);
4827
4828deleted:
4829 evas_object_unref(sd->obj);
4825} 4830}
4826 4831
4827static void 4832static void
@@ -5594,6 +5599,7 @@ static void
5594_internal_elm_genlist_clear(Evas_Object *obj) 5599_internal_elm_genlist_clear(Evas_Object *obj)
5595{ 5600{
5596 ELM_GENLIST_DATA_GET(obj, sd); 5601 ELM_GENLIST_DATA_GET(obj, sd);
5602 Eina_Inlist *l;
5597 Elm_Gen_Item *it; 5603 Elm_Gen_Item *it;
5598 5604
5599 _elm_genlist_item_unfocused(sd->focused_item); 5605 _elm_genlist_item_unfocused(sd->focused_item);
@@ -5602,13 +5608,10 @@ _internal_elm_genlist_clear(Evas_Object *obj)
5602 ELM_SAFE_FREE(sd->state, eina_inlist_sorted_state_free); 5608 ELM_SAFE_FREE(sd->state, eina_inlist_sorted_state_free);
5603 5609
5604 evas_event_freeze(evas_object_evas_get(sd->obj)); 5610 evas_event_freeze(evas_object_evas_get(sd->obj));
5605 // Do not use EINA_INLIST_FOREACH or EINA_INLIST_FOREACH_SAFE 5611
5606 // because sd->items can be modified inside elm_widget_item_del() 5612 EINA_INLIST_FOREACH_SAFE(sd->items, l, it)
5607 while (sd->items) 5613 eo_do(EO_OBJ(it), elm_wdg_item_del());
5608 { 5614
5609 it = EINA_INLIST_CONTAINER_GET(sd->items->last, Elm_Gen_Item);
5610 eo_do(EO_OBJ(it), elm_wdg_item_del());
5611 }
5612 sd->pan_changed = EINA_TRUE; 5615 sd->pan_changed = EINA_TRUE;
5613 if (!sd->queue) 5616 if (!sd->queue)
5614 { 5617 {
@@ -5645,18 +5648,19 @@ _internal_elm_genlist_clear(Evas_Object *obj)
5645 evas_event_thaw_eval(evas_object_evas_get(sd->obj)); 5648 evas_event_thaw_eval(evas_object_evas_get(sd->obj));
5646} 5649}
5647 5650
5648static void 5651/* Return EINA_TRUE if the item is deleted in this function */
5652static Eina_Bool
5649_item_select(Elm_Gen_Item *it) 5653_item_select(Elm_Gen_Item *it)
5650{ 5654{
5651 Evas_Object *obj = WIDGET(it); 5655 Evas_Object *obj = WIDGET(it);
5652 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd); 5656 ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
5653 Elm_Object_Item *eo_it = EO_OBJ(it); 5657 Elm_Object_Item *eo_it = EO_OBJ(it);
5654 5658
5655 if (eo_do(eo_it, elm_wdg_item_disabled_get())) return; 5659 if (eo_do(eo_it, elm_wdg_item_disabled_get())) return EINA_FALSE;
5656 if (_is_no_select(it) || (it->decorate_it_set)) return; 5660 if (_is_no_select(it) || (it->decorate_it_set)) return EINA_FALSE;
5657 if ((sd->select_mode != ELM_OBJECT_SELECT_MODE_ALWAYS) && 5661 if ((sd->select_mode != ELM_OBJECT_SELECT_MODE_ALWAYS) &&
5658 (it->select_mode != ELM_OBJECT_SELECT_MODE_ALWAYS) && it->selected) 5662 (it->select_mode != ELM_OBJECT_SELECT_MODE_ALWAYS) && it->selected)
5659 return; 5663 return EINA_FALSE;
5660 5664
5661 if (!sd->multi) 5665 if (!sd->multi)
5662 { 5666 {
@@ -5677,8 +5681,20 @@ _item_select(Elm_Gen_Item *it)
5677 } 5681 }
5678 5682
5679 evas_object_ref(obj); 5683 evas_object_ref(obj);
5684 it->walking++;
5680 if (it->func.func) it->func.func((void *)it->func.data, WIDGET(it), eo_it); 5685 if (it->func.func) it->func.func((void *)it->func.data, WIDGET(it), eo_it);
5681 evas_object_smart_callback_call(WIDGET(it), SIG_SELECTED, eo_it); 5686 evas_object_smart_callback_call(WIDGET(it), SIG_SELECTED, eo_it);
5687 it->walking--;
5688
5689 // delete item if it's requested deletion in the above callbacks.
5690 if ((it->base)->on_deletion)
5691 {
5692 _item_del(it);
5693 eo_del(eo_it);
5694 evas_object_unref(obj);
5695 return EINA_TRUE;
5696 }
5697
5682 elm_object_item_focus_set(eo_it, EINA_TRUE); 5698 elm_object_item_focus_set(eo_it, EINA_TRUE);
5683 _elm_genlist_item_content_focus_set(it, ELM_FOCUS_PREVIOUS); 5699 _elm_genlist_item_content_focus_set(it, ELM_FOCUS_PREVIOUS);
5684 5700
@@ -5700,6 +5716,8 @@ _item_select(Elm_Gen_Item *it)
5700 } 5716 }
5701 5717
5702 evas_object_unref(obj); 5718 evas_object_unref(obj);
5719
5720 return EINA_FALSE;
5703} 5721}
5704 5722
5705EOLIAN static Evas_Object * 5723EOLIAN static Evas_Object *
@@ -5775,6 +5793,7 @@ EOLIAN static Eina_Bool
5775_elm_genlist_item_elm_widget_item_del_pre(Eo *eo_it EINA_UNUSED, 5793_elm_genlist_item_elm_widget_item_del_pre(Eo *eo_it EINA_UNUSED,
5776 Elm_Gen_Item *it) 5794 Elm_Gen_Item *it)
5777{ 5795{
5796 if (it->walking > 0) return EINA_FALSE;
5778 _item_del(it); 5797 _item_del(it);
5779 return EINA_TRUE; 5798 return EINA_TRUE;
5780} 5799}