LCOV - code coverage report
Current view: top level - view - nsViewManager.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 330 535 61.7 %
Date: 2017-07-14 16:53:18 Functions: 38 50 76.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       4             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       5             : 
       6             : #include "nsAutoPtr.h"
       7             : #include "nsViewManager.h"
       8             : #include "nsGfxCIID.h"
       9             : #include "nsView.h"
      10             : #include "nsCOMPtr.h"
      11             : #include "mozilla/MouseEvents.h"
      12             : #include "nsRegion.h"
      13             : #include "nsCOMArray.h"
      14             : #include "nsIPluginWidget.h"
      15             : #include "nsXULPopupManager.h"
      16             : #include "nsIPresShell.h"
      17             : #include "nsIPresShellInlines.h"
      18             : #include "nsPresContext.h"
      19             : #include "mozilla/StartupTimeline.h"
      20             : #include "GeckoProfiler.h"
      21             : #include "nsRefreshDriver.h"
      22             : #include "mozilla/Preferences.h"
      23             : #include "nsContentUtils.h" // for nsAutoScriptBlocker
      24             : #include "nsLayoutUtils.h"
      25             : #include "Layers.h"
      26             : #include "gfxPlatform.h"
      27             : #include "gfxPrefs.h"
      28             : #include "nsIDocument.h"
      29             : 
      30             : /**
      31             :    XXX TODO XXX
      32             : 
      33             :    DeCOMify newly private methods
      34             :    Optimize view storage
      35             : */
      36             : 
      37             : /**
      38             :    A note about platform assumptions:
      39             : 
      40             :    We assume that a widget is z-ordered on top of its parent.
      41             : 
      42             :    We do NOT assume anything about the relative z-ordering of sibling widgets. Even though
      43             :    we ask for a specific z-order, we don't assume that widget z-ordering actually works.
      44             : */
      45             : 
      46             : using namespace mozilla;
      47             : using namespace mozilla::layers;
      48             : 
      49             : #define NSCOORD_NONE      INT32_MIN
      50             : 
      51             : #undef DEBUG_MOUSE_LOCATION
      52             : 
      53             : // Weakly held references to all of the view managers
      54             : nsTArray<nsViewManager*>* nsViewManager::gViewManagers = nullptr;
      55             : uint32_t nsViewManager::gLastUserEventTime = 0;
      56             : 
      57          28 : nsViewManager::nsViewManager()
      58             :   : mPresShell(nullptr)
      59             :   , mDelayedResize(NSCOORD_NONE, NSCOORD_NONE)
      60             :   , mRootView(nullptr)
      61             :   , mRootViewManager(this)
      62             :   , mRefreshDisableCount(0)
      63             :   , mPainting(false)
      64             :   , mRecursiveRefreshPending(false)
      65             :   , mHasPendingWidgetGeometryChanges(false)
      66          28 :   , mPrintRelated(false)
      67             : {
      68          28 :   if (gViewManagers == nullptr) {
      69             :     // Create an array to hold a list of view managers
      70           2 :     gViewManagers = new nsTArray<nsViewManager*>;
      71             :   }
      72             : 
      73          28 :   gViewManagers->AppendElement(this);
      74          28 : }
      75             : 
      76           8 : nsViewManager::~nsViewManager()
      77             : {
      78           4 :   if (mRootView) {
      79             :     // Destroy any remaining views
      80           4 :     mRootView->Destroy();
      81           4 :     mRootView = nullptr;
      82             :   }
      83             : 
      84           4 :   if (!IsRootVM()) {
      85             :     // We have a strong ref to mRootViewManager
      86           0 :     NS_RELEASE(mRootViewManager);
      87             :   }
      88             : 
      89           4 :   NS_ASSERTION(gViewManagers != nullptr, "About to use null gViewManagers");
      90             : 
      91             : #ifdef DEBUG
      92             :   bool removed =
      93             : #endif
      94           4 :     gViewManagers->RemoveElement(this);
      95           4 :   NS_ASSERTION(removed, "Viewmanager instance was not in the global list of viewmanagers");
      96             : 
      97           4 :   if (gViewManagers->IsEmpty()) {
      98             :     // There aren't any more view managers so
      99             :     // release the global array of view managers
     100           0 :     delete gViewManagers;
     101           0 :     gViewManagers = nullptr;
     102             :   }
     103             : 
     104           4 :   mPresShell = nullptr;
     105           4 : }
     106             : 
     107             : // We don't hold a reference to the presentation context because it
     108             : // holds a reference to us.
     109             : nsresult
     110          28 : nsViewManager::Init(nsDeviceContext* aContext)
     111             : {
     112          28 :   NS_PRECONDITION(nullptr != aContext, "null ptr");
     113             : 
     114          28 :   if (nullptr == aContext) {
     115           0 :     return NS_ERROR_NULL_POINTER;
     116             :   }
     117          28 :   if (nullptr != mContext) {
     118           0 :     return NS_ERROR_ALREADY_INITIALIZED;
     119             :   }
     120          28 :   mContext = aContext;
     121             : 
     122          28 :   return NS_OK;
     123             : }
     124             : 
     125             : nsView*
     126          78 : nsViewManager::CreateView(const nsRect& aBounds,
     127             :                           nsView* aParent,
     128             :                           nsViewVisibility aVisibilityFlag)
     129             : {
     130          78 :   auto *v = new nsView(this, aVisibilityFlag);
     131          78 :   v->SetParent(aParent);
     132          78 :   v->SetPosition(aBounds.x, aBounds.y);
     133         156 :   nsRect dim(0, 0, aBounds.width, aBounds.height);
     134          78 :   v->SetDimensions(dim, false);
     135         156 :   return v;
     136             : }
     137             : 
     138             : void
     139          32 : nsViewManager::SetRootView(nsView *aView)
     140             : {
     141          32 :   NS_PRECONDITION(!aView || aView->GetViewManager() == this,
     142             :                   "Unexpected viewmanager on root view");
     143             : 
     144             :   // Do NOT destroy the current root view. It's the caller's responsibility
     145             :   // to destroy it
     146          32 :   mRootView = aView;
     147             : 
     148          32 :   if (mRootView) {
     149          28 :     nsView* parent = mRootView->GetParent();
     150          28 :     if (parent) {
     151             :       // Calling InsertChild on |parent| will InvalidateHierarchy() on us, so
     152             :       // no need to set mRootViewManager ourselves here.
     153           1 :       parent->InsertChild(mRootView, nullptr);
     154             :     } else {
     155          27 :       InvalidateHierarchy();
     156             :     }
     157             : 
     158          28 :     mRootView->SetZIndex(false, 0);
     159             :   }
     160             :   // Else don't touch mRootViewManager
     161          32 : }
     162             : 
     163             : void
     164           0 : nsViewManager::GetWindowDimensions(nscoord *aWidth, nscoord *aHeight)
     165             : {
     166           0 :   if (nullptr != mRootView) {
     167           0 :     if (mDelayedResize == nsSize(NSCOORD_NONE, NSCOORD_NONE)) {
     168           0 :       nsRect dim = mRootView->GetDimensions();
     169           0 :       *aWidth = dim.width;
     170           0 :       *aHeight = dim.height;
     171             :     } else {
     172           0 :       *aWidth = mDelayedResize.width;
     173           0 :       *aHeight = mDelayedResize.height;
     174             :     }
     175             :   }
     176             :   else
     177             :     {
     178           0 :       *aWidth = 0;
     179           0 :       *aHeight = 0;
     180             :     }
     181           0 : }
     182             : 
     183          56 : void nsViewManager::DoSetWindowDimensions(nscoord aWidth, nscoord aHeight)
     184             : {
     185         112 :   nsRect oldDim = mRootView->GetDimensions();
     186         112 :   nsRect newDim(0, 0, aWidth, aHeight);
     187             :   // We care about resizes even when one dimension is already zero.
     188          56 :   if (!oldDim.IsEqualEdges(newDim)) {
     189             :     // Don't resize the widget. It is already being set elsewhere.
     190          22 :     mRootView->SetDimensions(newDim, true, false);
     191          22 :     if (mPresShell)
     192          22 :       mPresShell->ResizeReflow(aWidth, aHeight, oldDim.width, oldDim.height);
     193             :   }
     194          56 : }
     195             : 
     196             : bool
     197          56 : nsViewManager::ShouldDelayResize() const
     198             : {
     199          56 :   MOZ_ASSERT(mRootView);
     200         168 :   if (!mRootView->IsEffectivelyVisible() ||
     201         112 :       !mPresShell || !mPresShell->IsVisible()) {
     202           0 :     return true;
     203             :   }
     204          56 :   if (nsRefreshDriver* rd = mPresShell->GetRefreshDriver()) {
     205          56 :     if (rd->IsResizeSuppressed()) {
     206           0 :       return true;
     207             :     }
     208             :   }
     209          56 :   return false;
     210             : }
     211             : 
     212             : void
     213          56 : nsViewManager::SetWindowDimensions(nscoord aWidth, nscoord aHeight, bool aDelayResize)
     214             : {
     215          56 :   if (mRootView) {
     216          56 :     if (!ShouldDelayResize() && !aDelayResize) {
     217         112 :       if (mDelayedResize != nsSize(NSCOORD_NONE, NSCOORD_NONE) &&
     218          56 :           mDelayedResize != nsSize(aWidth, aHeight)) {
     219             :         // We have a delayed resize; that now obsolete size may already have
     220             :         // been flushed to the PresContext so we need to update the PresContext
     221             :         // with the new size because if the new size is exactly the same as the
     222             :         // root view's current size then DoSetWindowDimensions will not
     223             :         // request a resize reflow (which would correct it). See bug 617076.
     224           0 :         mDelayedResize = nsSize(aWidth, aHeight);
     225           0 :         FlushDelayedResize(false);
     226             :       }
     227          56 :       mDelayedResize.SizeTo(NSCOORD_NONE, NSCOORD_NONE);
     228          56 :       DoSetWindowDimensions(aWidth, aHeight);
     229             :     } else {
     230           0 :       mDelayedResize.SizeTo(aWidth, aHeight);
     231           0 :       if (mPresShell) {
     232           0 :         mPresShell->SetNeedStyleFlush();
     233           0 :         mPresShell->SetNeedLayoutFlush();
     234             :       }
     235             :     }
     236             :   }
     237          56 : }
     238             : 
     239             : void
     240         227 : nsViewManager::FlushDelayedResize(bool aDoReflow)
     241             : {
     242         227 :   if (mDelayedResize != nsSize(NSCOORD_NONE, NSCOORD_NONE)) {
     243           0 :     if (aDoReflow) {
     244           0 :       DoSetWindowDimensions(mDelayedResize.width, mDelayedResize.height);
     245           0 :       mDelayedResize.SizeTo(NSCOORD_NONE, NSCOORD_NONE);
     246           0 :     } else if (mPresShell && !mPresShell->GetIsViewportOverridden()) {
     247           0 :       nsPresContext* presContext = mPresShell->GetPresContext();
     248           0 :       if (presContext) {
     249           0 :         presContext->SetVisibleArea(nsRect(nsPoint(0, 0), mDelayedResize));
     250             :       }
     251             :     }
     252             :   }
     253         227 : }
     254             : 
     255             : // Convert aIn from being relative to and in appunits of aFromView, to being
     256             : // relative to and in appunits of aToView.
     257           0 : static nsRegion ConvertRegionBetweenViews(const nsRegion& aIn,
     258             :                                           nsView* aFromView,
     259             :                                           nsView* aToView)
     260             : {
     261           0 :   nsRegion out = aIn;
     262           0 :   out.MoveBy(aFromView->GetOffsetTo(aToView));
     263           0 :   out = out.ScaleToOtherAppUnitsRoundOut(
     264             :     aFromView->GetViewManager()->AppUnitsPerDevPixel(),
     265           0 :     aToView->GetViewManager()->AppUnitsPerDevPixel());
     266           0 :   return out;
     267             : }
     268             : 
     269          13 : nsView* nsViewManager::GetDisplayRootFor(nsView* aView)
     270             : {
     271          13 :   nsView *displayRoot = aView;
     272             :   for (;;) {
     273          13 :     nsView *displayParent = displayRoot->GetParent();
     274          13 :     if (!displayParent)
     275          13 :       return displayRoot;
     276             : 
     277           0 :     if (displayRoot->GetFloating() && !displayParent->GetFloating())
     278           0 :       return displayRoot;
     279             : 
     280             :     // If we have a combobox dropdown popup within a panel popup, both the view
     281             :     // for the dropdown popup and its parent will be floating, so we need to
     282             :     // distinguish this situation. We do this by looking for a widget. Any view
     283             :     // with a widget is a display root, except for plugins.
     284           0 :     nsIWidget* widget = displayRoot->GetWidget();
     285           0 :     if (widget && widget->WindowType() == eWindowType_popup) {
     286           0 :       NS_ASSERTION(displayRoot->GetFloating() && displayParent->GetFloating(),
     287             :         "this should only happen with floating views that have floating parents");
     288           0 :       return displayRoot;
     289             :     }
     290             : 
     291           0 :     displayRoot = displayParent;
     292           0 :   }
     293             : }
     294             : 
     295             : /**
     296             :    aRegion is given in device coordinates!!
     297             :    aContext may be null, in which case layers should be used for
     298             :    rendering.
     299             : */
     300           1 : void nsViewManager::Refresh(nsView* aView, const LayoutDeviceIntRegion& aRegion)
     301             : {
     302           1 :   NS_ASSERTION(aView->GetViewManager() == this, "wrong view manager");
     303             : 
     304           1 :   if (mPresShell && mPresShell->IsNeverPainting()) {
     305           0 :     return;
     306             :   }
     307             : 
     308             :   // damageRegion is the damaged area, in twips, relative to the view origin
     309           2 :   nsRegion damageRegion = aRegion.ToAppUnits(AppUnitsPerDevPixel());
     310             : 
     311             :   // move region from widget coordinates into view coordinates
     312           1 :   damageRegion.MoveBy(-aView->ViewToWidgetOffset());
     313             : 
     314           1 :   if (damageRegion.IsEmpty()) {
     315             : #ifdef DEBUG_roc
     316             :     nsRect viewRect = aView->GetDimensions();
     317             :     nsRect damageRect = damageRegion.GetBounds();
     318             :     printf_stderr("XXX Damage rectangle (%d,%d,%d,%d) does not intersect the widget's view (%d,%d,%d,%d)!\n",
     319             :            damageRect.x, damageRect.y, damageRect.width, damageRect.height,
     320             :            viewRect.x, viewRect.y, viewRect.width, viewRect.height);
     321             : #endif
     322           0 :     return;
     323             :   }
     324             : 
     325           1 :   nsIWidget *widget = aView->GetWidget();
     326           1 :   if (!widget) {
     327           0 :     return;
     328             :   }
     329             : 
     330           1 :   NS_ASSERTION(!IsPainting(), "recursive painting not permitted");
     331           1 :   if (IsPainting()) {
     332           0 :     RootViewManager()->mRecursiveRefreshPending = true;
     333           0 :     return;
     334             :   }
     335             : 
     336             :   {
     337           2 :     nsAutoScriptBlocker scriptBlocker;
     338           1 :     SetPainting(true);
     339             : 
     340           1 :     NS_ASSERTION(GetDisplayRootFor(aView) == aView,
     341             :                  "Widgets that we paint must all be display roots");
     342             : 
     343           1 :     if (mPresShell) {
     344             : #ifdef MOZ_DUMP_PAINTING
     345           1 :       if (nsLayoutUtils::InvalidationDebuggingIsEnabled()) {
     346           0 :         printf_stderr("--COMPOSITE-- %p\n", mPresShell);
     347             :       }
     348             : #endif
     349           1 :       uint32_t paintFlags = nsIPresShell::PAINT_COMPOSITE;
     350           1 :       LayerManager *manager = widget->GetLayerManager();
     351           1 :       if (!manager->NeedsWidgetInvalidation()) {
     352           1 :         manager->FlushRendering();
     353             :       } else {
     354           0 :         mPresShell->Paint(aView, damageRegion,
     355           0 :                           paintFlags);
     356             :       }
     357             : #ifdef MOZ_DUMP_PAINTING
     358           1 :       if (nsLayoutUtils::InvalidationDebuggingIsEnabled()) {
     359           0 :         printf_stderr("--ENDCOMPOSITE--\n");
     360             :       }
     361             : #endif
     362           1 :       mozilla::StartupTimeline::RecordOnce(mozilla::StartupTimeline::FIRST_PAINT);
     363             :     }
     364             : 
     365           1 :     SetPainting(false);
     366             :   }
     367             : 
     368           1 :   if (RootViewManager()->mRecursiveRefreshPending) {
     369           0 :     RootViewManager()->mRecursiveRefreshPending = false;
     370           0 :     InvalidateAllViews();
     371             :   }
     372             : }
     373             : 
     374             : void
     375          43 : nsViewManager::ProcessPendingUpdatesForView(nsView* aView,
     376             :                                             bool aFlushDirtyRegion)
     377             : {
     378          43 :   NS_ASSERTION(IsRootVM(), "Updates will be missed");
     379          43 :   if (!aView) {
     380           0 :     return;
     381             :   }
     382             : 
     383          86 :   nsCOMPtr<nsIPresShell> rootShell(mPresShell);
     384          86 :   AutoTArray<nsCOMPtr<nsIWidget>, 1> widgets;
     385          43 :   aView->GetViewManager()->ProcessPendingUpdatesRecurse(aView, widgets);
     386          86 :   for (uint32_t i = 0; i < widgets.Length(); ++i) {
     387          43 :     nsView* view = nsView::GetViewFor(widgets[i]);
     388          43 :     if (view) {
     389          43 :       if (view->mNeedsWindowPropertiesSync) {
     390          20 :         view->mNeedsWindowPropertiesSync = false;
     391          20 :         if (nsViewManager* vm = view->GetViewManager()) {
     392          20 :           if (nsIPresShell* ps = vm->GetPresShell()) {
     393          20 :             ps->SyncWindowProperties(view);
     394             :           }
     395             :         }
     396             :       }
     397             :     }
     398          43 :     view = nsView::GetViewFor(widgets[i]);
     399          43 :     if (view) {
     400          43 :       view->ResetWidgetBounds(false, true);
     401             :     }
     402             :   }
     403          43 :   if (rootShell->GetViewManager() != this) {
     404           0 :     return; // presentation might have been torn down
     405             :   }
     406          43 :   if (aFlushDirtyRegion) {
     407          70 :     nsAutoScriptBlocker scriptBlocker;
     408          35 :     SetPainting(true);
     409          70 :     for (uint32_t i = 0; i < widgets.Length(); ++i) {
     410          35 :       nsIWidget* widget = widgets[i];
     411          35 :       nsView* view = nsView::GetViewFor(widget);
     412          35 :       if (view) {
     413          35 :         view->GetViewManager()->ProcessPendingUpdatesPaint(widget);
     414             :       }
     415             :     }
     416          35 :     SetPainting(false);
     417             :   }
     418             : }
     419             : 
     420             : void
     421        1464 : nsViewManager::ProcessPendingUpdatesRecurse(nsView* aView,
     422             :                                             AutoTArray<nsCOMPtr<nsIWidget>, 1>& aWidgets)
     423             : {
     424        1464 :   if (mPresShell && mPresShell->IsNeverPainting()) {
     425           0 :     return;
     426             :   }
     427             : 
     428        2885 :   for (nsView* childView = aView->GetFirstChild(); childView;
     429             :        childView = childView->GetNextSibling()) {
     430             :     childView->GetViewManager()->
     431        1421 :       ProcessPendingUpdatesRecurse(childView, aWidgets);
     432             :   }
     433             : 
     434        1464 :   nsIWidget* widget = aView->GetWidget();
     435        1464 :   if (widget) {
     436          43 :     aWidgets.AppendElement(widget);
     437             :   } else {
     438        1421 :     FlushDirtyRegionToWidget(aView);
     439             :   }
     440             : }
     441             : 
     442             : void
     443          35 : nsViewManager::ProcessPendingUpdatesPaint(nsIWidget* aWidget)
     444             : {
     445          35 :   if (aWidget->NeedsPaint()) {
     446             :     // If an ancestor widget was hidden and then shown, we could
     447             :     // have a delayed resize to handle.
     448          58 :     for (RefPtr<nsViewManager> vm = this; vm;
     449          29 :          vm = vm->mRootView->GetParent()
     450           0 :            ? vm->mRootView->GetParent()->GetViewManager()
     451          29 :            : nullptr) {
     452          87 :       if (vm->mDelayedResize != nsSize(NSCOORD_NONE, NSCOORD_NONE) &&
     453           0 :           vm->mRootView->IsEffectivelyVisible() &&
     454          87 :           vm->mPresShell && vm->mPresShell->IsVisible()) {
     455           0 :         vm->FlushDelayedResize(true);
     456             :       }
     457             :     }
     458          29 :     nsView* view = nsView::GetViewFor(aWidget);
     459             : 
     460          29 :     if (!view) {
     461           0 :       NS_ERROR("FlushDelayedResize destroyed the nsView?");
     462           0 :       return;
     463             :     }
     464             : 
     465          29 :     nsIWidgetListener* previousListener = aWidget->GetPreviouslyAttachedWidgetListener();
     466             : 
     467          29 :     if (previousListener &&
     468          29 :         previousListener != view &&
     469           0 :         view->IsPrimaryFramePaintSuppressed()) {
     470           0 :       return;
     471             :     }
     472             : 
     473          29 :     if (mPresShell) {
     474             : #ifdef MOZ_DUMP_PAINTING
     475          29 :       if (nsLayoutUtils::InvalidationDebuggingIsEnabled()) {
     476           0 :         printf_stderr("---- PAINT START ----PresShell(%p), nsView(%p), nsIWidget(%p)\n",
     477           0 :                       mPresShell, view, aWidget);
     478             :       }
     479             : #endif
     480             : 
     481          29 :       mPresShell->Paint(view, nsRegion(), nsIPresShell::PAINT_LAYERS);
     482          29 :       view->SetForcedRepaint(false);
     483             : 
     484             : #ifdef MOZ_DUMP_PAINTING
     485          29 :       if (nsLayoutUtils::InvalidationDebuggingIsEnabled()) {
     486           0 :         printf_stderr("---- PAINT END ----\n");
     487             :       }
     488             : #endif
     489             :     }
     490             :   }
     491          35 :   FlushDirtyRegionToWidget(nsView::GetViewFor(aWidget));
     492             : }
     493             : 
     494        1456 : void nsViewManager::FlushDirtyRegionToWidget(nsView* aView)
     495             : {
     496        1456 :   NS_ASSERTION(aView->GetViewManager() == this,
     497             :                "FlushDirtyRegionToWidget called on view we don't own");
     498             : 
     499        1456 :   if (!aView->HasNonEmptyDirtyRegion())
     500        1456 :     return;
     501             : 
     502           0 :   nsRegion* dirtyRegion = aView->GetDirtyRegion();
     503           0 :   nsView* nearestViewWithWidget = aView;
     504           0 :   while (!nearestViewWithWidget->HasWidget() &&
     505           0 :          nearestViewWithWidget->GetParent()) {
     506           0 :     nearestViewWithWidget = nearestViewWithWidget->GetParent();
     507             :   }
     508             :   nsRegion r =
     509           0 :     ConvertRegionBetweenViews(*dirtyRegion, aView, nearestViewWithWidget);
     510             : 
     511           0 :   nsViewManager* widgetVM = nearestViewWithWidget->GetViewManager();
     512           0 :   widgetVM->InvalidateWidgetArea(nearestViewWithWidget, r);
     513           0 :   dirtyRegion->SetEmpty();
     514             : }
     515             : 
     516             : void
     517           0 : nsViewManager::InvalidateView(nsView *aView)
     518             : {
     519             :   // Mark the entire view as damaged
     520           0 :   InvalidateView(aView, aView->GetDimensions());
     521           0 : }
     522             : 
     523             : static void
     524           0 : AddDirtyRegion(nsView *aView, const nsRegion &aDamagedRegion)
     525             : {
     526           0 :   nsRegion* dirtyRegion = aView->GetDirtyRegion();
     527           0 :   if (!dirtyRegion)
     528           0 :     return;
     529             : 
     530           0 :   dirtyRegion->Or(*dirtyRegion, aDamagedRegion);
     531           0 :   dirtyRegion->SimplifyOutward(8);
     532             : }
     533             : 
     534             : void
     535          23 : nsViewManager::PostPendingUpdate()
     536             : {
     537          23 :   nsViewManager* rootVM = RootViewManager();
     538          23 :   rootVM->mHasPendingWidgetGeometryChanges = true;
     539          23 :   if (rootVM->mPresShell) {
     540          23 :     rootVM->mPresShell->ScheduleViewManagerFlush();
     541             :   }
     542          23 : }
     543             : 
     544             : /**
     545             :  * @param aDamagedRegion this region, relative to aWidgetView, is invalidated in
     546             :  * every widget child of aWidgetView, plus aWidgetView's own widget
     547             :  */
     548             : void
     549           0 : nsViewManager::InvalidateWidgetArea(nsView *aWidgetView,
     550             :                                     const nsRegion &aDamagedRegion)
     551             : {
     552           0 :   NS_ASSERTION(aWidgetView->GetViewManager() == this,
     553             :                "InvalidateWidgetArea called on view we don't own");
     554           0 :   nsIWidget* widget = aWidgetView->GetWidget();
     555             : 
     556             : #if 0
     557             :   nsRect dbgBounds = aDamagedRegion.GetBounds();
     558             :   printf("InvalidateWidgetArea view:%X (%d) widget:%X region: %d, %d, %d, %d\n",
     559             :     aWidgetView, aWidgetView->IsAttachedToTopLevel(),
     560             :     widget, dbgBounds.x, dbgBounds.y, dbgBounds.width, dbgBounds.height);
     561             : #endif
     562             : 
     563             :   // If the widget is hidden, it don't cover nothing
     564           0 :   if (widget && !widget->IsVisible()) {
     565           0 :     return;
     566             :   }
     567             : 
     568           0 :   if (!widget) {
     569             :     // The root view or a scrolling view might not have a widget
     570             :     // (for example, during printing). We get here when we scroll
     571             :     // during printing to show selected options in a listbox, for example.
     572           0 :     return;
     573             :   }
     574             : 
     575             :   // Update all child widgets with the damage. In the process,
     576             :   // accumulate the union of all the child widget areas, or at least
     577             :   // some subset of that.
     578           0 :   nsRegion children;
     579           0 :   if (widget->GetTransparencyMode() != eTransparencyTransparent) {
     580           0 :     for (nsIWidget* childWidget = widget->GetFirstChild();
     581           0 :          childWidget;
     582             :          childWidget = childWidget->GetNextSibling()) {
     583           0 :       nsView* view = nsView::GetViewFor(childWidget);
     584           0 :       NS_ASSERTION(view != aWidgetView, "will recur infinitely");
     585           0 :       nsWindowType type = childWidget->WindowType();
     586           0 :       if (view && childWidget->IsVisible() && type != eWindowType_popup) {
     587           0 :         NS_ASSERTION(childWidget->IsPlugin(),
     588             :                      "Only plugin or popup widgets can be children!");
     589             : 
     590             :         // We do not need to invalidate in plugin widgets, but we should
     591             :         // exclude them from the invalidation region IF we're not on
     592             :         // Mac. On Mac we need to draw under plugin widgets, because
     593             :         // plugin widgets are basically invisible
     594             : #ifndef XP_MACOSX
     595             :         // GetBounds should compensate for chrome on a toplevel widget
     596           0 :         LayoutDeviceIntRect bounds = childWidget->GetBounds();
     597             : 
     598           0 :         nsTArray<LayoutDeviceIntRect> clipRects;
     599           0 :         childWidget->GetWindowClipRegion(&clipRects);
     600           0 :         for (uint32_t i = 0; i < clipRects.Length(); ++i) {
     601             :           nsRect rr = LayoutDeviceIntRect::ToAppUnits(
     602           0 :             clipRects[i] + bounds.TopLeft(), AppUnitsPerDevPixel());
     603           0 :           children.Or(children, rr - aWidgetView->ViewToWidgetOffset());
     604           0 :           children.SimplifyInward(20);
     605             :         }
     606             : #endif
     607             :       }
     608             :     }
     609             :   }
     610             : 
     611           0 :   nsRegion leftOver;
     612           0 :   leftOver.Sub(aDamagedRegion, children);
     613             : 
     614           0 :   if (!leftOver.IsEmpty()) {
     615           0 :     for (auto iter = leftOver.RectIter(); !iter.Done(); iter.Next()) {
     616           0 :       LayoutDeviceIntRect bounds = ViewToWidget(aWidgetView, iter.Get());
     617           0 :       widget->Invalidate(bounds);
     618             :     }
     619             :   }
     620             : }
     621             : 
     622             : static bool
     623           0 : ShouldIgnoreInvalidation(nsViewManager* aVM)
     624             : {
     625           0 :   while (aVM) {
     626           0 :     nsIPresShell* shell = aVM->GetPresShell();
     627           0 :     if (!shell || shell->ShouldIgnoreInvalidation()) {
     628           0 :       return true;
     629             :     }
     630           0 :     nsView* view = aVM->GetRootView()->GetParent();
     631           0 :     aVM = view ? view->GetViewManager() : nullptr;
     632             :   }
     633           0 :   return false;
     634             : }
     635             : 
     636             : void
     637           0 : nsViewManager::InvalidateView(nsView *aView, const nsRect &aRect)
     638             : {
     639             :   // If painting is suppressed in the presshell or an ancestor drop all
     640             :   // invalidates, it will invalidate everything when it unsuppresses.
     641           0 :   if (ShouldIgnoreInvalidation(this)) {
     642           0 :     return;
     643             :   }
     644             : 
     645           0 :   InvalidateViewNoSuppression(aView, aRect);
     646             : }
     647             : 
     648             : void
     649           0 : nsViewManager::InvalidateViewNoSuppression(nsView *aView,
     650             :                                            const nsRect &aRect)
     651             : {
     652           0 :   NS_PRECONDITION(nullptr != aView, "null view");
     653             : 
     654           0 :   NS_ASSERTION(aView->GetViewManager() == this,
     655             :                "InvalidateViewNoSuppression called on view we don't own");
     656             : 
     657           0 :   nsRect damagedRect(aRect);
     658           0 :   if (damagedRect.IsEmpty()) {
     659           0 :     return;
     660             :   }
     661             : 
     662           0 :   nsView* displayRoot = GetDisplayRootFor(aView);
     663           0 :   nsViewManager* displayRootVM = displayRoot->GetViewManager();
     664             :   // Propagate the update to the displayRoot, since iframes, for example,
     665             :   // can overlap each other and be translucent.  So we have to possibly
     666             :   // invalidate our rect in each of the widgets we have lying about.
     667           0 :   damagedRect.MoveBy(aView->GetOffsetTo(displayRoot));
     668           0 :   int32_t rootAPD = displayRootVM->AppUnitsPerDevPixel();
     669           0 :   int32_t APD = AppUnitsPerDevPixel();
     670           0 :   damagedRect = damagedRect.ScaleToOtherAppUnitsRoundOut(APD, rootAPD);
     671             : 
     672             :   // accumulate this rectangle in the view's dirty region, so we can
     673             :   // process it later.
     674           0 :   AddDirtyRegion(displayRoot, nsRegion(damagedRect));
     675             : }
     676             : 
     677             : void
     678           0 : nsViewManager::InvalidateAllViews()
     679             : {
     680           0 :   if (RootViewManager() != this) {
     681           0 :     return RootViewManager()->InvalidateAllViews();
     682             :   }
     683             : 
     684           0 :   InvalidateViews(mRootView);
     685             : }
     686             : 
     687           0 : void nsViewManager::InvalidateViews(nsView *aView)
     688             : {
     689             :   // Invalidate this view.
     690           0 :   InvalidateView(aView);
     691             : 
     692             :   // Invalidate all children as well.
     693           0 :   nsView* childView = aView->GetFirstChild();
     694           0 :   while (nullptr != childView)  {
     695           0 :     childView->GetViewManager()->InvalidateViews(childView);
     696           0 :     childView = childView->GetNextSibling();
     697             :   }
     698           0 : }
     699             : 
     700           3 : void nsViewManager::WillPaintWindow(nsIWidget* aWidget)
     701             : {
     702           6 :   RefPtr<nsIWidget> widget(aWidget);
     703           3 :   if (widget) {
     704           3 :     nsView* view = nsView::GetViewFor(widget);
     705           3 :     LayerManager* manager = widget->GetLayerManager();
     706           9 :     if (view &&
     707           3 :         (view->ForcedRepaint() || !manager->NeedsWidgetInvalidation())) {
     708           3 :       ProcessPendingUpdates();
     709             :       // Re-get the view pointer here since the ProcessPendingUpdates might have
     710             :       // destroyed it during CallWillPaintOnObservers.
     711           3 :       view = nsView::GetViewFor(widget);
     712           3 :       if (view) {
     713           3 :         view->SetForcedRepaint(false);
     714             :       }
     715             :     }
     716             :   }
     717             : 
     718           6 :   nsCOMPtr<nsIPresShell> shell = mPresShell;
     719           3 :   if (shell) {
     720           3 :     shell->WillPaintWindow();
     721             :   }
     722           3 : }
     723             : 
     724           1 : bool nsViewManager::PaintWindow(nsIWidget* aWidget,
     725             :                                 const LayoutDeviceIntRegion& aRegion)
     726             : {
     727           1 :   if (!aWidget || !mContext)
     728           0 :     return false;
     729             : 
     730           1 :   NS_ASSERTION(IsPaintingAllowed(),
     731             :                "shouldn't be receiving paint events while painting is disallowed!");
     732             : 
     733             :   // Get the view pointer here since NS_WILL_PAINT might have
     734             :   // destroyed it during CallWillPaintOnObservers (bug 378273).
     735           1 :   nsView* view = nsView::GetViewFor(aWidget);
     736           1 :   if (view && !aRegion.IsEmpty()) {
     737           1 :     Refresh(view, aRegion);
     738             :   }
     739             : 
     740           1 :   return true;
     741             : }
     742             : 
     743           3 : void nsViewManager::DidPaintWindow()
     744             : {
     745           6 :   nsCOMPtr<nsIPresShell> shell = mPresShell;
     746           3 :   if (shell) {
     747           3 :     shell->DidPaintWindow();
     748             :   }
     749           3 : }
     750             : 
     751             : void
     752          12 : nsViewManager::DispatchEvent(WidgetGUIEvent *aEvent,
     753             :                              nsView* aView,
     754             :                              nsEventStatus* aStatus)
     755             : {
     756          18 :   AUTO_PROFILER_LABEL("nsViewManager::DispatchEvent", EVENTS);
     757             : 
     758          12 :   WidgetMouseEvent* mouseEvent = aEvent->AsMouseEvent();
     759          24 :   if ((mouseEvent &&
     760             :        // Ignore mouse events that we synthesize.
     761          24 :        mouseEvent->mReason == WidgetMouseEvent::eReal &&
     762             :        // Ignore mouse exit and enter (we'll get moves if the user
     763             :        // is really moving the mouse) since we get them when we
     764             :        // create and destroy widgets.
     765          22 :        mouseEvent->mMessage != eMouseExitFromWidget &&
     766          14 :        mouseEvent->mMessage != eMouseEnterIntoWidget) ||
     767           8 :       aEvent->HasKeyEventMessage() ||
     768          20 :       aEvent->HasIMEEventMessage() ||
     769           4 :       aEvent->mMessage == ePluginInputEvent) {
     770           8 :     gLastUserEventTime = PR_IntervalToMicroseconds(PR_IntervalNow());
     771             :   }
     772             : 
     773             :   // Find the view whose coordinates system we're in.
     774          12 :   nsView* view = aView;
     775          12 :   bool dispatchUsingCoordinates = aEvent->IsUsingCoordinates();
     776          12 :   if (dispatchUsingCoordinates) {
     777             :     // Will dispatch using coordinates. Pretty bogus but it's consistent
     778             :     // with what presshell does.
     779          12 :     view = GetDisplayRootFor(view);
     780             :   }
     781             : 
     782             :   // If the view has no frame, look for a view that does.
     783          12 :   nsIFrame* frame = view->GetFrame();
     784          18 :   if (!frame &&
     785           0 :       (dispatchUsingCoordinates || aEvent->HasKeyEventMessage() ||
     786           0 :        aEvent->IsIMERelatedEvent() ||
     787           0 :        aEvent->IsNonRetargetedNativeEventDelivererForPlugin() ||
     788           0 :        aEvent->HasPluginActivationEventMessage())) {
     789          18 :     while (view && !view->GetFrame()) {
     790           6 :       view = view->GetParent();
     791             :     }
     792             : 
     793           6 :     if (view) {
     794           0 :       frame = view->GetFrame();
     795             :     }
     796             :   }
     797             : 
     798          12 :   if (nullptr != frame) {
     799             :     // Hold a refcount to the presshell. The continued existence of the
     800             :     // presshell will delay deletion of this view hierarchy should the event
     801             :     // want to cause its destruction in, say, some JavaScript event handler.
     802           6 :     nsCOMPtr<nsIPresShell> shell = view->GetViewManager()->GetPresShell();
     803           6 :     if (shell) {
     804           6 :       shell->HandleEvent(frame, aEvent, false, aStatus);
     805           6 :           return;
     806             :     }
     807             :   }
     808             : 
     809           6 :   *aStatus = nsEventStatus_eIgnore;
     810             : }
     811             : 
     812             : // Recursively reparent widgets if necessary
     813             : 
     814           0 : void nsViewManager::ReparentChildWidgets(nsView* aView, nsIWidget *aNewWidget)
     815             : {
     816           0 :   NS_PRECONDITION(aNewWidget, "");
     817             : 
     818           0 :   if (aView->HasWidget()) {
     819             :     // Check to see if the parent widget is the
     820             :     // same as the new parent. If not then reparent
     821             :     // the widget, otherwise there is nothing more
     822             :     // to do for the view and its descendants
     823           0 :     nsIWidget* widget = aView->GetWidget();
     824           0 :     nsIWidget* parentWidget = widget->GetParent();
     825           0 :     if (parentWidget) {
     826             :       // Child widget
     827           0 :       if (parentWidget != aNewWidget) {
     828           0 :         widget->SetParent(aNewWidget);
     829             :       }
     830             :     } else {
     831             :       // Toplevel widget (popup, dialog, etc)
     832           0 :       widget->ReparentNativeWidget(aNewWidget);
     833             :     }
     834           0 :     return;
     835             :   }
     836             : 
     837             :   // Need to check each of the views children to see
     838             :   // if they have a widget and reparent it.
     839             : 
     840           0 :   for (nsView *kid = aView->GetFirstChild(); kid; kid = kid->GetNextSibling()) {
     841           0 :     ReparentChildWidgets(kid, aNewWidget);
     842             :   }
     843             : }
     844             : 
     845             : // Reparent a view and its descendant views widgets if necessary
     846             : 
     847          50 : void nsViewManager::ReparentWidgets(nsView* aView, nsView *aParent)
     848             : {
     849          50 :   NS_PRECONDITION(aParent, "Must have a parent");
     850          50 :   NS_PRECONDITION(aView, "Must have a view");
     851             : 
     852             :   // Quickly determine whether the view has pre-existing children or a
     853             :   // widget. In most cases the view will not have any pre-existing
     854             :   // children when this is called.  Only in the case
     855             :   // where a view has been reparented by removing it from
     856             :   // a reinserting it into a new location in the view hierarchy do we
     857             :   // have to consider reparenting the existing widgets for the view and
     858             :   // it's descendants.
     859          50 :   if (aView->HasWidget() || aView->GetFirstChild()) {
     860           0 :     nsIWidget* parentWidget = aParent->GetNearestWidget(nullptr);
     861           0 :     if (parentWidget) {
     862           0 :       ReparentChildWidgets(aView, parentWidget);
     863           0 :       return;
     864             :     }
     865           0 :     NS_WARNING("Can not find a widget for the parent view");
     866             :   }
     867             : }
     868             : 
     869             : void
     870          50 : nsViewManager::InsertChild(nsView *aParent, nsView *aChild, nsView *aSibling,
     871             :                            bool aAfter)
     872             : {
     873          50 :   NS_PRECONDITION(nullptr != aParent, "null ptr");
     874          50 :   NS_PRECONDITION(nullptr != aChild, "null ptr");
     875          50 :   NS_ASSERTION(aSibling == nullptr || aSibling->GetParent() == aParent,
     876             :                "tried to insert view with invalid sibling");
     877          50 :   NS_ASSERTION(!IsViewInserted(aChild), "tried to insert an already-inserted view");
     878             : 
     879          50 :   if ((nullptr != aParent) && (nullptr != aChild))
     880             :     {
     881             :       // if aAfter is set, we will insert the child after 'prev' (i.e. after 'kid' in document
     882             :       // order, otherwise after 'kid' (i.e. before 'kid' in document order).
     883             : 
     884          50 :       if (nullptr == aSibling) {
     885          47 :         if (aAfter) {
     886             :           // insert at end of document order, i.e., before first view
     887             :           // this is the common case, by far
     888          47 :           aParent->InsertChild(aChild, nullptr);
     889          47 :           ReparentWidgets(aChild, aParent);
     890             :         } else {
     891             :           // insert at beginning of document order, i.e., after last view
     892           0 :           nsView *kid = aParent->GetFirstChild();
     893           0 :           nsView *prev = nullptr;
     894           0 :           while (kid) {
     895           0 :             prev = kid;
     896           0 :             kid = kid->GetNextSibling();
     897             :           }
     898             :           // prev is last view or null if there are no children
     899           0 :           aParent->InsertChild(aChild, prev);
     900           0 :           ReparentWidgets(aChild, aParent);
     901             :         }
     902             :       } else {
     903           3 :         nsView *kid = aParent->GetFirstChild();
     904           3 :         nsView *prev = nullptr;
     905           3 :         while (kid && aSibling != kid) {
     906             :           //get the next sibling view
     907           0 :           prev = kid;
     908           0 :           kid = kid->GetNextSibling();
     909             :         }
     910           3 :         NS_ASSERTION(kid != nullptr,
     911             :                      "couldn't find sibling in child list");
     912           3 :         if (aAfter) {
     913             :           // insert after 'kid' in document order, i.e. before in view order
     914           3 :           aParent->InsertChild(aChild, prev);
     915           3 :           ReparentWidgets(aChild, aParent);
     916             :         } else {
     917             :           // insert before 'kid' in document order, i.e. after in view order
     918           0 :           aParent->InsertChild(aChild, kid);
     919           0 :           ReparentWidgets(aChild, aParent);
     920             :         }
     921             :       }
     922             : 
     923             :       // if the parent view is marked as "floating", make the newly added view float as well.
     924          50 :       if (aParent->GetFloating())
     925           0 :         aChild->SetFloating(true);
     926             :     }
     927          50 : }
     928             : 
     929             : void
     930          12 : nsViewManager::RemoveChild(nsView *aChild)
     931             : {
     932          12 :   NS_ASSERTION(aChild, "aChild must not be null");
     933             : 
     934          12 :   nsView* parent = aChild->GetParent();
     935             : 
     936          12 :   if (nullptr != parent) {
     937          12 :     NS_ASSERTION(aChild->GetViewManager() == this ||
     938             :                  parent->GetViewManager() == this, "wrong view manager");
     939          12 :     parent->RemoveChild(aChild);
     940             :   }
     941          12 : }
     942             : 
     943             : void
     944          38 : nsViewManager::MoveViewTo(nsView *aView, nscoord aX, nscoord aY)
     945             : {
     946          38 :   NS_ASSERTION(aView->GetViewManager() == this, "wrong view manager");
     947          38 :   aView->SetPosition(aX, aY);
     948          38 : }
     949             : 
     950             : void
     951          80 : nsViewManager::ResizeView(nsView *aView, const nsRect &aRect, bool aRepaintExposedAreaOnly)
     952             : {
     953          80 :   NS_ASSERTION(aView->GetViewManager() == this, "wrong view manager");
     954             : 
     955         160 :   nsRect oldDimensions = aView->GetDimensions();
     956          80 :   if (!oldDimensions.IsEqualEdges(aRect)) {
     957           7 :     aView->SetDimensions(aRect, true);
     958             :   }
     959             : 
     960             :   // Note that if layout resizes the view and the view has a custom clip
     961             :   // region set, then we expect layout to update the clip region too. Thus
     962             :   // in the case where mClipRect has been optimized away to just be a null
     963             :   // pointer, and this resize is implicitly changing the clip rect, it's OK
     964             :   // because layout will change it back again if necessary.
     965          80 : }
     966             : 
     967             : void
     968          44 : nsViewManager::SetViewFloating(nsView *aView, bool aFloating)
     969             : {
     970          44 :   NS_ASSERTION(!(nullptr == aView), "no view");
     971             : 
     972          44 :   aView->SetFloating(aFloating);
     973          44 : }
     974             : 
     975             : void
     976           3 : nsViewManager::SetViewVisibility(nsView *aView, nsViewVisibility aVisible)
     977             : {
     978           3 :   NS_ASSERTION(aView->GetViewManager() == this, "wrong view manager");
     979             : 
     980           3 :   if (aVisible != aView->GetVisibility()) {
     981           0 :     aView->SetVisibility(aVisible);
     982             :   }
     983           3 : }
     984             : 
     985          50 : bool nsViewManager::IsViewInserted(nsView *aView)
     986             : {
     987          50 :   if (mRootView == aView) {
     988           0 :     return true;
     989             :   }
     990          50 :   if (aView->GetParent() == nullptr) {
     991           0 :     return false;
     992             :   }
     993          50 :   nsView* view = aView->GetParent()->GetFirstChild();
     994        2088 :   while (view != nullptr) {
     995        1019 :     if (view == aView) {
     996           0 :       return true;
     997             :     }
     998        1019 :     view = view->GetNextSibling();
     999             :   }
    1000          50 :   return false;
    1001             : }
    1002             : 
    1003             : void
    1004          78 : nsViewManager::SetViewZIndex(nsView *aView, bool aAutoZIndex, int32_t aZIndex)
    1005             : {
    1006          78 :   NS_ASSERTION((aView != nullptr), "no view");
    1007             : 
    1008             :   // don't allow the root view's z-index to be changed. It should always be zero.
    1009             :   // This could be removed and replaced with a style rule, or just removed altogether, with interesting consequences
    1010          78 :   if (aView == mRootView) {
    1011          25 :     return;
    1012             :   }
    1013             : 
    1014          53 :   if (aAutoZIndex) {
    1015           9 :     aZIndex = 0;
    1016             :   }
    1017             : 
    1018          53 :   aView->SetZIndex(aAutoZIndex, aZIndex);
    1019             : }
    1020             : 
    1021             : nsViewManager*
    1022          68 : nsViewManager::IncrementDisableRefreshCount()
    1023             : {
    1024          68 :   if (!IsRootVM()) {
    1025           0 :     return RootViewManager()->IncrementDisableRefreshCount();
    1026             :   }
    1027             : 
    1028          68 :   ++mRefreshDisableCount;
    1029             : 
    1030          68 :   return this;
    1031             : }
    1032             : 
    1033             : void
    1034          68 : nsViewManager::DecrementDisableRefreshCount()
    1035             : {
    1036          68 :   NS_ASSERTION(IsRootVM(), "Should only be called on root");
    1037          68 :   --mRefreshDisableCount;
    1038          68 :   NS_ASSERTION(mRefreshDisableCount >= 0, "Invalid refresh disable count!");
    1039          68 : }
    1040             : 
    1041             : void
    1042         277 : nsViewManager::GetRootWidget(nsIWidget **aWidget)
    1043             : {
    1044         277 :   if (!mRootView) {
    1045           0 :     *aWidget = nullptr;
    1046           0 :     return;
    1047             :   }
    1048         277 :   if (mRootView->HasWidget()) {
    1049         233 :     *aWidget = mRootView->GetWidget();
    1050         233 :     NS_ADDREF(*aWidget);
    1051         233 :     return;
    1052             :   }
    1053          44 :   if (mRootView->GetParent()) {
    1054           0 :     mRootView->GetParent()->GetViewManager()->GetRootWidget(aWidget);
    1055           0 :     return;
    1056             :   }
    1057          44 :   *aWidget = nullptr;
    1058             : }
    1059             : 
    1060             : LayoutDeviceIntRect
    1061           0 : nsViewManager::ViewToWidget(nsView* aView, const nsRect& aRect) const
    1062             : {
    1063           0 :   NS_ASSERTION(aView->GetViewManager() == this, "wrong view manager");
    1064             : 
    1065             :   // account for the view's origin not lining up with the widget's
    1066           0 :   nsRect rect = aRect + aView->ViewToWidgetOffset();
    1067             : 
    1068             :   // finally, convert to device coordinates.
    1069             :   return LayoutDeviceIntRect::FromUnknownRect(
    1070           0 :     rect.ToOutsidePixels(AppUnitsPerDevPixel()));
    1071             : }
    1072             : 
    1073             : void
    1074         179 : nsViewManager::IsPainting(bool& aIsPainting)
    1075             : {
    1076         179 :   aIsPainting = IsPainting();
    1077         179 : }
    1078             : 
    1079             : void
    1080          35 : nsViewManager::ProcessPendingUpdates()
    1081             : {
    1082          35 :   if (!IsRootVM()) {
    1083           0 :     RootViewManager()->ProcessPendingUpdates();
    1084           0 :     return;
    1085             :   }
    1086             : 
    1087             :   // Flush things like reflows by calling WillPaint on observer presShells.
    1088          35 :   if (mPresShell) {
    1089          35 :     mPresShell->GetPresContext()->RefreshDriver()->RevokeViewManagerFlush();
    1090             : 
    1091          70 :     RefPtr<nsViewManager> strongThis(this);
    1092          35 :     CallWillPaintOnObservers();
    1093             : 
    1094          35 :     ProcessPendingUpdatesForView(mRootView, true);
    1095             :   }
    1096             : }
    1097             : 
    1098             : void
    1099          56 : nsViewManager::UpdateWidgetGeometry()
    1100             : {
    1101          56 :   if (!IsRootVM()) {
    1102           0 :     RootViewManager()->UpdateWidgetGeometry();
    1103           0 :     return;
    1104             :   }
    1105             : 
    1106          56 :   if (mHasPendingWidgetGeometryChanges) {
    1107           8 :     mHasPendingWidgetGeometryChanges = false;
    1108          16 :     RefPtr<nsViewManager> strongThis(this);
    1109           8 :     ProcessPendingUpdatesForView(mRootView, false);
    1110             :   }
    1111             : }
    1112             : 
    1113             : void
    1114          35 : nsViewManager::CallWillPaintOnObservers()
    1115             : {
    1116          35 :   NS_PRECONDITION(IsRootVM(), "Must be root VM for this to be called!");
    1117             : 
    1118          35 :   if (NS_WARN_IF(!gViewManagers)) {
    1119           0 :     return;
    1120             :   }
    1121             : 
    1122             :   uint32_t index;
    1123         652 :   for (index = 0; index < gViewManagers->Length(); index++) {
    1124         617 :     nsViewManager* vm = gViewManagers->ElementAt(index);
    1125         617 :     if (vm->RootViewManager() == this) {
    1126             :       // One of our kids.
    1127          35 :       if (vm->mRootView && vm->mRootView->IsEffectivelyVisible()) {
    1128          70 :         nsCOMPtr<nsIPresShell> shell = vm->GetPresShell();
    1129          35 :         if (shell) {
    1130          35 :           shell->WillPaint();
    1131             :         }
    1132             :       }
    1133             :     }
    1134             :   }
    1135             : }
    1136             : 
    1137             : void
    1138          58 : nsViewManager::GetLastUserEventTime(uint32_t& aTime)
    1139             : {
    1140          58 :   aTime = gLastUserEventTime;
    1141          58 : }
    1142             : 
    1143             : void
    1144          29 : nsViewManager::InvalidateHierarchy()
    1145             : {
    1146          29 :   if (mRootView) {
    1147          29 :     if (!IsRootVM()) {
    1148           1 :       NS_RELEASE(mRootViewManager);
    1149             :     }
    1150          29 :     nsView *parent = mRootView->GetParent();
    1151          29 :     if (parent) {
    1152           1 :       mRootViewManager = parent->GetViewManager()->RootViewManager();
    1153           1 :       NS_ADDREF(mRootViewManager);
    1154           1 :       NS_ASSERTION(mRootViewManager != this,
    1155             :                    "Root view had a parent, but it has the same view manager");
    1156             :     } else {
    1157          28 :       mRootViewManager = this;
    1158             :     }
    1159             :   }
    1160          29 : }
    1161             : 

Generated by: LCOV version 1.13