Andreas Ekstrand wrote:
Albrecht,

This solution was sure fast enough (61ms compared to previous 1500ms), at least 
normally. In some cases though, the fix_focus still causes problems, even 
slower than before, actually over 60 seconds for one clear in debug mode.

I middle-click on a button in my Fl_Scroll and the clear method is called 
before recreation of the scroll contents. Maybe because the middle-click it 
seems like the fix_focus problems appears again, even more serious. Any idea 
why?

Not really, but I can reproduce this now with a slightly modified test
program. There are two different, but related problems with this:

Problem #1:
If you click a button inside the Fl_Scroll and call any version
of clear(), then this deletes the button in its own callback. This
is problematic, and the usual way to avoid this (since FLTK 1.1.5)
is to use Fl::delete_widget() to do such things. Unfortunately your
use case doesn't qualify for this unless you accept to also delete
the Fl_Scroll itself and recreate it as well. Then you could try
to remove() the Fl_Scroll from its group (or window), call
Fl::delete_widget(scroll), and finally create and add a new
Fl_Scroll widget with its new contents.

That said, my intention is to make clear() work in this scenario
as well, i.e. to allow a widget to delete itself in its callback,
but this needs more testing.

I have a patch that removes some bad behavior (crashes in some
cases), but this one alone doesn't solve your problem.

To get an impression of the problems with this, you can read
STR #1306: <http://www.fltk.org/str.php?L1306> . It's not yet
complete, but the patch mentioned above is one of mayn that need
to be tested and committed yet.

Anyway, I append Fl_Button.patch. This might help you prevent
a crash, but doesn't solve ...

Problem #2:

The time consuming problem is now probably the fix_focus stuff,
but only if you click a button inside the Fl_Scroll. As I wrote
before, this is probably not very useful, because this sends events
to widgets that are about to be deleted anyway but do still exist
as children in the group. This is at least in the order of n**2
where n = children(), and that make it scale so dramatically with
your number of children.

I can issue the same clear and recreation sequence with another button without 
clicking in the Fl_Scroll. This doesn't cause the same problem, so I guess the 
event sent to the button, causing the clear method to be called, is the problem 
here somehow.

Yes, I can confirm this, and I'll do more investigation, when
I have the time, but probably not before the weekend. :-(

Albrecht
Index: src/Fl_Button.cxx
===================================================================
--- src/Fl_Button.cxx   (revision 7052)
+++ src/Fl_Button.cxx   (working copy)
@@ -117,7 +117,11 @@
     else {
       value(oldval);
       set_changed();
-      if (when() & FL_WHEN_CHANGED) do_callback();
+      if (when() & FL_WHEN_CHANGED) {
+       Fl_Widget_Tracker wp(this);
+        do_callback();
+        if (wp.deleted()) return 1;
+      }
     }
     if (when() & FL_WHEN_RELEASE) do_callback();
     return 1;
@@ -156,6 +160,7 @@
     if (Fl::focus() == this && Fl::event_key() == ' ' &&
         !(Fl::event_state() & (FL_SHIFT | FL_CTRL | FL_ALT | FL_META))) {
       set_changed();
+      Fl_Widget_Tracker wp(this);
       if (type() == FL_RADIO_BUTTON && !value_) {
        setonly();
        if (when() & FL_WHEN_CHANGED) do_callback();
@@ -163,6 +168,7 @@
        value(!value());
        if (when() & FL_WHEN_CHANGED) do_callback();
       }
+      if (wp.deleted()) return 1;
       if (when() & FL_WHEN_RELEASE) do_callback();
       return 1;
     }
_______________________________________________
fltk-dev mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk-dev

Reply via email to