Commit fdb3a753 authored by Robert O'Callahan's avatar Robert O'Callahan
Browse files

Bug 505896. Try to avoid invalidating plugins unnecessarily on Windows. r=jmathies

--HG--
extra : rebase_source : dfd12f047b693a61126e4d1c961a75a84fd6e9a2
parent 075323ed
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -4457,7 +4457,8 @@ nsWindow::ConfigureChildren(const nsTArray<Configuration>& aConfigurations)
nsresult
nsWindow::SetWindowClipRegion(const nsTArray<nsIntRect>& aRects)
{
    StoreWindowClipRegion(aRects);
    if (!StoreWindowClipRegion(aRects))
        return NS_OK;

    if (!mDrawingarea)
        return NS_OK;
+45 −5
Original line number Diff line number Diff line
@@ -2299,11 +2299,22 @@ NS_IMETHODIMP nsWindow::Update()
 *
 **************************************************************/

static PRBool
ClipRegionContainedInRect(const nsTArray<nsIntRect>& aClipRects,
                          const nsIntRect& aRect)
{
  for (PRUint32 i = 0; i < aClipRects.Length(); ++i) {
    if (!aRect.Contains(aClipRects[i]))
      return PR_FALSE;
  }
  return PR_TRUE;
}

void
nsWindow::Scroll(const nsIntPoint& aDelta, const nsIntRect& aSource,
                 const nsTArray<Configuration>& aConfigurations)
{
  // We can use SW_SCROLLCHILDREN if all the windows that intersect the
  // We use SW_SCROLLCHILDREN if all the windows that intersect the
  // affected area are moving by the scroll amount.
  // First, build the set of widgets that are to be moved by the scroll
  // amount.
@@ -2338,7 +2349,25 @@ nsWindow::Scroll(const nsIntPoint& aDelta, const nsIntRect& aSource,
    }
  }

  nsIntRect destRect = aSource + aDelta;
  if (flags & SW_SCROLLCHILDREN) {
    for (PRUint32 i = 0; i < aConfigurations.Length(); ++i) {
      const Configuration& configuration = aConfigurations[i];
      nsWindow* w = static_cast<nsWindow*>(configuration.mChild);
      // Widgets that will be scrolled by SW_SCROLLCHILDREN but which
      // will be partly visible outside the scroll area after scrolling
      // must be invalidated, because SW_SCROLLCHILDREN doesn't
      // update parts of widgets outside the area it scrolled, even
      // if it moved them.
      if (w->mBounds.Intersects(affectedRect) &&
          !ClipRegionContainedInRect(configuration.mClipRegion,
                                     affectedRect - (w->mBounds.TopLeft() + aDelta))) {
        w->Invalidate(PR_FALSE);
      }
    }
  }

  // Note that when SW_SCROLLCHILDREN is used, WM_MOVE messages are sent
  // which will update the mBounds of the children.
  RECT clip = { affectedRect.x, affectedRect.y, affectedRect.XMost(), affectedRect.YMost() };
  ::ScrollWindowEx(mWnd, aDelta.x, aDelta.y, &clip, &clip, NULL, NULL, flags);

@@ -5540,9 +5569,15 @@ nsWindow::ConfigureChildren(const nsTArray<Configuration>& aConfigurations)
    // We put the region back just below, anyway.
    ::SetWindowRgn(w->mWnd, NULL, TRUE);
#endif
    nsIntRect bounds;
    w->GetBounds(bounds);
    if (bounds.Size() != configuration.mBounds.Size()) {
      w->Resize(configuration.mBounds.x, configuration.mBounds.y,
                configuration.mBounds.width, configuration.mBounds.height,
                PR_TRUE);
    } else if (bounds.TopLeft() != configuration.mBounds.TopLeft()) {
      w->Move(configuration.mBounds.x, configuration.mBounds.y);
    }
    nsresult rv = w->SetWindowClipRegion(configuration.mClipRegion, PR_FALSE);
    NS_ENSURE_SUCCESS(rv, rv);
  }
@@ -5575,6 +5610,11 @@ nsresult
nsWindow::SetWindowClipRegion(const nsTArray<nsIntRect>& aRects,
                              PRBool aIntersectWithExisting)
{
  if (!aIntersectWithExisting) {
    if (!StoreWindowClipRegion(aRects))
      return NS_OK;
  }

  HRGN dest = CreateHRGNFromArray(aRects);
  if (!dest)
    return NS_ERROR_OUT_OF_MEMORY;
+6 −1
Original line number Diff line number Diff line
@@ -561,14 +561,19 @@ nsTransparencyMode nsBaseWidget::GetTransparencyMode() {
  return eTransparencyOpaque;
}

void
PRBool
nsBaseWidget::StoreWindowClipRegion(const nsTArray<nsIntRect>& aRects)
{
  if (mClipRects && mClipRectCount == aRects.Length() &&
      memcmp(mClipRects, aRects.Elements(), sizeof(nsIntRect)*mClipRectCount) == 0)
    return PR_FALSE;

  mClipRectCount = aRects.Length();
  mClipRects = new nsIntRect[mClipRectCount];
  if (mClipRects) {
    memcpy(mClipRects, aRects.Elements(), sizeof(nsIntRect)*mClipRectCount);
  }
  return PR_TRUE;
}

void
+3 −1
Original line number Diff line number Diff line
@@ -171,7 +171,9 @@ protected:
                                            const nsAString& aUnmodifiedCharacters)
  { return NS_ERROR_UNEXPECTED; }

  void StoreWindowClipRegion(const nsTArray<nsIntRect>& aRects);
  // Stores the clip rectangles in aRects into mClipRects. Returns true
  // if the new rectangles are different from the old rectangles.
  PRBool StoreWindowClipRegion(const nsTArray<nsIntRect>& aRects);

protected: 
  void*             mClientData;