Hello, let's get more agressive regarding these excessive redraws :-) Below are two patches. The first one adds a own run method to FltkPlatform. It is pretty similar to what fltk delivers, but this way we can tweak it as we like. Especially when to call our idle functions. The other patch changes resizeIdle() a bit. As stated in the comments, resizeIdle() can queue a new resizeIdle(). So instead of drawing the preliminary layout, then change it and redraw again, we now wait until the layout is settled and then draw it. Please note, that the provided run method was tuned for my computer, so it may need other values on slower/faster machines. Play around with other strategies! Johannes diff --git a/dw/fltkplatform.cc b/dw/fltkplatform.cc --- a/dw/fltkplatform.cc +++ b/dw/fltkplatform.cc @@ -25,6 +25,7 @@ #include <fltk/draw.h> #include <fltk/run.h> #include <fltk/events.h> +#include <fltk/Window.h> #include <stdio.h> namespace dw { @@ -185,6 +186,9 @@ container::typed::HashTable <dw::core::s new container::typed::HashTable <dw::core::style::ColorAttrs, dw::core::style::Color> (false, false); +container::typed::List <FltkPlatform> *FltkPlatform::idlePlatforms = + new container::typed::List <FltkPlatform> (0); + FltkPlatform::FltkPlatform () { layout = NULL; @@ -200,8 +204,7 @@ FltkPlatform::FltkPlatform () FltkPlatform::~FltkPlatform () { - if(idleFuncRunning) - remove_idle (generalStaticIdle, (void*)this); + idlePlatforms->removeRef(this); delete idleQueue; } @@ -241,11 +244,6 @@ int FltkPlatform::textWidth (core::style FltkFont *ff = (FltkFont*) font; setfont (ff->font, ff->size); return (int) getwidth (text, len); -} - -void FltkPlatform::generalStaticIdle (void *data) -{ - ((FltkPlatform*)data)->generalIdle(); } void FltkPlatform::generalIdle () @@ -263,7 +261,7 @@ void FltkPlatform::generalIdle () if(idleQueue->isEmpty()) { idleFuncRunning = false; - remove_idle (generalStaticIdle, (void*)this); + idlePlatforms->removeRef (this); } } @@ -277,8 +275,9 @@ int FltkPlatform::addIdle (void (core::L * idle function, the passed idle function is put into a queue. */ if(!idleFuncRunning) { - add_idle (generalStaticIdle, (void*)this); idleFuncRunning = true; + idlePlatforms->removeRef (this); + idlePlatforms->append (this); } idleFuncId++; @@ -306,7 +305,7 @@ void FltkPlatform::removeIdle (int idleI } if(idleFuncRunning && idleQueue->isEmpty()) - remove_idle (generalStaticIdle, (void*)this); + idlePlatforms->removeRef (this); } @@ -409,5 +408,30 @@ void FltkPlatform::detachResource (ui::F resources->removeRef (resource); } + +int FltkPlatform::run () { + int skipped = 0; + + while (::fltk::Window::first()) { + int r = fltk::wait (0.01); + + if (r == 0 || skipped >= 50) { + skipped = 0; + + for (container::typed::Iterator <FltkPlatform> it = idlePlatforms->iterator (); + it.hasNext (); ) { + FltkPlatform *p = it.getNext (); + + p->generalIdle (); + } + + } else { + skipped++; + } + } + + return 0; +} + } // namespace fltk } // namespace dw diff --git a/dw/fltkplatform.hh b/dw/fltkplatform.hh --- a/dw/fltkplatform.hh +++ b/dw/fltkplatform.hh @@ -94,7 +94,7 @@ private: bool idleFuncRunning; int idleFuncId; - static void generalStaticIdle(void *data); + static container::typed::List <FltkPlatform> *idlePlatforms; void generalIdle(); container::typed::List <FltkView> *views; @@ -163,6 +163,8 @@ public: void attachResource (ui::FltkResource *resource); void detachResource (ui::FltkResource *resource); + + static int run(); }; } // namespace fltk diff --git a/config.h.in b/config.h.in diff --git a/src/dillo.cc b/src/dillo.cc --- a/src/dillo.cc +++ b/src/dillo.cc @@ -23,6 +23,8 @@ #include <fltk/Window.h> #include <fltk/run.h> + +#include "dw/fltkcore.hh" #include "dir.h" #include "uicmd.hh" @@ -103,5 +105,5 @@ int main(int argc, char **argv) a_Nav_push(bw, prefs.start_page); } - return fltk::run(); + return dw::fltk::FltkPlatform::run(); } diff --git a/dw/layout.cc b/dw/layout.cc --- a/dw/layout.cc +++ b/dw/layout.cc @@ -520,58 +520,61 @@ void Layout::updateBgColor () void Layout::resizeIdle () { - // Reset already here, since in this function, queueResize() may be - // called again. - resizeIdleId = -1; - - if (topLevel) { - Requisition requisition; - Allocation allocation; - - topLevel->sizeRequest (&requisition); - - allocation.x = allocation.y = 0; - allocation.width = requisition.width; - allocation.ascent = requisition.ascent; - allocation.descent = requisition.descent; - topLevel->sizeAllocate (&allocation); - - canvasWidth = requisition.width; - canvasAscent = requisition.ascent; - canvasDescent = requisition.descent; - emitter.emitCanvasSizeChanged (canvasWidth, canvasAscent, canvasDescent); + while (resizeIdleId != -1) { + // Reset already here, since in this function, queueResize() may be + // called again. + resizeIdleId = -1; - // Tell the views about the new world size. - for (typed::Iterator <View> it = views->iterator (); it.hasNext (); ) { - View *view = it.getNext (); - view->setCanvasSize (canvasWidth, canvasAscent, canvasDescent); - view->queueDrawTotal (); - } + if (topLevel) { + Requisition requisition; + Allocation allocation; - if (usesViewport) { - int actualHScrollbarThickness = - (canvasWidth > viewportWidth) ? hScrollbarThickness : 0; - int actualVScrollbarThickness = + topLevel->sizeRequest (&requisition); + + allocation.x = allocation.y = 0; + allocation.width = requisition.width; + allocation.ascent = requisition.ascent; + allocation.descent = requisition.descent; + topLevel->sizeAllocate (&allocation); + + canvasWidth = requisition.width; + canvasAscent = requisition.ascent; + canvasDescent = requisition.descent; + + emitter.emitCanvasSizeChanged (canvasWidth, canvasAscent, canvasDescent); + + // Tell the views about the new world size. + for (typed::Iterator <View> it = views->iterator (); it.hasNext (); ) { + View *view = it.getNext (); + view->setCanvasSize (canvasWidth, canvasAscent, canvasDescent); + view->queueDrawTotal (); + } + + if (usesViewport) { + int actualHScrollbarThickness = + (canvasWidth > viewportWidth) ? hScrollbarThickness : 0; + int actualVScrollbarThickness = (canvasAscent + canvasDescent > viewportWidth) ? vScrollbarThickness : 0; - - if (!canvasHeightGreater && - canvasAscent + canvasDescent - > viewportHeight - actualHScrollbarThickness) { - canvasHeightGreater = true; - setSizeHints (); - /* May queue a new resize. */ - } - // Set viewport sizes. - for (typed::Iterator <View> it = views->iterator (); - it.hasNext (); ) { - View *view = it.getNext (); - if (view->usesViewport ()) - view->setViewportSize (viewportWidth, viewportHeight, - actualHScrollbarThickness, - actualVScrollbarThickness); + if (!canvasHeightGreater && + canvasAscent + canvasDescent + > viewportHeight - actualHScrollbarThickness) { + canvasHeightGreater = true; + setSizeHints (); + /* May queue a new resize. */ + } + + // Set viewport sizes. + for (typed::Iterator <View> it = views->iterator (); + it.hasNext (); ) { + View *view = it.getNext (); + if (view->usesViewport ()) + view->setViewportSize (viewportWidth, viewportHeight, + actualHScrollbarThickness, + actualVScrollbarThickness); + } } }