diff options
| author | Albrecht Schlosser <albrechts.fltk@online.de> | 2010-02-07 21:14:35 +0000 |
|---|---|---|
| committer | Albrecht Schlosser <albrechts.fltk@online.de> | 2010-02-07 21:14:35 +0000 |
| commit | ee36ebc394cf2ff297302471467cd8e387e79423 (patch) | |
| tree | 2c562c77c544dce0d595e0aa1385612a87cc04a7 | |
| parent | ce7da76d6a219c5fc0a33f9c5b2701f3b47220d6 (diff) | |
Reverting previous change (optimization of Fl_Group::clear),
because fl_throw_focus and fl_fix_focus would send events
that could access deleted widgets. This must be fixed first.
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@7039 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
| -rw-r--r-- | CHANGES | 3 | ||||
| -rw-r--r-- | src/Fl_Group.cxx | 33 | ||||
| -rw-r--r-- | src/Fl_Scroll.cxx | 17 |
3 files changed, 18 insertions, 35 deletions
@@ -1,8 +1,5 @@ CHANGES IN FLTK 1.3.0 - - Optimized Fl_Group::clear() and Fl_Scroll::clear() as - discussed in fltk.development in "Fl_Group::clear SLOW!" - on Feb. 06/07, 2010 (no STR) - Replaced _WIN32 symbols that had come with UTF-8 and the new Fl_Table widget with WIN32 - Fixed a buffer overflow in fl_utf8from_mb() (STR #2279) diff --git a/src/Fl_Group.cxx b/src/Fl_Group.cxx index b84fe7e32..b42f1caf8 100644 --- a/src/Fl_Group.cxx +++ b/src/Fl_Group.cxx @@ -382,33 +382,24 @@ Fl_Group::Fl_Group(int X,int Y,int W,int H,const char *l) This method differs from the remove() method in that it affects all child widgets and deletes them from memory. */ -/* Implementation note: - This is optimized and does not remove children _during_ the loop. - However, deleting one child may also delete other children in the - group because a child widget can destroy other children in the same - group in its destructor or simply remove them from the parent group. - Because of this we must walk forwards through the array of children. - The allocated array_ of children is freed after the loop. -*/ void Fl_Group::clear() { savedfocus_ = 0; resizable_ = this; init_sizes(); // okay, now it is safe to destroy the children: - int i; - for (i=0; i<children_; i++) { // delete all children - Fl_Widget* o = child(i); // get child widget - if (o->parent()==this) { // should always be true - o->parent_ = 0; // reset child's parent - delete o; // delete it + while (children_) { + Fl_Widget* o = child(0); // *first* child widget + if (o->parent() == this) { // should always be true + remove(o); // remove child widget first + delete o; // then delete it + } else { // this should never happen ! +#ifdef DEBUG_CLEAR + printf ("Fl_Group::clear() widget:%p, parent: %p != this (%p)\n", + o, o->parent(), this); fflush(stdout); +#endif // DEBUG_CLEAR + remove(o); // remove it } } - // now free the array_ of children (if any) - if (children_ > 1) { - free((void*)array_); - } - array_ = 0; - children_ = 0; } /** @@ -478,8 +469,6 @@ void Fl_Group::add(Fl_Widget &o) {insert(o, children_);} This method differs from the clear() method in that it only affects a single widget and does not delete it from memory. */ -// Note: if you change this, be sure to do similar changes in -// Fl_Group::clear() as well, if applicable. void Fl_Group::remove(Fl_Widget &o) { if (!children_) return; int i = find(o); diff --git a/src/Fl_Scroll.cxx b/src/Fl_Scroll.cxx index 333c4892d..085d47bf0 100644 --- a/src/Fl_Scroll.cxx +++ b/src/Fl_Scroll.cxx @@ -32,16 +32,13 @@ /** Clear all but the scrollbars... */ void Fl_Scroll::clear() { - // Note: the scrollbars are removed from the group before - // calling Fl_Group::clear() to take advantage of the - // optimized widget removal. Finally they are added - // to the Fl_Scroll's group again. - // This is MUCH faster than removing each widget. - remove(scrollbar); - remove(hscrollbar); - Fl_Group::clear(); - add(hscrollbar); - add(scrollbar); + for (int i=children() - 1; i >= 0; i --) { + Fl_Widget* o = child(i); + if (o != &hscrollbar && o != &scrollbar) { + remove(o); + delete o; + } + } } /** Insure the scrollbars are the last children */ |
