From eabc91dd282043ea4aef8c2195d59c0d68445662 Mon Sep 17 00:00:00 2001 From: cpk Date: Fri, 9 Nov 2001 01:11:44 +0000 Subject: [PATCH] This should fix the "can't kill window" bugs. Well at least those I was able to reproduce. I've fixed the reference counting on borders, reference counts are now only modified where the references actually change. PLEASE: if we don't want to end up dead in the water with the reference counts, it'll be absolutely necessary to not just increment them here and there. When you store a pointer in a data structure somewhere, increment the counter. When you remove the pointer from the structure, decrement. Do NOT modify the counters anywhere else. Unfortunately I cannot enforce this in C. SVN revision: 5661 --- src/actions.c | 124 +++++++++++++++++++++++++++++++------------------- src/border.c | 11 +++-- src/debug.c | 39 ++++++++++------ 3 files changed, 108 insertions(+), 66 deletions(-) diff --git a/src/actions.c b/src/actions.c index 1eb72d8dc..2e6ff15f2 100644 --- a/src/actions.c +++ b/src/actions.c @@ -248,8 +248,13 @@ e_action_find(char *action, E_Action_Type act, int button, aa->button = a->button; e_strdup(aa->key, a->key); aa->modifiers = a->modifiers; + aa->action_impl = ap; + e_object_ref(E_OBJECT(ap)); + aa->object = object; + e_object_ref(object); + aa->started = 0; current_actions = evas_list_append(current_actions, aa); } @@ -274,11 +279,29 @@ e_action_cleanup(E_Action *a) e_keys_ungrab(a->key, (Ecore_Event_Key_Modifiers)a->modifiers, 0); } + /* Clean up the strings by simply freeing them ... */ IF_FREE(a->name); IF_FREE(a->action); IF_FREE(a->params); IF_FREE(a->key); + /* Cleanup action implementations and objects. These + we don't free directly, but just decrement their use counts. + */ + + if (a->action_impl) + { + e_object_unref(E_OBJECT(a->action_impl)); + a->action_impl = NULL; + } + + if (a->object) + { + e_object_unref(a->object); + a->object = NULL; + } + + /* Cleanup superclass. */ e_object_cleanup(E_OBJECT(a)); D_RETURN; @@ -310,14 +333,6 @@ e_action_start(char *action, E_Action_Type act, int button, } if (a->action_impl->func_start) { - E_Object *obj; - - if (a->object) - { - obj = a->object; - if (a->started) - e_object_ref(obj); - } a->action_impl->func_start(a->object, a, data, x, y, rx, ry); } } @@ -379,21 +394,13 @@ e_action_stop(char *action, E_Action_Type act, int button, ok = 1; if (ok) { - E_Object *obj; - - if (a->object) - { - obj = a->object; - e_object_unref(obj); - } a->action_impl->func_stop(a->object, a, data, x, y, rx, ry); a->started = 0; } } if (!a->started) { - current_actions = evas_list_remove(current_actions, a); - + current_actions = evas_list_remove(current_actions, a); e_object_unref(E_OBJECT(a)); goto again; } @@ -437,7 +444,10 @@ e_action_stop_by_object(E_Object *object, void *data, int x, int y, int rx, int { Evas_List l; + D_ENTER; + e_action_del_timer_object(object); + again: for (l = current_actions; l; l = l->next) { @@ -446,18 +456,14 @@ e_action_stop_by_object(E_Object *object, void *data, int x, int y, int rx, int a = l->data; if ((a->started) && (object == a->object)) { - E_Object *obj; - - if (a->object) - { - obj = a->object; - e_object_unref(obj); - } if (a->action_impl->func_stop) a->action_impl->func_stop(a->object, a, data, x, y, rx, ry); + a->started = 0; + current_actions = evas_list_remove(current_actions, a); e_object_unref(E_OBJECT(a)); + goto again; } } @@ -480,13 +486,6 @@ e_action_stop_by_type(char *action) if ((a->started) && (a->action_impl->func_stop) && (action) && (!strcmp(action, a->name))) { - E_Object *obj; - - if (a->object) - { - obj = a->object; - e_object_unref(obj); - } a->action_impl->func_stop(a->object, a, NULL, 0, 0, 0, 0); a->started = 0; } @@ -548,6 +547,7 @@ e_action_del_timer(E_Object *object, char *name) (at->name) && (!strcmp(at->name, name))) { + e_object_unref(at->object); ecore_del_event_timer(at->name); current_timers = evas_list_remove(current_timers, at); IF_FREE(at->name); @@ -568,6 +568,7 @@ e_action_add_timer(E_Object *object, char *name) at = NEW(E_Active_Action_Timer, 1); at->object = object; + e_object_ref(object); e_strdup(at->name, name); current_timers = evas_list_append(current_timers, at); @@ -589,6 +590,7 @@ e_action_del_timer_object(E_Object *object) at = l->data; if (at->object == object) { + e_object_unref(at->object); ecore_del_event_timer(at->name); current_timers = evas_list_remove(current_timers, at); IF_FREE(at->name); @@ -667,10 +669,18 @@ e_act_move_start (E_Object *object, E_Action *a, void *data, int x, int y, int r E_CONFIG_FLOAT_GET(cfg_guides_display_x, align_x); E_CONFIG_FLOAT_GET(cfg_guides_display_y, align_y); E_CONFIG_INT_GET(cfg_guides_display_location, display_loc); + b = (E_Border*) object; - if (!b) b = e_border_current_focused(); - if (!b) D_RETURN; - if (b->client.fixed) D_RETURN; + + if (!b) + b = e_border_current_focused(); + + if (!b) + D_RETURN; + + if (b->client.fixed) + D_RETURN; + if (move_mode >= E_GUIDES_BOX) b->hold_changes = 1; /* if non opaque */ b->mode.move = 1; @@ -678,6 +688,7 @@ e_act_move_start (E_Object *object, E_Action *a, void *data, int x, int y, int r b->current.requested.dy = 0; b->previous.requested.dx = 0; b->previous.requested.dy = 0; + { char buf[PATH_MAX]; @@ -710,9 +721,16 @@ e_act_move_stop (E_Object *object, E_Action *a, void *data, int x, int y, int r D_ENTER; b = (E_Border*) object; - if (!b) b = e_border_current_focused(); - if (!b) D_RETURN; - if (b->client.fixed) D_RETURN; + + if (!b) + b = e_border_current_focused(); + + if (!b) + D_RETURN; + + if (b->client.fixed) + D_RETURN; + b->hold_changes = 0; /* if non opaque */ b->current.requested.x = b->current.x; b->current.requested.y = b->current.y; @@ -746,9 +764,16 @@ e_act_move_cont (E_Object *object, E_Action *a, void *data, int x, int y, int r D_ENTER; b = (E_Border*) object; - if (!b) b = e_border_current_focused(); - if (!b) D_RETURN; - if (b->client.fixed) D_RETURN; + + if (!b) + b = e_border_current_focused(); + + if (!b) + D_RETURN; + + if (b->client.fixed) + D_RETURN; + b->current.requested.x += dx; b->current.requested.y += dy; if (dx != 0) b->current.requested.dx = dx; @@ -1301,10 +1326,11 @@ e_act_cb_shade(int val, void *data) b = data; if (!b) b = e_border_current_focused(); if (!b) D_RETURN; - if (b->client.is_desktop) D_RETURN; + if (b->client.is_desktop) + D_RETURN; + if (val == 0) { - e_object_ref(E_OBJECT(b)); t = ecore_get_time(); ecore_window_gravity_set(b->win.client, SouthWestGravity); e_action_del_timer(E_OBJECT(b), "shader"); @@ -1325,7 +1351,6 @@ e_act_cb_shade(int val, void *data) { e_action_del_timer(E_OBJECT(b), "shader"); ecore_window_gravity_reset(b->win.client); - e_object_ref(E_OBJECT(b)); } D_RETURN; @@ -1349,7 +1374,6 @@ e_act_cb_unshade(int val, void *data) if (b->client.is_desktop) D_RETURN; if (val == 0) { - e_object_ref(E_OBJECT(b)); t = ecore_get_time(); ecore_window_gravity_set(b->win.client, SouthWestGravity); e_action_del_timer(E_OBJECT(b), "shader"); @@ -1371,7 +1395,6 @@ e_act_cb_unshade(int val, void *data) { e_action_del_timer(E_OBJECT(b), "shader"); ecore_window_gravity_reset(b->win.client); - e_object_ref(E_OBJECT(b)); } D_RETURN; @@ -1387,9 +1410,14 @@ e_act_shade_start (E_Object *object, E_Action *a, void *data, int x, int y, int b = (E_Border*) object; if (!b) b = e_border_current_focused(); if (!b) D_RETURN; - if (b->client.is_desktop) D_RETURN; - if (b->current.shaded == 0) e_act_cb_shade(0, b); - else e_act_cb_unshade(0, b); + + if (b->client.is_desktop) + D_RETURN; + + if (b->current.shaded == 0) + e_act_cb_shade(0, b); + else + e_act_cb_unshade(0, b); D_RETURN; UN(a); diff --git a/src/border.c b/src/border.c index 1b365c6d9..a9dde4118 100644 --- a/src/border.c +++ b/src/border.c @@ -69,7 +69,7 @@ static void e_cb_border_move_resize(E_Border *b); static void e_cb_border_visibility(E_Border *b); static void e_border_poll(int val, void *data); -static void e_border_free(E_Border *b); +static void e_border_cleanup(E_Border *b); static int e_border_replay_query(Ecore_Event_Mouse_Down *ev) { @@ -600,6 +600,8 @@ e_mouse_down(Ecore_Event * ev) { Evas evas; int x, y; + + evas = b->evas.l; ecore_window_get_root_relative_location(evas_get_window(evas), @@ -1233,7 +1235,7 @@ e_border_poll(int val, void *data) } static void -e_border_free(E_Border *b) +e_border_cleanup(E_Border *b) { Evas_List l; @@ -1275,6 +1277,7 @@ e_border_free(E_Border *b) evas_list_free(b->grabs); } + /* Cleanup superclass. */ e_object_cleanup(E_OBJECT(b)); D_RETURN; @@ -1600,10 +1603,12 @@ e_border_new(void) b = NEW(E_Border, 1); ZERO(b, E_Border, 1); - e_object_init(E_OBJECT(b), (E_Cleanup_Func) e_border_free); + e_object_init(E_OBJECT(b), (E_Cleanup_Func) e_border_cleanup); e_observer_register_observee(E_OBSERVER(delayed_window_raise), E_OBSERVEE(b)); + D("BORDER CREATED AT %p\n", b); + b->current.requested.w = 1; b->current.requested.h = 1; b->client.min.w = 1; diff --git a/src/debug.c b/src/debug.c index 8f691e178..6ee375d0d 100644 --- a/src/debug.c +++ b/src/debug.c @@ -34,6 +34,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "debug.h" +static int do_print = 0; static int calldepth = 0; static void debug_whitespace(int calldepth); @@ -60,27 +61,35 @@ debug_print_info(void) void e_debug_enter(const char *file, const char *func) { - - calldepth++; - - printf("ENTER "); - debug_print_info(); - debug_whitespace(calldepth); - printf("%s, %s()\n", file, func); - fflush(stdout); + if (do_print) + { + calldepth++; + + printf("ENTER "); + debug_print_info(); + debug_whitespace(calldepth); + printf("%s, %s()\n", file, func); + fflush(stdout); + } } void e_debug_return(const char *file, const char *func) { - printf("RETURN "); - debug_print_info(); - debug_whitespace(calldepth); - printf("%s, %s()\n", file, func); - fflush(stdout); - - calldepth--; + if (do_print) + { + printf("RETURN "); + debug_print_info(); + debug_whitespace(calldepth); + printf("%s, %s()\n", file, func); + fflush(stdout); + + calldepth--; + + if (calldepth < 0) + printf("NEGATIVE!!!\n"); + } }