Bug 517804 - Flush reflows and invalidations during viewWillDraw. r=roc, r=josh
☠☠ backed out by 80f8fb6eb86e ☠ ☠
authorMarkus Stange <mstange@themasta.com>
Mon, 21 Sep 2009 18:29:59 +1200
changeset 32911 7799cfb993623e112a2555d6de0c4a45d29c1c90
parent 32910 4730f6f1fe6b172091e99f13cea12ad635034ecd
child 32912 e5f6affc4c8868f65c61c9dafb4540c88991e463
child 32970 80f8fb6eb86e72f39cd3f6ff0f6af48329e8b380
push idunknown
push userunknown
push dateunknown
reviewersroc, josh
bugs517804
milestone1.9.3a1pre
Bug 517804 - Flush reflows and invalidations during viewWillDraw. r=roc, r=josh
view/src/nsViewManager.cpp
widget/public/nsGUIEvent.h
widget/src/cocoa/nsChildView.mm
--- a/view/src/nsViewManager.cpp
+++ b/view/src/nsViewManager.cpp
@@ -888,38 +888,41 @@ NS_IMETHODIMP nsViewManager::DispatchEve
                                     NSIntPixelsToAppUnits(height, p2a));
                 *aStatus = nsEventStatus_eConsumeNoDefault;
               }
           }
 
         break;
       }
 
+    case NS_WILL_PAINT:
     case NS_PAINT:
       {
         nsPaintEvent *event = static_cast<nsPaintEvent*>(aEvent);
 
         if (!aView || !mContext)
           break;
 
         *aStatus = nsEventStatus_eConsumeNoDefault;
 
         // The rect is in device units, and it's in the coordinate space of its
         // associated window.
         nsCOMPtr<nsIRegion> region = event->region;
-        if (!region) {
-          if (NS_FAILED(CreateRegion(getter_AddRefs(region))))
-            break;
+        if (aEvent->message == NS_PAINT) {
+          if (!region) {
+            if (NS_FAILED(CreateRegion(getter_AddRefs(region))))
+              break;
 
-          const nsIntRect& damrect = *event->rect;
-          region->SetTo(damrect.x, damrect.y, damrect.width, damrect.height);
+            const nsIntRect& damrect = *event->rect;
+            region->SetTo(damrect.x, damrect.y, damrect.width, damrect.height);
+          }
+
+          if (region->IsEmpty())
+            break;
         }
-        
-        if (region->IsEmpty())
-          break;
 
         // Refresh the view
         if (IsRefreshEnabled()) {
           // If an ancestor widget was hidden and then shown, we could
           // have a delayed resize to handle.
           PRBool didResize = PR_FALSE;
           for (nsViewManager *vm = this; vm;
                vm = vm->mRootView->GetParent()
@@ -980,22 +983,22 @@ NS_IMETHODIMP nsViewManager::DispatchEve
               }
             }
             // Make sure to sync up any widget geometry changes we
             // have pending before we paint.
             if (rootVM->mHasPendingUpdates) {
               rootVM->ProcessPendingUpdates(mRootView, PR_FALSE);
             }
             
-            if (view) {
+            if (view && aEvent->message == NS_PAINT) {
               Refresh(view, event->renderingContext, region,
                       NS_VMREFRESH_DOUBLE_BUFFER);
             }
           }
-        } else {
+        } else if (aEvent->message == NS_PAINT) {
           // since we got an NS_PAINT event, we need to
           // draw something so we don't get blank areas,
           // unless there's no widget or it's transparent.
           nsIntRect damIntRect;
           region->GetBoundingBox(&damIntRect.x, &damIntRect.y,
                                  &damIntRect.width, &damIntRect.height);
           nsRect damRect =
             damIntRect.ToAppUnits(mContext->AppUnitsPerDevPixel());
--- a/widget/public/nsGUIEvent.h
+++ b/widget/public/nsGUIEvent.h
@@ -157,16 +157,18 @@ class nsHashKey;
 // Widget size mode was changed
 #define NS_SIZEMODE                     (NS_WINDOW_START + 4)
 // Widget got activated
 #define NS_ACTIVATE                     (NS_WINDOW_START + 7)
 // Widget got deactivated
 #define NS_DEACTIVATE                   (NS_WINDOW_START + 8)
 // top-level window z-level change request
 #define NS_SETZLEVEL                    (NS_WINDOW_START + 9)
+// Widget will need to be painted
+#define NS_WILL_PAINT                   (NS_WINDOW_START + 29)
 // Widget needs to be repainted
 #define NS_PAINT                        (NS_WINDOW_START + 30)
 // Key is pressed within a window
 #define NS_KEY_PRESS                    (NS_WINDOW_START + 31)
 // Key is released within a window
 #define NS_KEY_UP                       (NS_WINDOW_START + 32)
 // Key is pressed within a window
 #define NS_KEY_DOWN                     (NS_WINDOW_START + 33)
--- a/widget/src/cocoa/nsChildView.mm
+++ b/widget/src/cocoa/nsChildView.mm
@@ -2734,16 +2734,25 @@ static const PRInt32 sShadowInvalidation
   CGContextSetLineWidth (cgContext, 4.0);
   CGContextStrokeRect (cgContext,
                        CGRectMake(aRect.origin.x, aRect.origin.y, aRect.size.width, aRect.size.height));
 #endif
 
   NS_OBJC_END_TRY_ABORT_BLOCK;
 }
 
+- (void)viewWillDraw
+{
+  if (!mGeckoChild)
+    return;
+
+  nsPaintEvent paintEvent(PR_TRUE, NS_WILL_PAINT, mGeckoChild);
+  mGeckoChild->DispatchWindowEvent(paintEvent);
+}
+
 // Allows us to turn off setting up the clip region
 // before each drawRect. We already clip within gecko.
 - (BOOL)wantsDefaultClipping
 {
   return NO;
 }
 
 #if USE_CLICK_HOLD_CONTEXTMENU