summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRyuan Choi <ryuan.choi@gmail.com>2014-10-29 10:07:44 +0900
committerRyuan Choi <ryuan.choi@gmail.com>2014-10-29 12:57:31 +0900
commit3b392e004590ae930db4e4f145a8ed62252c2801 (patch)
treea9ab291cb1dec5c331607c9c128b798bcb9c7ed8
parent0281c063bfbd6e97bef5a28f846e84e8011d38eb (diff)
fileselector: Do not call _populate directly in APIs
Summary: User application may call some fileselector APIs to configure fileselector instance. And some of them may call _populate but only last request is needed. However, T1663 raises that last request might be rejected with expansion option and multiple requests of _populate. It's because expansion mode do not allow next _populate until previous one is finished. So, this patch fixes it via scheduling _populate instead of calling _populate() directly in APIs. @fix Maniphest Tasks: T1663
-rw-r--r--src/lib/elc_fileselector.c130
-rw-r--r--src/lib/elm_widget_fileselector.h5
2 files changed, 86 insertions, 49 deletions
diff --git a/src/lib/elc_fileselector.c b/src/lib/elc_fileselector.c
index e1145c473..b6e7d017a 100644
--- a/src/lib/elc_fileselector.c
+++ b/src/lib/elc_fileselector.c
@@ -736,29 +736,50 @@ static Eina_Bool
736_populate_do(void *data) 736_populate_do(void *data)
737{ 737{
738 struct sel_data *sdata = data; 738 struct sel_data *sdata = data;
739 const char *p;
740
741 ELM_FILESELECTOR_DATA_GET(sdata->fs, sd); 739 ELM_FILESELECTOR_DATA_GET(sdata->fs, sd);
742 740
743 /* keep a ref to path 'couse it will be destroyed by _populate */ 741 _populate(sdata->fs, sdata->path, NULL, sdata->selected);
744 p = eina_stringshare_add(sdata->path); 742 eina_stringshare_del(sdata->path);
745 _populate(sdata->fs, p, NULL, NULL); 743 eina_stringshare_del(sdata->selected);
746 eina_stringshare_del(p);
747 744
748 sd->populate_idler = NULL; 745 sd->populate_idler = NULL;
746
749 free(sdata); 747 free(sdata);
750 return ECORE_CALLBACK_CANCEL; 748 return ECORE_CALLBACK_CANCEL;
751} 749}
752 750
753static void 751static void
752_schedule_populate(Evas_Object *fs,
753 Elm_Fileselector_Data *sd,
754 Eina_Stringshare *path,
755 Eina_Stringshare *selected)
756{
757 struct sel_data *sdata;
758 sdata = malloc(sizeof(*sdata));
759 if (!sdata) return;
760
761 sdata->fs = fs;
762 sdata->path = path;
763 sdata->selected = selected;
764
765 if (sd->populate_idler)
766 {
767 struct sel_data *old_sdata;
768 old_sdata = ecore_idler_del(sd->populate_idler);
769 eina_stringshare_del(old_sdata->path);
770 eina_stringshare_del(old_sdata->selected);
771 free(old_sdata);
772 }
773 sd->populate_idler = ecore_idler_add(_populate_do, sdata);
774}
775
776static void
754_on_item_activated(void *data, 777_on_item_activated(void *data,
755 Evas_Object *obj EINA_UNUSED, 778 Evas_Object *obj EINA_UNUSED,
756 void *event_info) 779 void *event_info)
757{ 780{
758 //This event_info could be a list or gengrid item 781 //This event_info could be a list or gengrid item
759 Elm_Object_Item *it = event_info; 782 Elm_Object_Item *it = event_info;
760 struct sel_data *sdata;
761 void *old_sdata;
762 const char *path; 783 const char *path;
763 Eina_Bool is_dir; 784 Eina_Bool is_dir;
764 785
@@ -776,18 +797,7 @@ _on_item_activated(void *data,
776 797
777 if (!sd->double_tap_navigation) return; 798 if (!sd->double_tap_navigation) return;
778 799
779 sdata = malloc(sizeof(*sdata)); 800 _schedule_populate(data, sd, eina_stringshare_add(path), NULL);
780 if (!sdata) return;
781
782 sdata->fs = data;
783 sdata->path = path;
784
785 if (sd->populate_idler)
786 {
787 old_sdata = ecore_idler_del(sd->populate_idler);
788 free(old_sdata);
789 }
790 sd->populate_idler = ecore_idler_add(_populate_do, sdata);
791} 801}
792 802
793static void 803static void
@@ -825,8 +835,6 @@ _on_item_selected(void *data,
825{ 835{
826 //This event_info could be a list or gengrid item 836 //This event_info could be a list or gengrid item
827 Elm_Object_Item *it = event_info; 837 Elm_Object_Item *it = event_info;
828 struct sel_data *sdata;
829 void *old_sdata;
830 const char *path; 838 const char *path;
831 char *parent_path; 839 char *parent_path;
832 Eina_Bool is_dir; 840 Eina_Bool is_dir;
@@ -904,18 +912,7 @@ _on_item_selected(void *data,
904 912
905 if (sd->double_tap_navigation) return; 913 if (sd->double_tap_navigation) return;
906 914
907 sdata = malloc(sizeof(*sdata)); 915 _schedule_populate(data, sd, eina_stringshare_add(path), NULL);
908 if (!sdata) return;
909
910 sdata->fs = data;
911 sdata->path = path;
912
913 if (sd->populate_idler)
914 {
915 old_sdata = ecore_idler_del(sd->populate_idler);
916 free(old_sdata);
917 }
918 sd->populate_idler = ecore_idler_add(_populate_do, sdata);
919} 916}
920 917
921static void 918static void
@@ -1605,7 +1602,11 @@ _elm_fileselector_elm_interface_fileselector_folder_only_set(Eo *obj, Elm_Filese
1605 if (sd->only_folder == only) return; 1602 if (sd->only_folder == only) return;
1606 1603
1607 sd->only_folder = !!only; 1604 sd->only_folder = !!only;
1608 if (sd->path) _populate(obj, sd->path, NULL, NULL); 1605 if (sd->path)
1606 {
1607 eina_stringshare_ref(sd->path);
1608 _schedule_populate(obj, sd, sd->path, NULL);
1609 }
1609} 1610}
1610 1611
1611EAPI Eina_Bool 1612EAPI Eina_Bool
@@ -1676,7 +1677,11 @@ _elm_fileselector_elm_interface_fileselector_expandable_set(Eo *obj, Elm_Filesel
1676{ 1677{
1677 sd->expand = !!expand; 1678 sd->expand = !!expand;
1678 1679
1679 if (sd->path) _populate(obj, sd->path, NULL, NULL); 1680 if (sd->path)
1681 {
1682 eina_stringshare_ref(sd->path);
1683 _schedule_populate(obj, sd, sd->path, NULL);
1684 }
1680} 1685}
1681 1686
1682EAPI Eina_Bool 1687EAPI Eina_Bool
@@ -1703,12 +1708,12 @@ elm_fileselector_path_set(Evas_Object *obj,
1703} 1708}
1704 1709
1705EOLIAN static void 1710EOLIAN static void
1706_elm_fileselector_elm_interface_fileselector_path_set(Eo *obj, Elm_Fileselector_Data *sd EINA_UNUSED, const char *_path) 1711_elm_fileselector_elm_interface_fileselector_path_set(Eo *obj, Elm_Fileselector_Data *sd, const char *_path)
1707{ 1712{
1708 char *path; 1713 char *path;
1709 1714
1710 path = ecore_file_realpath(_path); 1715 path = ecore_file_realpath(_path);
1711 _populate(obj, path, NULL, NULL); 1716 _schedule_populate(obj, sd, eina_stringshare_add(path), NULL);
1712 free(path); 1717 free(path);
1713} 1718}
1714 1719
@@ -1763,7 +1768,11 @@ _elm_fileselector_elm_interface_fileselector_mode_set(Eo *obj, Elm_Fileselector_
1763 1768
1764 sd->mode = mode; 1769 sd->mode = mode;
1765 1770
1766 _populate(obj, sd->path, NULL, NULL); 1771 if (sd->path)
1772 {
1773 eina_stringshare_ref(sd->path);
1774 _schedule_populate(obj, sd, sd->path, NULL);
1775 }
1767} 1776}
1768 1777
1769EAPI Elm_Fileselector_Mode 1778EAPI Elm_Fileselector_Mode
@@ -1901,7 +1910,8 @@ _elm_fileselector_elm_interface_fileselector_selected_set(Eo *obj, Elm_Fileselec
1901 1910
1902 path = ecore_file_realpath(_path); 1911 path = ecore_file_realpath(_path);
1903 1912
1904 if (ecore_file_is_dir(path)) _populate(obj, path, NULL, NULL); 1913 if (ecore_file_is_dir(path))
1914 _schedule_populate(obj, sd, eina_stringshare_add(path), NULL);
1905 else 1915 else
1906 { 1916 {
1907 if (!ecore_file_exists(path)) 1917 if (!ecore_file_exists(path))
@@ -1911,8 +1921,9 @@ _elm_fileselector_elm_interface_fileselector_selected_set(Eo *obj, Elm_Fileselec
1911 } 1921 }
1912 1922
1913 dir = ecore_file_dir_get(path); 1923 dir = ecore_file_dir_get(path);
1914 _populate(obj, dir, NULL, path);
1915 eina_stringshare_replace(&sd->selection, path); 1924 eina_stringshare_replace(&sd->selection, path);
1925 eina_stringshare_ref(sd->selection);
1926 _schedule_populate(obj, sd, eina_stringshare_add(dir), sd->selection);
1916 free(dir); 1927 free(dir);
1917 } 1928 }
1918 1929
@@ -2014,7 +2025,11 @@ _elm_fileselector_elm_interface_fileselector_mime_types_filter_append(Eo *obj, E
2014 2025
2015 sd->filter_list = eina_list_append(sd->filter_list, ff); 2026 sd->filter_list = eina_list_append(sd->filter_list, ff);
2016 2027
2017 _populate(obj, sd->path, NULL, NULL); 2028 if (sd->path)
2029 {
2030 eina_stringshare_ref(sd->path);
2031 _schedule_populate(obj, sd, sd->path, NULL);
2032 }
2018 2033
2019 if (need_theme) 2034 if (need_theme)
2020 eo_do(obj, elm_obj_widget_theme_apply()); 2035 eo_do(obj, elm_obj_widget_theme_apply());
@@ -2057,7 +2072,11 @@ _elm_fileselector_elm_interface_fileselector_custom_filter_append(Eo *obj, Elm_F
2057 2072
2058 sd->filter_list = eina_list_append(sd->filter_list, ff); 2073 sd->filter_list = eina_list_append(sd->filter_list, ff);
2059 2074
2060 _populate(obj, sd->path, NULL, NULL); 2075 if (sd->path)
2076 {
2077 eina_stringshare_ref(sd->path);
2078 _schedule_populate(obj, sd, sd->path, NULL);
2079 }
2061 2080
2062 if (need_theme) 2081 if (need_theme)
2063 eo_do(obj, elm_obj_widget_theme_apply()); 2082 eo_do(obj, elm_obj_widget_theme_apply());
@@ -2094,7 +2113,11 @@ _elm_fileselector_elm_interface_fileselector_filters_clear(Eo *obj, Elm_Filesele
2094 2113
2095 ELM_SAFE_FREE(sd->filter_hoversel, evas_object_del); 2114 ELM_SAFE_FREE(sd->filter_hoversel, evas_object_del);
2096 2115
2097 _populate(obj, sd->path, NULL, NULL); 2116 if (sd->path)
2117 {
2118 eina_stringshare_ref(sd->path);
2119 _schedule_populate(obj, sd, sd->path, NULL);
2120 }
2098} 2121}
2099 2122
2100EAPI void 2123EAPI void
@@ -2112,7 +2135,12 @@ _elm_fileselector_elm_interface_fileselector_hidden_visible_set(Eo *obj EINA_UNU
2112 sd->hidden_visible = visible; 2135 sd->hidden_visible = visible;
2113 2136
2114 _clear_selections(sd, NULL); 2137 _clear_selections(sd, NULL);
2115 _populate(obj, sd->path, NULL, NULL); 2138
2139 if (sd->path)
2140 {
2141 eina_stringshare_ref(sd->path);
2142 _schedule_populate(obj, sd, sd->path, NULL);
2143 }
2116} 2144}
2117 2145
2118EAPI Eina_Bool 2146EAPI Eina_Bool
@@ -2153,7 +2181,11 @@ _elm_fileselector_elm_interface_fileselector_thumbnail_size_set(Eo *obj EINA_UNU
2153 if (sd->mode == ELM_FILESELECTOR_GRID) 2181 if (sd->mode == ELM_FILESELECTOR_GRID)
2154 elm_gengrid_item_size_set(sd->files_view, w + GENGRID_PADDING, h + GENGRID_PADDING); 2182 elm_gengrid_item_size_set(sd->files_view, w + GENGRID_PADDING, h + GENGRID_PADDING);
2155 2183
2156 _populate(obj, sd->path, NULL, NULL); 2184 if (sd->path)
2185 {
2186 eina_stringshare_ref(sd->path);
2187 _schedule_populate(obj, sd, sd->path, NULL);
2188 }
2157} 2189}
2158 2190
2159EAPI void 2191EAPI void
@@ -2216,7 +2248,11 @@ _elm_fileselector_elm_interface_fileselector_sort_method_set(Eo *obj EINA_UNUSED
2216 sd->sort_method = strcoll; 2248 sd->sort_method = strcoll;
2217 } 2249 }
2218 2250
2219 _populate(obj, sd->path, NULL, NULL); 2251 if (sd->path)
2252 {
2253 eina_stringshare_ref(sd->path);
2254 _schedule_populate(obj, sd, sd->path, NULL);
2255 }
2220} 2256}
2221 2257
2222EAPI Elm_Fileselector_Sort 2258EAPI Elm_Fileselector_Sort
diff --git a/src/lib/elm_widget_fileselector.h b/src/lib/elm_widget_fileselector.h
index 08c0f697f..e9b0f0390 100644
--- a/src/lib/elm_widget_fileselector.h
+++ b/src/lib/elm_widget_fileselector.h
@@ -84,8 +84,9 @@ struct _Elm_Fileselector_Data
84 84
85struct sel_data 85struct sel_data
86{ 86{
87 Evas_Object *fs; 87 Evas_Object *fs;
88 const char *path; 88 Eina_Stringshare *path;
89 Eina_Stringshare *selected;
89}; 90};
90 91
91typedef struct _Listing_Request Listing_Request; 92typedef struct _Listing_Request Listing_Request;