On Tue Apr 04 2017 13:29:07, 'Stephan Effelsberg' via fltk.general wrote:
> First an improvement to Ian's latest example code, use flush() if you know that the window is Fl_Double_Window. This removed the flickering for me.
Hmm, what platform were you testing on? I didn’t see any flickering for the updates in my test; this was on Win7 Pro on a machine thats a few years old now, with a decent (but not great) Intel GPU, so not the fastest or most capable GPU...
>
> main_window->flush();
>
> Second there may be a much simpler approach without Windows specific code.
Sure, this can work, but I think I’m generally in favour of a solution that #ifdef’s this on only for WIN32, as it is likely that other platforms do not need this code (at least, it seems OK on OSX and my X11 test box at any rate!) so having this code “always on” seems like overhead.
(Note: this isn’t entirely true either - the OSX test does sometimes “pause” whilst the window is being resized, but otherwise interacting with the WM frame does not stop the main window from refreshing. So “less bad” than the WIN32 case, not as good as X11 on my laptop...)
> If it is known that the window's contents are updated (we do in this example), then set a timeout to issue a redraw.
Again... yes, but...
In the specific example I posted, we do know that a redraw is posted, but that’s mainly because I just started with my old offscreen demo, as a simple basis for a window that animates constantly.
However, what I was trying to show was that it is possible to detect the WM_ENTERSIZEMOVE state and go into a “special mode” to deal with that circumstance specifically, which I *imagine* might allow us to keep the window refreshing even in response to events from “elsewhere” - whatever that might be...
> Again starting with Ian's code, remove all WIN32 stuff, make main_window a simple Fl_Double_Window* without derivation, then expand the drawing callback like this:
>
> static void redraw_if_damaged_cb(void* arg)
> {
> Fl_Double_Window* win = (Fl_Double_Window*)arg;
> if (win && win->damage()) {
> win->flush();
> }
> }
I think that’s a neater option than my make_current(); draw(); hack - does it work robustly? I think it should, in which case it seems safer than my way.
>
> static void oscr_anim(void *)
> {
> os_box->oscr_drawing();
> Fl::repeat_timeout(delta_time, oscr_anim);
> if (!Fl::has_timeout(redraw_if_damaged_cb, main_window)) {
> Fl::add_timeout(0.2, redraw_if_damaged_cb, main_window);
> }
> }
(Though, as noted above, I think I’d still #ifdef around the redraw_if_damaged_cb timer to make it WIN32 only...)
>
> This means that if the window gets new contents and it is still damaged after 200 ms, then a flush() will do the trick. Everything seems to be pivoted around smartly using flush(). Tested on Win7.
>
> And while we're at problems that occur in this special situation, let me expand the list of things that don't work then:
> - Callbacks added with add_idle() and add_check() are not called.
I had imagined that, once we detect the WM_ENTERSIZEMOVE state, we can probably contrive to trigger these, if we need to.
It’s possible that calling wait(...); might be enough? It should service all the timers and any pending idle callbacks, then call flush(). Assuming that wait() itself does not block, of course... Don’t have a WinXX box to hand to test this on now.
> - If a thread is running and this thread calls Fl::lock(), this call will block until the situation is "back to normal”.
I have to guess that’s happening because the main thread is holding the lock while it is itself "blocked”, but I don’t think that’s what I expect to happen.
Again, polling on wait() might get that moving again? Not sure.
> - If you run the program with a console attached and pin its scrollbar with the mouse, then any print to the console will block.
Which console were you using?
In my test, I was using the Msys console (I was building with both mingw32 and with the TDM mingw-64) and had some printf’s in there to see what was happening, and they seemed to keep on ticking even when the window was “held” (that’s basically how I figured out what the relevant events were...)
I wonder why it’s different?