[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[E-devel] [PATCH] Shelf Delete Segv.



The patch attached fixes an issue where you can open multiple shelf
delete confirmation dialog boxes for the same shelf and clicking Yes to
more than one results in a segv. This also occurs if you spawn the
confirm dialogs using diff. methods. 

In order to fix this patch, e_confirm_dialog_show now has a callback for
when it is closed, whether yes/no or some other method is used to close
the box.

metrics
Index: src/bin/e_confirm_dialog.c
===================================================================
RCS file: /var/cvs/e/e17/apps/e/src/bin/e_confirm_dialog.c,v
retrieving revision 1.2
diff -u -r1.2 e_confirm_dialog.c
--- src/bin/e_confirm_dialog.c	14 Aug 2006 15:22:44 -0000	1.2
+++ src/bin/e_confirm_dialog.c	23 Oct 2006 02:22:47 -0000
@@ -18,6 +18,12 @@
 	void *data;
 	void (*func)(void *data);
      } no;
+
+   struct
+     {
+	void *data;
+	void (*func)(void *data);
+     } del;
    E_Dialog *dia;
 };
 
@@ -32,7 +38,7 @@
 EAPI void 
 e_confirm_dialog_show(const char *title, const char *icon, const char *text,
 		      const char *button_text, const char *button2_text, void (*func)(void *data),
-		      void (*func2)(void *data), void *data, void *data2)
+		      void (*func2)(void *data), void *data, void *data2, void (*del_func)(void *data), void *del_data)
 {
    E_Confirm_Dialog *cd; 
    E_Dialog *dia;
@@ -42,6 +48,8 @@
    cd->yes.data = data;
    cd->no.func = func2;
    cd->no.data = data2;
+   cd->del.func = del_func;
+   cd->del.data = del_data;
 
    dia = e_dialog_new(e_container_current_get(e_manager_current_get()), "E", "_confirm_dialog");
    if (!dia)
@@ -94,6 +102,7 @@
    dia = win->data;
    cd = dia->data;
 
+   if (cd->del.func) cd->del.func(cd->del.data);
    e_object_del(E_OBJECT(dia));
    free(cd);
 }
Index: src/bin/e_confirm_dialog.h
===================================================================
RCS file: /var/cvs/e/e17/apps/e/src/bin/e_confirm_dialog.h,v
retrieving revision 1.1
diff -u -r1.1 e_confirm_dialog.h
--- src/bin/e_confirm_dialog.h	22 May 2006 20:28:32 -0000	1.1
+++ src/bin/e_confirm_dialog.h	23 Oct 2006 02:22:47 -0000
@@ -18,7 +18,7 @@
  * data - the pointer passed to func
  * data2 - the pointer passed to func2
  */
-EAPI void e_confirm_dialog_show(const char *title, const char *icon, const char *text, const char *button_text, const char *button2_text, void (*func)(void *data), void (*func2)(void *data), void *data, void *data2);
+EAPI void e_confirm_dialog_show(const char *title, const char *icon, const char *text, const char *button_text, const char *button2_text, void (*func)(void *data), void (*func2)(void *data), void *data, void *data2, void (*del_func)(void *data), void * del_data);
 
 #endif
 #endif
Index: src/bin/e_int_config_shelf.c
===================================================================
RCS file: /var/cvs/e/e17/apps/e/src/bin/e_int_config_shelf.c,v
retrieving revision 1.25
diff -u -r1.25 e_int_config_shelf.c
--- src/bin/e_int_config_shelf.c	8 Oct 2006 08:04:17 -0000	1.25
+++ src/bin/e_int_config_shelf.c	23 Oct 2006 02:22:53 -0000
@@ -8,6 +8,7 @@
 static void _cb_add(void *data, void *data2);
 static void _cb_delete(void *data, void *data2);
 static void _cb_dialog_yes(void *data);
+static void _cb_dialog_destroy(void *data);
 static void _cb_config(void *data, void *data2);
 
 struct _E_Config_Dialog_Data 
@@ -19,6 +20,14 @@
    char *cur_shelf;
 };
 
+typedef struct _Shelf_Del_Confirm_Data Shelf_Del_Confirm_Data;
+struct _Shelf_Del_Confirm_Data
+{
+    E_Config_Dialog_Data *cfdata;
+    E_Shelf *es;
+};
+    
+
 EAPI E_Config_Dialog *
 e_int_config_shelf(E_Container *con) 
 {
@@ -229,38 +238,51 @@
 static void 
 _cb_delete(void *data, void *data2) 
 {
-   E_Config_Dialog_Data *cfdata;
+   Shelf_Del_Confirm_Data *d;
    char buf[4096];
    
-   cfdata = data;
-   if (!cfdata) return;
-   if (!cfdata->cur_shelf) return;
+   d = E_NEW(Shelf_Del_Confirm_Data, 1);
+   if (!d) return;
+   d->cfdata = data;
+   if (!d->cfdata) return;
+   if (!d->cfdata->cur_shelf) return;
+   d->es = evas_list_nth(e_shelf_list(), e_widget_ilist_selected_get(d->cfdata->o_list));
+   if (!d->es) return;
+   e_object_ref(E_OBJECT(d->es));
    
    snprintf(buf, sizeof(buf), _("You requested to delete \"%s\".<br><br>"
 				"Are you sure you want to delete this shelf?"),
-	    cfdata->cur_shelf);
+           d->cfdata->cur_shelf);
    
    e_confirm_dialog_show(_("Are you sure you want to delete this shelf?"), 
-			   "enlightenment/exit", buf, NULL, NULL, _cb_dialog_yes, NULL, cfdata, NULL);
+			   "enlightenment/exit", buf, NULL, NULL, _cb_dialog_yes, NULL, d, NULL, 
+                           _cb_dialog_destroy, d);
 }
 
 static void 
 _cb_dialog_yes(void *data) 
 {
-   E_Config_Dialog_Data *cfdata;
+   Shelf_Del_Confirm_Data *d;
    E_Shelf *es;
    
-   cfdata = data;
-   if (!cfdata) return;
+   d = data;
+   if (!data) return;
 
-   es = evas_list_nth(e_shelf_list(), e_widget_ilist_selected_get(cfdata->o_list));
-   if (!es) return;
-
-   e_shelf_unsave(es);
-   e_object_del(E_OBJECT(es));
+   if (e_object_is_del(E_OBJECT(d->es))) return;
+   e_shelf_unsave(d->es);
+   e_object_del(E_OBJECT(d->es));
    e_config_save_queue();
+}
 
