changeset 4645:ab70f9ce4353

Fix Layout::resizeIdle() This was three year old bug, that went undiscovered (hg#2863). The patch is simpler than it looks, it's just a while cycle enclosing the body, indentation makes it look large. How to reproduce: 1. Load [5] at normal size, wait for most images to load, search for "re-re" with Find Text, press page down (you'll see an image), go Bck/Fwd, check the image is there. If not, you can place the cursor where the image was, if you get a hand cursor, Dillo thinks it is there. Wait for the tooltip and drag it a bit downwards to the right, Dillo will repaint from the image data. [5] http://tinyurl.com/huvf6pn
author Jorge Arellano Cid <jcid@dillo.org>
date Sa, 16 Jul 2016 18:56:16 -0400
parents 46080df49751
children 3bfefb5042e9
files dw/layout.cc
diffstat 1 files changed, 77 insertions(+), 82 deletions(-) [+]
line wrap: on
line diff
--- a/dw/layout.cc	Mi Jul 13 15:16:27 2016 -0400
+++ b/dw/layout.cc	Sa Jul 16 18:56:16 2016 -0400
@@ -864,94 +864,89 @@
 
    enterResizeIdle ();
 
-   //static int calls = 0;
-   //printf ("Layout::resizeIdle calls = %d\n", ++calls);
-
-   assert (resizeIdleId != -1);
-
-   for (typed::Iterator <Widget> it = queueResizeList->iterator();
-        it.hasNext (); ) {
-      Widget *widget = it.getNext ();
-
-      //printf ("   the %stop-level %s %p was queued (extremes changed: %s)\n",
-      //        widget->parent ? "non-" : "", widget->getClassName(), widget,
-      //        widget->extremesQueued () ? "yes" : "no");
+   static int calls = 0;
 
-      if (widget->resizeQueued ()) {
-         widget->setFlags (Widget::NEEDS_RESIZE);
-         widget->unsetFlags (Widget::RESIZE_QUEUED);
-      }
+   while (resizeIdleId != -1) {
+      printf ("Layout::resizeIdle calls = %d\n", ++calls);
 
-      if (widget->allocateQueued ()) {
-         widget->setFlags (Widget::NEEDS_ALLOCATE);
-         widget->unsetFlags (Widget::ALLOCATE_QUEUED);
+      for (typed::Iterator <Widget> it = queueResizeList->iterator();
+           it.hasNext (); ) {
+         Widget *widget = it.getNext ();
+
+         if (widget->resizeQueued ()) {
+            widget->setFlags (Widget::NEEDS_RESIZE);
+            widget->unsetFlags (Widget::RESIZE_QUEUED);
+         }
+
+         if (widget->allocateQueued ()) {
+            widget->setFlags (Widget::NEEDS_ALLOCATE);
+            widget->unsetFlags (Widget::ALLOCATE_QUEUED);
+         }
+
+         if (widget->extremesQueued ()) {
+            widget->setFlags (Widget::EXTREMES_CHANGED);
+            widget->unsetFlags (Widget::EXTREMES_QUEUED);
+         }
       }
+      queueResizeList->clear ();
 
-      if (widget->extremesQueued ()) {
-         widget->setFlags (Widget::EXTREMES_CHANGED);
-         widget->unsetFlags (Widget::EXTREMES_QUEUED);
+      // Reset here, since below, queueResize() may be called again.
+      resizeIdleId = -1;
+
+      // If this method is triggered by a viewport change, we can save
+      // time when the toplevel widget is not affected (as for a toplevel
+      // image resource).
+      if (topLevel && (topLevel->needsResize () || topLevel->needsAllocate ())) {
+         Requisition requisition;
+         Allocation allocation;
+
+         topLevel->sizeRequest (&requisition);
+         DBG_OBJ_MSGF ("resize", 1, "toplevel size: %d * (%d + %d)",
+                       requisition.width, requisition.ascent,
+                       requisition.descent);
+
+         // This method is triggered by Widget::queueResize, which will,
+         // in any case, set NEEDS_ALLOCATE (indirectly, as ALLOCATE_QUEUED).
+         // This assertion helps to find inconsistencies. (Cases where
+         // this method is triggered by a viewport change, but the
+         // toplevel widget is not affected, are filtered out some lines
+         // above: "if (topLevel && topLevel->needsResize ())".)
+         assert (topLevel->needsAllocate ());
+
+         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 view about the new world size.
+         view->setCanvasSize (canvasWidth, canvasAscent, canvasDescent);
+
+         if (usesViewport) {
+            int currHThickness = currHScrollbarThickness();
+            int currVThickness = currVScrollbarThickness();
+
+            if (!canvasHeightGreater &&
+                canvasAscent + canvasDescent > viewportHeight - currHThickness) {
+               canvasHeightGreater = true;
+               DBG_OBJ_SET_SYM ("canvasHeightGreater",
+                                canvasHeightGreater ? "true" : "false");
+               containerSizeChanged ();
+            }
+
+            // Set viewport sizes.
+            view->setViewportSize (viewportWidth, viewportHeight,
+                                   currHThickness, currVThickness);
+         }
+
+         // views are redrawn via Widget::resizeDrawImpl ()
       }
    }
-   queueResizeList->clear ();
-
-   // Reset already here, since in this function, queueResize() may be
-   // called again.
-   resizeIdleId = -1;
-
-   // If this method is triggered by a viewport change, we can save
-   // time when the toplevel widget is not affected (as for a toplevel
-   // image resource).
-   if (topLevel && (topLevel->needsResize () || topLevel->needsAllocate ())) {
-      Requisition requisition;
-      Allocation allocation;
-
-      topLevel->sizeRequest (&requisition);
-      DBG_OBJ_MSGF ("resize", 1, "toplevel size: %d * (%d + %d)",
-                    requisition.width, requisition.ascent, requisition.descent);
-
-      // This method is triggered by Widget::queueResize, which will,
-      // in any case, set NEEDS_ALLOCATE (indirectly, as ALLOCATE_QUEUED).
-      // This assertion helps to find inconsistences. (Cases where
-      // this method is triggered by a viewport change, but the
-      // toplevel widget is not affected, are filtered out some lines
-      // above: "if (topLevel && topLevel->needsResize ())".)
-      assert (topLevel->needsAllocate ());
-
-      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 view about the new world size.
-      view->setCanvasSize (canvasWidth, canvasAscent, canvasDescent);
-
-      if (usesViewport) {
-         int currHThickness = currHScrollbarThickness();
-         int currVThickness = currVScrollbarThickness();
-
-         if (!canvasHeightGreater &&
-             canvasAscent + canvasDescent > viewportHeight - currHThickness) {
-            canvasHeightGreater = true;
-            DBG_OBJ_SET_SYM ("canvasHeightGreater",
-                             canvasHeightGreater ? "true" : "false");
-            containerSizeChanged ();
-         }
-
-         // Set viewport sizes.
-         view->setViewportSize (viewportWidth, viewportHeight,
-                                currHThickness, currVThickness);
-      }
-
-      // views are redrawn via Widget::resizeDrawImpl ()
-   }
-
    updateAnchor ();
 
    DBG_OBJ_MSGF ("resize", 1,