LCOV - code coverage report
Current view: top level - view - nsViewManager.h (source / functions) Hit Total Coverage
Test: output.info Lines: 25 26 96.2 %
Date: 2017-07-14 16:53:18 Functions: 15 16 93.8 %
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             : #ifndef nsViewManager_h___
       7             : #define nsViewManager_h___
       8             : 
       9             : #include "nscore.h"
      10             : #include "nsView.h"
      11             : #include "nsCOMPtr.h"
      12             : #include "nsCRT.h"
      13             : #include "nsTArray.h"
      14             : #include "nsDeviceContext.h"
      15             : #include "nsTArray.h"
      16             : #include "mozilla/EventForwards.h"
      17             : 
      18             : class nsIWidget;
      19             : struct nsRect;
      20             : class nsRegion;
      21             : class nsDeviceContext;
      22             : class nsIPresShell;
      23             : 
      24             : class nsViewManager final
      25             : {
      26             :   ~nsViewManager();
      27             : public:
      28             :   friend class nsView;
      29             : 
      30             :   typedef mozilla::LayoutDeviceIntRect LayoutDeviceIntRect;
      31             :   typedef mozilla::LayoutDeviceIntRegion LayoutDeviceIntRegion;
      32             : 
      33         708 :   NS_INLINE_DECL_REFCOUNTING(nsViewManager)
      34             : 
      35             :   nsViewManager();
      36             : 
      37             :   /**
      38             :    * Initialize the ViewManager
      39             :    * Note: this instance does not hold a reference to the presshell
      40             :    * because it holds a reference to this instance.
      41             :    * @result The result of the initialization, NS_OK if no errors
      42             :    */
      43             :   nsresult Init(nsDeviceContext* aContext);
      44             : 
      45             :   /**
      46             :    * Create an ordinary view
      47             :    * @param aBounds initial bounds for view
      48             :    *        XXX We should eliminate this parameter; you can set the bounds after CreateView
      49             :    * @param aParent intended parent for view. this is not actually set in the
      50             :    *        nsView through this method. it is only used by the initialization
      51             :    *        code to walk up the view tree, if necessary, to find resources.
      52             :    *        XXX We should eliminate this parameter!
      53             :    * @param aVisibilityFlag initial visibility state of view
      54             :    *        XXX We should eliminate this parameter; you can set it after CreateView
      55             :    * @result The new view.  Never null.
      56             :    */
      57             :   nsView* CreateView(const nsRect& aBounds,
      58             :                      nsView* aParent,
      59             :                      nsViewVisibility aVisibilityFlag = nsViewVisibility_kShow);
      60             : 
      61             :   /**
      62             :    * Get the root of the view tree.
      63             :    * @result the root view
      64             :    */
      65       16983 :   nsView* GetRootView() { return mRootView; }
      66             : 
      67             :   /**
      68             :    * Set the root of the view tree. Does not destroy the current root view.
      69             :    * aView may have a parent view managed by a different view manager.
      70             :    * aView may have a widget (anything but printing) or may not (printing).
      71             :    * @param aView view to set as root
      72             :    */
      73             :   void SetRootView(nsView *aView);
      74             : 
      75             :   /**
      76             :    * Get the dimensions of the root window. The dimensions are in
      77             :    * twips
      78             :    * @param aWidth out parameter for width of window in twips
      79             :    * @param aHeight out parameter for height of window in twips
      80             :    */
      81             :   void GetWindowDimensions(nscoord *aWidth, nscoord *aHeight);
      82             : 
      83             :   /**
      84             :    * Set the dimensions of the root window.
      85             :    * Called if the root window is resized. The dimensions are in
      86             :    * twips
      87             :    * @param aWidth of window in twips
      88             :    * @param aHeight of window in twips
      89             :    */
      90             :   void SetWindowDimensions(nscoord aWidth, nscoord aHeight,
      91             :                            bool aDelayResize = false);
      92             : 
      93             :   /**
      94             :    * Do any resizes that are pending.
      95             :    */
      96             :   void FlushDelayedResize(bool aDoReflow);
      97             : 
      98             :   /**
      99             :    * Called to inform the view manager that the entire area of a view
     100             :    * is dirty and needs to be redrawn.
     101             :    * @param aView view to paint. should be root view
     102             :    */
     103             :   void InvalidateView(nsView *aView);
     104             : 
     105             :   /**
     106             :    * Called to inform the view manager that some portion of a view is dirty and
     107             :    * needs to be redrawn. The rect passed in should be in the view's coordinate
     108             :    * space. Does not check for paint suppression.
     109             :    * @param aView view to paint. should be root view
     110             :    * @param rect rect to mark as damaged
     111             :    */
     112             :   void InvalidateViewNoSuppression(nsView *aView, const nsRect &aRect);
     113             : 
     114             :   /**
     115             :    * Called to inform the view manager that it should invalidate all views.
     116             :    */
     117             :   void InvalidateAllViews();
     118             : 
     119             :   /**
     120             :    * Called to dispatch an event to the appropriate view. Often called
     121             :    * as a result of receiving a mouse or keyboard event from the widget
     122             :    * event system.
     123             :    * @param aEvent event to dispatch
     124             :    * @param aViewTarget dispatch the event to this view
     125             :    * @param aStatus event handling status
     126             :    */
     127             :   void DispatchEvent(mozilla::WidgetGUIEvent *aEvent,
     128             :                      nsView* aViewTarget,
     129             :                      nsEventStatus* aStatus);
     130             : 
     131             :   /**
     132             :    * Given a parent view, insert another view as its child.
     133             :    * aSibling and aAbove control the "document order" for the insertion.
     134             :    * If aSibling is null, the view is inserted at the end of the document order
     135             :    * if aAfter is true, otherwise it is inserted at the beginning.
     136             :    * If aSibling is non-null, then if aAfter is true, the view is inserted
     137             :    * after the sibling in document order (appearing above the sibling unless
     138             :    * overriden by z-order).
     139             :    * If it is false, the view is inserted before the sibling.
     140             :    * The view manager generates the appopriate dirty regions.
     141             :    * @param aParent parent view
     142             :    * @param aChild child view
     143             :    * @param aSibling sibling view
     144             :    * @param aAfter after or before in the document order
     145             :    */
     146             :   void InsertChild(nsView *aParent, nsView *aChild, nsView *aSibling,
     147             :                    bool aAfter);
     148             : 
     149             :   /**
     150             :    * Remove a specific child view from its parent. This will NOT remove its placeholder
     151             :    * if there is one.
     152             :    * The view manager generates the appropriate dirty regions.
     153             :    * @param aParent parent view
     154             :    * @param aChild child view
     155             :    */
     156             :   void RemoveChild(nsView *aChild);
     157             : 
     158             :   /**
     159             :    * Move a view to the specified position, provided in parent coordinates.
     160             :    * The new position is the (0, 0) origin for the view's coordinate system.
     161             :    * The view's bounds may extend above or to the left of this point.
     162             :    * The view manager generates the appropriate dirty regions.
     163             :    * @param aView view to move
     164             :    * @param aX x value for new view position
     165             :    * @param aY y value for new view position
     166             :    */
     167             :   void MoveViewTo(nsView *aView, nscoord aX, nscoord aY);
     168             : 
     169             :   /**
     170             :    * Resize a view. In addition to setting the width and height, you can
     171             :    * set the x and y of its bounds relative to its position. Negative x and y
     172             :    * will let the view extend above and to the left of the (0,0) point in its
     173             :    * coordinate system.
     174             :    * The view manager generates the appropriate dirty regions.
     175             :    * @param aView view to move
     176             :    * @param the new bounds relative to the current position
     177             :    * @param RepaintExposedAreaOnly
     178             :    *     if true Repaint only the expanded or contracted region,
     179             :    *     if false Repaint the union of the old and new rectangles.
     180             :    */
     181             :   void ResizeView(nsView *aView, const nsRect &aRect,
     182             :                   bool aRepaintExposedAreaOnly = false);
     183             : 
     184             :   /**
     185             :    * Set the visibility of a view. Hidden views have the effect of hiding
     186             :    * their descendants as well. This does not affect painting, so layout
     187             :    * is responsible for ensuring that content in hidden views is not
     188             :    * painted nor handling events. It does affect the visibility of widgets;
     189             :    * if a view is hidden, descendant views with widgets have their widgets
     190             :    * hidden.
     191             :    * The view manager generates the appropriate dirty regions.
     192             :    * @param aView view to change visibility state of
     193             :    * @param visible new visibility state
     194             :    */
     195             :   void SetViewVisibility(nsView *aView, nsViewVisibility aVisible);
     196             : 
     197             :   /**
     198             :    * Set the z-index of a view. Positive z-indices mean that a view
     199             :    * is above its parent in z-order. Negative z-indices mean that a
     200             :    * view is below its parent.
     201             :    * The view manager generates the appropriate dirty regions.
     202             :    * @param aAutoZIndex indicate that the z-index of a view is "auto". An "auto" z-index
     203             :    * means that the view does not define a new stacking context,
     204             :    * which means that the z-indicies of the view's children are
     205             :    * relative to the view's siblings.
     206             :    * @param aView view to change z depth of
     207             :    * @param aZindex explicit z depth
     208             :    */
     209             :   void SetViewZIndex(nsView *aView, bool aAutoZIndex, int32_t aZindex);
     210             : 
     211             :   /**
     212             :    * Set whether the view "floats" above all other views,
     213             :    * which tells the compositor not to consider higher views in
     214             :    * the view hierarchy that would geometrically intersect with
     215             :    * this view. This is a hack, but it fixes some problems with
     216             :    * views that need to be drawn in front of all other views.
     217             :    */
     218             :   void SetViewFloating(nsView *aView, bool aFloatingView);
     219             : 
     220             :   /**
     221             :    * Set the presshell associated with this manager
     222             :    * @param aPresShell - new presshell
     223             :    */
     224          32 :   void SetPresShell(nsIPresShell *aPresShell) { mPresShell = aPresShell; }
     225             : 
     226             :   /**
     227             :    * Get the pres shell associated with this manager
     228             :    */
     229         110 :   nsIPresShell* GetPresShell() { return mPresShell; }
     230             : 
     231             :   /**
     232             :    * Get the device context associated with this manager
     233             :    */
     234           4 :   nsDeviceContext* GetDeviceContext() const
     235             :   {
     236           4 :     return mContext;
     237             :   }
     238             : 
     239             :   /**
     240             :    * A stack class for disallowing changes that would enter painting. For
     241             :    * example, popup widgets shouldn't be resized during reflow, since doing so
     242             :    * might cause synchronous painting inside reflow which is forbidden.
     243             :    * While refresh is disabled, widget geometry changes are deferred and will
     244             :    * be handled later, either from the refresh driver or from an NS_WILL_PAINT
     245             :    * event.
     246             :    * We don't want to defer widget geometry changes all the time. Resizing a
     247             :    * popup from script doesn't need to be deferred, for example, especially
     248             :    * since popup widget geometry is observable from script and expected to
     249             :    * update synchronously.
     250             :    */
     251             :   class MOZ_STACK_CLASS AutoDisableRefresh {
     252             :   public:
     253          68 :     explicit AutoDisableRefresh(nsViewManager* aVM) {
     254          68 :       if (aVM) {
     255          68 :         mRootVM = aVM->IncrementDisableRefreshCount();
     256             :       }
     257          68 :     }
     258         136 :     ~AutoDisableRefresh() {
     259          68 :       if (mRootVM) {
     260          68 :         mRootVM->DecrementDisableRefreshCount();
     261             :       }
     262          68 :     }
     263             :   private:
     264             :     AutoDisableRefresh(const AutoDisableRefresh& aOther);
     265             :     const AutoDisableRefresh& operator=(const AutoDisableRefresh& aOther);
     266             : 
     267             :     RefPtr<nsViewManager> mRootVM;
     268             :   };
     269             : 
     270             : private:
     271             :   friend class AutoDisableRefresh;
     272             : 
     273             :   nsViewManager* IncrementDisableRefreshCount();
     274             :   void DecrementDisableRefreshCount();
     275             : 
     276             : public:
     277             :   /**
     278             :    * Retrieve the widget at the root of the nearest enclosing
     279             :    * view manager whose root view has a widget.
     280             :    */
     281             :   void GetRootWidget(nsIWidget **aWidget);
     282             : 
     283             :   /**
     284             :    * Indicate whether the viewmanager is currently painting
     285             :    *
     286             :    * @param aPainting true if the viewmanager is painting
     287             :    *                  false otherwise
     288             :    */
     289             :   void IsPainting(bool& aIsPainting);
     290             : 
     291             :   /**
     292             :    * Retrieve the time of the last user event. User events
     293             :    * include mouse and keyboard events. The viewmanager
     294             :    * saves the time of the last user event.
     295             :    *
     296             :    * @param aTime Last user event time in microseconds
     297             :    */
     298             :   void GetLastUserEventTime(uint32_t& aTime);
     299             : 
     300             :   /**
     301             :    * Find the nearest display root view for the view aView. This is the view for
     302             :    * the nearest enclosing popup or the root view for the root document.
     303             :    */
     304             :   static nsView* GetDisplayRootFor(nsView* aView);
     305             : 
     306             :   /**
     307             :    * Flush the accumulated dirty region to the widget and update widget
     308             :    * geometry.
     309             :    */
     310             :   void ProcessPendingUpdates();
     311             : 
     312             :   /**
     313             :    * Just update widget geometry without flushing the dirty region
     314             :    */
     315             :   void UpdateWidgetGeometry();
     316             : 
     317        1863 :   int32_t AppUnitsPerDevPixel() const
     318             :   {
     319        1863 :     return mContext->AppUnitsPerDevPixel();
     320             :   }
     321             : 
     322           0 :   void SetPrintRelated() { mPrintRelated = true; }
     323          15 :   bool GetPrintRelated() { return mPrintRelated; }
     324             : 
     325             : private:
     326             :   static uint32_t gLastUserEventTime;
     327             : 
     328             :   /* Update the cached RootViewManager pointer on this view manager. */
     329             :   void InvalidateHierarchy();
     330             :   void FlushPendingInvalidates();
     331             : 
     332             :   void ProcessPendingUpdatesForView(nsView *aView,
     333             :                                     bool aFlushDirtyRegion = true);
     334             :   void ProcessPendingUpdatesRecurse(nsView* aView,
     335             :                                     AutoTArray<nsCOMPtr<nsIWidget>, 1>& aWidgets);
     336             :   void ProcessPendingUpdatesPaint(nsIWidget* aWidget);
     337             : 
     338             :   void FlushDirtyRegionToWidget(nsView* aView);
     339             :   /**
     340             :    * Call WillPaint() on all view observers under this vm root.
     341             :    */
     342             :   void CallWillPaintOnObservers();
     343             :   void ReparentChildWidgets(nsView* aView, nsIWidget *aNewWidget);
     344             :   void ReparentWidgets(nsView* aView, nsView *aParent);
     345             :   void InvalidateWidgetArea(nsView *aWidgetView, const nsRegion &aDamagedRegion);
     346             : 
     347             :   void InvalidateViews(nsView *aView);
     348             : 
     349             :   // aView is the view for aWidget and aRegion is relative to aWidget.
     350             :   void Refresh(nsView* aView, const LayoutDeviceIntRegion& aRegion);
     351             : 
     352             :   // Utilities
     353             : 
     354             :   bool IsViewInserted(nsView *aView);
     355             : 
     356             :   /**
     357             :    * Intersects aRect with aView's bounds and then transforms it from aView's
     358             :    * coordinate system to the coordinate system of the widget attached to
     359             :    * aView.
     360             :    */
     361             :   LayoutDeviceIntRect ViewToWidget(nsView* aView, const nsRect& aRect) const;
     362             : 
     363             :   void DoSetWindowDimensions(nscoord aWidth, nscoord aHeight);
     364             :   bool ShouldDelayResize() const;
     365             : 
     366         181 :   bool IsPainting() const {
     367         181 :     return RootViewManager()->mPainting;
     368             :   }
     369             : 
     370          72 :   void SetPainting(bool aPainting) {
     371          72 :     RootViewManager()->mPainting = aPainting;
     372          72 :   }
     373             : 
     374             :   void InvalidateView(nsView *aView, const nsRect &aRect);
     375             : 
     376        1234 :   nsViewManager* RootViewManager() const { return mRootViewManager; }
     377         338 :   bool IsRootVM() const { return this == RootViewManager(); }
     378             : 
     379             :   // Whether synchronous painting is allowed at the moment. For example,
     380             :   // widget geometry changes can cause synchronous painting, so they need to
     381             :   // be deferred while refresh is disabled.
     382           1 :   bool IsPaintingAllowed() { return RootViewManager()->mRefreshDisableCount == 0; }
     383             : 
     384             :   void WillPaintWindow(nsIWidget* aWidget);
     385             :   bool PaintWindow(nsIWidget* aWidget, const LayoutDeviceIntRegion& aRegion);
     386             :   void DidPaintWindow();
     387             : 
     388             :   // Call this when you need to let the viewmanager know that it now has
     389             :   // pending updates.
     390             :   void PostPendingUpdate();
     391             : 
     392             :   RefPtr<nsDeviceContext> mContext;
     393             :   nsIPresShell   *mPresShell;
     394             : 
     395             :   // The size for a resize that we delayed until the root view becomes
     396             :   // visible again.
     397             :   nsSize            mDelayedResize;
     398             : 
     399             :   nsView           *mRootView;
     400             :   // mRootViewManager is a strong ref unless it equals |this|.  It's
     401             :   // never null (if we have no ancestors, it will be |this|).
     402             :   nsViewManager   *mRootViewManager;
     403             : 
     404             :   // The following members should not be accessed directly except by
     405             :   // the root view manager.  Some have accessor functions to enforce
     406             :   // this, as noted.
     407             : 
     408             :   int32_t           mRefreshDisableCount;
     409             :   // Use IsPainting() and SetPainting() to access mPainting.
     410             :   bool              mPainting;
     411             :   bool              mRecursiveRefreshPending;
     412             :   bool              mHasPendingWidgetGeometryChanges;
     413             :   bool              mPrintRelated;
     414             : 
     415             :   //from here to public should be static and locked... MMP
     416             : 
     417             :   //list of view managers
     418             :   static nsTArray<nsViewManager*> *gViewManagers;
     419             : };
     420             : 
     421             : /**
     422             :    Invalidation model:
     423             : 
     424             :    1) Callers call into the view manager and ask it to invalidate a view.
     425             : 
     426             :    2) The view manager finds the "right" widget for the view, henceforth called
     427             :       the root widget.
     428             : 
     429             :    3) The view manager traverses descendants of the root widget and for each
     430             :       one that needs invalidation stores the rect to invalidate on the widget's
     431             :       view (batching).
     432             : 
     433             :    4) The dirty region is flushed to the right widget when
     434             :       ProcessPendingUpdates is called from the RefreshDriver.
     435             : 
     436             :    It's important to note that widgets associated to views outside this view
     437             :    manager can end up being invalidated during step 3.  Therefore, the end of a
     438             :    view update batch really needs to traverse the entire view tree, to ensure
     439             :    that those invalidates happen.
     440             : 
     441             :    To cope with this, invalidation processing and should only happen on the
     442             :    root viewmanager.
     443             : */
     444             : 
     445             : #endif  // nsViewManager_h___

Generated by: LCOV version 1.13