-   _ilist_fill(cfdata);
+static void
+_cb_dialog_destroy(void *data)
+{
+   Shelf_Del_Confirm_Data *d;
+
+   d = data;
+   e_object_unref(E_OBJECT(d->es));
+   _ilist_fill(d->cfdata);
+   E_FREE(d);
 }
 
 static void 
Index: src/bin/e_shelf.c
===================================================================
RCS file: /var/cvs/e/e17/apps/e/src/bin/e_shelf.c,v
retrieving revision 1.42
diff -u -r1.42 e_shelf.c
--- src/bin/e_shelf.c	16 Oct 2006 10:40:10 -0000	1.42
+++ src/bin/e_shelf.c	23 Oct 2006 02:23:02 -0000
@@ -12,6 +12,7 @@
 static void _e_shelf_cb_menu_edit(void *data, E_Menu *m, E_Menu_Item *mi);
 static void _e_shelf_cb_menu_contents(void *data, E_Menu *m, E_Menu_Item *mi);
 static void _e_shelf_cb_confirm_dialog_yes(void *data);
+static void _e_shelf_cb_confirm_dialog_no(void *data);
 static void _e_shelf_cb_menu_delete(void *data, E_Menu *m, E_Menu_Item *mi);
 static void _e_shelf_menu_append(E_Shelf *es, E_Menu *mn);
 static void _e_shelf_cb_menu_items_append(void *data, E_Menu *mn);
@@ -22,6 +23,7 @@
 static int  _e_shelf_cb_id_sort(void *data1, void *data2);
 
 static Evas_List *shelves = NULL;
+static Evas_Bool _del_confirm_active = 0;
 
 /* externally accessible functions */
 EAPI int
@@ -46,7 +48,9 @@
 	E_Shelf *es;
 
 	es = shelves->data;
+	printf("Before e_object_del\n");
 	e_object_del(E_OBJECT(es));
+	printf("After e_object_del\n");
      }
 
    for (l = e_config->shelves; l; l = l->next)
@@ -866,6 +870,15 @@
 }
 
 static void
+_e_shelf_cb_confirm_dialog_destroy(void *data)
+{
+   E_Shelf *es;
+
+   es = data;
+   e_object_unref(E_OBJECT(es));
+}
+
+static void
 _e_shelf_cb_confirm_dialog_yes(void *data)
 {
    E_Config_Shelf *cfg;
@@ -873,6 +886,7 @@
 
    es = data;
    cfg = es->cfg;
+   if (e_object_is_del(E_OBJECT(es))) return;
    e_object_del(E_OBJECT(es));
    e_config->shelves = evas_list_remove(e_config->shelves, cfg);
    if (cfg->name) evas_stringshare_del(cfg->name);
@@ -886,11 +900,14 @@
 static void
 _e_shelf_cb_menu_delete(void *data, E_Menu *m, E_Menu_Item *mi)
 {
+   E_Shelf * es = data;
+   e_object_ref(E_OBJECT(es));
    e_confirm_dialog_show(_("Are you sure you want to delete this shelf?"), "enlightenment/e",
 			 _("You requested to delete this shelf.<br>"
 			      "<br>"
 			      "Are you sure you want to delete it?"), NULL, NULL,
-			 _e_shelf_cb_confirm_dialog_yes, NULL, data, NULL);
+			 _e_shelf_cb_confirm_dialog_yes, NULL, data, NULL, 
+			 _e_shelf_cb_confirm_dialog_destroy, data);
 }
 
 static void
Index: src/modules/ibar/e_mod_config.c
===================================================================
RCS file: /var/cvs/e/e17/apps/e/src/modules/ibar/e_mod_config.c,v
retrieving revision 1.31
diff -u -r1.31 e_mod_config.c
--- src/modules/ibar/e_mod_config.c	22 Sep 2006 19:55:11 -0000	1.31
+++ src/modules/ibar/e_mod_config.c	23 Oct 2006 02:23:07 -0000
@@ -175,7 +175,7 @@
 	    cfdata->dir);
    
    e_confirm_dialog_show(_("Are you sure you want to delete this bar source?"),
-			 "enlightenment/exit", buf, NULL, NULL, _cb_confirm_dialog_yes, NULL, cfdata, NULL);
+			 "enlightenment/exit", buf, NULL, NULL, _cb_confirm_dialog_yes, NULL, cfdata, NULL, NULL, NULL);
 }
 
 static void