Browse Source

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
pull/49/head
Albrecht Schlosser 16 years ago
parent
commit
ee36ebc394
  1. 3
      CHANGES
  2. 33
      src/Fl_Group.cxx
  3. 17
      src/Fl_Scroll.cxx

3
CHANGES

@ -1,8 +1,5 @@ @@ -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)

33
src/Fl_Group.cxx

@ -382,33 +382,24 @@ Fl_Group::Fl_Group(int X,int Y,int W,int H,const char *l) @@ -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_);} @@ -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);

17
src/Fl_Scroll.cxx

@ -32,16 +32,13 @@ @@ -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 */

Loading…
Cancel
Save