It looks as if you're not returning from a timer callback or an idle
callback for a longer time. If that is the case then the Fl::flush()
call that is done after processing all events in the normal event loop
is obviously not called, hence no drawing at all.
You can test if this theory is true:
(1) events would not be serviced while your text display is missing
updates (draws) although your printf() or other output statements
indicate that the text display is (was) modified
(2) the text display would refresh once the action that is blocking the
event loop (long running timer or idle callback) finishes.
> (2) Does it work on other OS's (Windows, Linux with X11)?
>
>
> I haven't tried it yet (can only test those on a VM) -- suspect
> answer to (1) is sufficient.
>
>
> (3) Can you strip this code down to a simple but complete,
> compileable
> example program that still shows the effect and can post it
> here? You
> could add test data in a timer event to the Fl_Text_Display.
>
> I'll work on it, but seems like it will be easier to build up an
> example from zero -- if that example doesn't show the behavior, then
> I'll be in a tough spot.
You'd likely do it differently and it wouldn't expose the same bad
behavior. Or maybe it would, depending on how similar you can rebuild
your existing code.
> (4) And, last but not least, can you also test with FLTK 1.4.0?
> There
> are weekly snapshots you can download. This is maybe the easiest
> test.
>
> I'll work on that also.
>
> This GUI is built programmatically, so I can't visually check the
> bounding boxes of the widgets in FLUID. From inspecting the code, I
> think it is correct -- and we don't generally have problems with
> events working up/down the hierarchy.
>
> I modified the code to trigger each Fl_Group::redraw() up the
> hierarchy (starting at the deepest nested level, adding the parent
> each test) until I got all the way up to the containing
> Fl_Double_Window. The behavior still does not work as desired.
> Even with all the redraw()s _and_ a flush(), it doesn't update.
>
>
> Forcing a Fl::wait() seems to 'correct' the problem. This seems like a
> terrible hack (so I'm hesitant to put it into production) but perhaps it
> will help the gurus help figure this out.
Yep, this supports my theory that you don't leave your
(whatever-type-of) callback so the normal FLTK event loop is blocked. I
hope there are no threads involved. That would open even more options to
do it wrong and to exhibit strange effects.
> The code is now like this:
>
> display->buffer()->append( text.c_str() );
>
> display->move_down();
>
> display->show_insert_position();
>
> display->redraw();
>
> Fl::wait();
Fl::wait() processes pending events and calls Fl::flush() after all
events have been processed. This should not be necessary here. If it
makes the code work then because it "heals" another bug.
We need more information about how your code above is called (timeout
event, idle callback?) and how long it runs. If it runs in a loop with
multiple display updates w/o _leaving_ this loop to return to the FLTK
event loop then _this_ is the culprit. All callbacks (even idle
callbacks[1]) must return as soon as possible to let the FLTK event loop
handle events and eventually call Fl::flush() to draw everything that
was changed.
Please check if this is the case. If it is, then this code will behave
similar (bad) on all platforms, and the fact that it seemed to work was
only good luck. Note: this is only an educated guess without knowing
your complete code, but I hope we're coming closer to the root cause...
-------------------
[1] idle callbacks should run only a few milliseconds, never more than
about 50-100ms before they return to the FLTK event loop to let FLTK
service pending events. Otherwise event handling would stall. When all
pending events are done FLTK will call the idle callback again. Your
code looks very similar to something that might be done in an idle callback.