diff --git a/ChangeLog b/ChangeLog index 0918441632..4e41710dd2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2013-07-18 Mike Blumenkrantz + + * Ecore-Evas: fix usage of underlying X window after it has received a destroy event + 2013-07-22 Jiyoun Park * Evas: fix infinite loop if app use ecore evas image diff --git a/NEWS b/NEWS index 014928678c..caf8ee5afe 100644 --- a/NEWS +++ b/NEWS @@ -340,6 +340,7 @@ Fixes: * Ecore_Evas: - Fix build of Ecore_Evas_Extn on Solaris. - Fix many memory problems with ecore_evas_extn. + - Fix usage of underlying X window after it has received a destroy event * Ecore_X: - Fix possible memory corruption in xrandr EDID functions. - Fix x11 error sync issue with ecore_x_image_get(). diff --git a/src/modules/ecore_evas/engines/x/ecore_evas_x.c b/src/modules/ecore_evas/engines/x/ecore_evas_x.c index 260ae40265..d4733d5d0f 100644 --- a/src/modules/ecore_evas/engines/x/ecore_evas_x.c +++ b/src/modules/ecore_evas/engines/x/ecore_evas_x.c @@ -95,6 +95,7 @@ struct _Ecore_Evas_Engine_Data_X11 { void *visual; // store visual used to create pixmap unsigned long colormap; // store colormap used to create pixmap } pixmap; + Eina_Bool destroyed : 1; // X window has been deleted and cannot be used }; static Ecore_Evas_Interface_X11 * _ecore_evas_x_interface_x11_new(void); @@ -152,8 +153,9 @@ static void _ecore_evas_x_group_leader_unset(Ecore_Evas *ee) { Ecore_Evas_Engine_Data_X11 *edata = ee->engine.data; - ecore_x_window_prop_property_del(ee->prop.window, - ECORE_X_ATOM_WM_CLIENT_LEADER); + if (!edata->destroyed) + ecore_x_window_prop_property_del(ee->prop.window, + ECORE_X_ATOM_WM_CLIENT_LEADER); if (edata->leader == leader_win) { leader_ref--; @@ -224,8 +226,8 @@ _ecore_evas_x_sync_set(Ecore_Evas *ee) } edata->sync_counter = 0; } - if (sync_counter != edata->sync_counter) - ecore_x_e_comp_sync_counter_set(ee->prop.window, edata->sync_counter); + if ((!edata->destroyed) && (sync_counter != edata->sync_counter)) + ecore_x_e_comp_sync_counter_set(ee->prop.window, edata->sync_counter); } static void @@ -1259,12 +1261,15 @@ _ecore_evas_x_event_window_destroy(void *data EINA_UNUSED, int type EINA_UNUSED, { Ecore_Evas *ee; Ecore_X_Event_Window_Destroy *e; + Ecore_Evas_Engine_Data_X11 *edata; e = event; ee = ecore_event_window_match(e->win); if (!ee) return ECORE_CALLBACK_PASS_ON; /* pass on event */ if (e->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON; + edata = ee->engine.data; if (ee->func.fn_destroy) ee->func.fn_destroy(ee); + edata->destroyed = 1; _ecore_evas_x_sync_clear(ee); ecore_evas_free(ee); return ECORE_CALLBACK_PASS_ON; @@ -1649,7 +1654,8 @@ _ecore_evas_x_free(Ecore_Evas *ee) _ecore_evas_x_sync_set(ee); if (edata->win_shaped_input) ecore_x_window_free(edata->win_shaped_input); - if (ee->prop.window) ecore_x_window_free(ee->prop.window); + ecore_event_window_unregister(ee->prop.window); + if (ee->prop.window && (!edata->destroyed)) ecore_x_window_free(ee->prop.window); if (edata->pmap) ecore_x_pixmap_free(edata->pmap); if (edata->mask) ecore_x_pixmap_free(edata->mask); if (edata->gc) ecore_x_gc_free(edata->gc); @@ -1658,7 +1664,6 @@ _ecore_evas_x_free(Ecore_Evas *ee) edata->mask = 0; edata->gc = 0; edata->damages = NULL; - ecore_event_window_unregister(ee->prop.window); while (edata->win_extra) { Ecore_X_Window *winp;