Bug 470455 - test_database_sync_embed_visits.js leaks, r=sdwilsh
[wine-gecko.git] / view / src / nsViewManager.h
blob09c6a7771d2b8f74ac4f1f8f2556278d659abe9e
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
13 * License.
15 * The Original Code is mozilla.org code.
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1998
20 * the Initial Developer. All Rights Reserved.
22 * Contributor(s):
24 * Alternatively, the contents of this file may be used under the terms of
25 * either of the GNU General Public License Version 2 or later (the "GPL"),
26 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
38 #ifndef nsViewManager_h___
39 #define nsViewManager_h___
40 #include "nsCOMPtr.h"
41 #include "nsIViewManager.h"
42 #include "nsCRT.h"
43 #include "nsIWidget.h"
44 #include "nsITimer.h"
45 #include "prtime.h"
46 #include "prinrval.h"
47 #include "nsVoidArray.h"
48 #include "nsThreadUtils.h"
49 #include "nsIScrollableView.h"
50 #include "nsIRegion.h"
51 #include "nsView.h"
52 #include "nsIViewObserver.h"
54 //Uncomment the following line to enable generation of viewmanager performance data.
55 #ifdef MOZ_PERF_METRICS
56 //#define NS_VM_PERF_METRICS 1
57 #endif
59 #ifdef NS_VM_PERF_METRICS
60 #include "nsTimer.h"
61 #endif
63 /**
64 Invalidation model:
66 1) Callers call into the view manager and ask it to update a view.
68 2) The view manager finds the "right" widget for the view, henceforth called
69 the root widget.
71 3) The view manager traverses descendants of the root widget and for each
72 one that needs invalidation either
74 a) Calls Invalidate() on the widget (no batching)
76 b) Stores the rect to invalidate on the widget's view (batching)
78 // XXXbz we want to change this a bit. See bug 243726
80 4) When batching, the call to end the batch either processes the pending
81 Invalidate() calls on the widgets or posts an event to do so.
83 It's important to note that widgets associated to views outside this view
84 manager can end up being invalidated during step 3. Therefore, the end of a
85 view update batch really needs to traverse the entire view tree, to ensure
86 that those invalidates happen.
88 To cope with this, invalidate event processing and view update batch
89 handling should only happen on the root viewmanager. This means the root
90 view manager is the only thing keeping track of mUpdateCnt. As a result,
91 Composite() calls should also be forwarded to the root view manager.
94 class nsViewManagerEvent : public nsRunnable {
95 public:
96 nsViewManagerEvent(class nsViewManager *vm) : mViewManager(vm) {
97 NS_ASSERTION(mViewManager, "null parameter");
99 void Revoke() { mViewManager = nsnull; }
100 protected:
101 class nsViewManager *mViewManager;
104 class nsViewManager : public nsIViewManager {
105 public:
106 nsViewManager();
108 NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW
110 NS_DECL_ISUPPORTS
112 NS_IMETHOD Init(nsIDeviceContext* aContext);
114 NS_IMETHOD_(nsIView*) CreateView(const nsRect& aBounds,
115 const nsIView* aParent,
116 nsViewVisibility aVisibilityFlag = nsViewVisibility_kShow);
118 NS_IMETHOD_(nsIScrollableView*) CreateScrollableView(const nsRect& aBounds,
119 const nsIView* aParent);
121 NS_IMETHOD GetRootView(nsIView *&aView);
122 NS_IMETHOD SetRootView(nsIView *aView);
124 NS_IMETHOD GetWindowDimensions(nscoord *width, nscoord *height);
125 NS_IMETHOD SetWindowDimensions(nscoord width, nscoord height);
126 NS_IMETHOD FlushDelayedResize();
128 NS_IMETHOD Composite(void);
130 NS_IMETHOD UpdateView(nsIView *aView, PRUint32 aUpdateFlags);
131 NS_IMETHOD UpdateView(nsIView *aView, const nsRect &aRect, PRUint32 aUpdateFlags);
132 NS_IMETHOD UpdateAllViews(PRUint32 aUpdateFlags);
134 NS_IMETHOD DispatchEvent(nsGUIEvent *aEvent, nsEventStatus* aStatus);
136 NS_IMETHOD GrabMouseEvents(nsIView *aView, PRBool &aResult);
138 NS_IMETHOD GetMouseEventGrabber(nsIView *&aView);
140 NS_IMETHOD InsertChild(nsIView *parent, nsIView *child, nsIView *sibling,
141 PRBool above);
143 NS_IMETHOD InsertChild(nsIView *parent, nsIView *child,
144 PRInt32 zindex);
146 NS_IMETHOD RemoveChild(nsIView *parent);
148 NS_IMETHOD MoveViewBy(nsIView *aView, nscoord aX, nscoord aY);
150 NS_IMETHOD MoveViewTo(nsIView *aView, nscoord aX, nscoord aY);
152 NS_IMETHOD ResizeView(nsIView *aView, const nsRect &aRect, PRBool aRepaintExposedAreaOnly = PR_FALSE);
154 NS_IMETHOD SetViewFloating(nsIView *aView, PRBool aFloating);
156 NS_IMETHOD SetViewVisibility(nsIView *aView, nsViewVisibility aVisible);
158 NS_IMETHOD SetViewZIndex(nsIView *aView, PRBool aAuto, PRInt32 aZIndex, PRBool aTopMost=PR_FALSE);
160 NS_IMETHOD SetViewObserver(nsIViewObserver *aObserver);
161 NS_IMETHOD GetViewObserver(nsIViewObserver *&aObserver);
163 NS_IMETHOD GetDeviceContext(nsIDeviceContext *&aContext);
165 NS_IMETHOD DisableRefresh(void);
166 NS_IMETHOD EnableRefresh(PRUint32 aUpdateFlags);
168 virtual nsIViewManager* BeginUpdateViewBatch(void);
169 NS_IMETHOD EndUpdateViewBatch(PRUint32 aUpdateFlags);
171 NS_IMETHOD SetRootScrollableView(nsIScrollableView *aScrollable);
172 NS_IMETHOD GetRootScrollableView(nsIScrollableView **aScrollable);
174 NS_IMETHOD GetWidget(nsIWidget **aWidget);
175 nsIWidget* GetWidget() { return mRootView ? mRootView->GetWidget() : nsnull; }
176 NS_IMETHOD ForceUpdate();
178 NS_IMETHOD IsPainting(PRBool& aIsPainting);
179 NS_IMETHOD SetDefaultBackgroundColor(nscolor aColor);
180 NS_IMETHOD GetDefaultBackgroundColor(nscolor* aColor);
181 NS_IMETHOD GetLastUserEventTime(PRUint32& aTime);
182 void ProcessInvalidateEvent();
183 static PRUint32 gLastUserEventTime;
186 * Determine if a rectangle specified in the view's coordinate system
187 * is completely, or partially visible.
188 * @param aView view that aRect coordinates are specified relative to
189 * @param aRect rectangle in twips to test for visibility
190 * @param aMinTwips is the min. pixel rows or cols at edge of screen
191 * needed for object to be counted visible
192 * @param aRectVisibility returns eVisible if the rect is visible,
193 * otherwise it returns an enum indicating why not
195 NS_IMETHOD GetRectVisibility(nsIView *aView, const nsRect &aRect,
196 PRUint16 aMinTwips,
197 nsRectVisibility *aRectVisibility);
199 NS_IMETHOD SynthesizeMouseMove(PRBool aFromScroll);
200 void ProcessSynthMouseMoveEvent(PRBool aFromScroll);
202 /* Update the cached RootViewManager pointer on this view manager. */
203 void InvalidateHierarchy();
206 * Enables/disables focus/blur event suppression.
207 * Enabling stops focus/blur events from reaching the widgets.
208 * This should be enabled when we're messing with the frame tree,
209 * so focus/blur handlers don't mess with stuff while we are.
211 * Disabling "reboots" the focus by sending a blur to what was focused
212 * before suppression began, and by sending a focus event to what should
213 * be currently focused. Note this can run arbitrary code, and could
214 * even destroy the view manager.
215 * See Bug 399852.
217 static void SuppressFocusEvents(PRBool aSuppress);
219 PRBool IsFocusSuppressed()
221 return sFocusSuppressed;
224 static void SetCurrentlyFocusedView(nsView *aView)
226 sCurrentlyFocusView = aView;
229 static nsView* GetCurrentlyFocusedView()
231 return sCurrentlyFocusView;
234 static void SetViewFocusedBeforeSuppression(nsView *aView)
236 sViewFocusedBeforeSuppression = aView;
239 static nsView* GetViewFocusedBeforeSuppression()
241 return sViewFocusedBeforeSuppression;
244 protected:
245 virtual ~nsViewManager();
247 private:
249 static nsView *sCurrentlyFocusView;
250 static nsView *sViewFocusedBeforeSuppression;
251 static PRBool sFocusSuppressed;
253 void FlushPendingInvalidates();
254 void ProcessPendingUpdates(nsView *aView, PRBool aDoInvalidate);
255 void ReparentChildWidgets(nsIView* aView, nsIWidget *aNewWidget);
256 void ReparentWidgets(nsIView* aView, nsIView *aParent);
257 already_AddRefed<nsIRenderingContext> CreateRenderingContext(nsView &aView);
258 void UpdateWidgetArea(nsView *aWidgetView, const nsRegion &aDamagedRegion,
259 nsView* aIgnoreWidgetView);
261 void UpdateViews(nsView *aView, PRUint32 aUpdateFlags);
263 void Refresh(nsView *aView, nsIRenderingContext *aContext,
264 nsIRegion *region, PRUint32 aUpdateFlags);
266 * Refresh aView (which must be non-null) with our default background color
268 void DefaultRefresh(nsView* aView, nsIRenderingContext *aContext, const nsRect* aRect);
269 void RenderViews(nsView *aRootView, nsIRenderingContext& aRC,
270 const nsRegion& aRegion);
272 void InvalidateRectDifference(nsView *aView, const nsRect& aRect, const nsRect& aCutOut, PRUint32 aUpdateFlags);
273 void InvalidateHorizontalBandDifference(nsView *aView, const nsRect& aRect, const nsRect& aCutOut,
274 PRUint32 aUpdateFlags, nscoord aY1, nscoord aY2, PRBool aInCutOut);
276 void AddCoveringWidgetsToOpaqueRegion(nsRegion &aRgn, nsIDeviceContext* aContext,
277 nsView* aRootView);
279 // Utilities
281 PRBool IsViewInserted(nsView *aView);
284 * Function to recursively call Update() on all widgets belonging to
285 * a view or its kids.
287 void UpdateWidgetsForView(nsView* aView);
290 * Transforms a rectangle from aView's coordinate system to the coordinate
291 * system of the widget attached to aWidgetView, which should be an ancestor
292 * of aView.
294 void ViewToWidget(nsView *aView, nsView* aWidgetView, nsRect &aRect) const;
297 * Transforms a rectangle from specified view's coordinate system to
298 * an absolute coordinate rectangle which can be compared against the
299 * rectangle returned by GetVisibleRect to determine visibility.
300 * @param aView view that aRect coordinates are specified relative to
301 * @param aRect rectangle in twips to convert to absolute coordinates
302 * @param aAbsRect rectangle in absolute coorindates.
303 * @returns NS_OK if successful otherwise, NS_ERROR_FAILURE
306 nsresult GetAbsoluteRect(nsView *aView, const nsRect &aRect,
307 nsRect& aAbsRect);
309 * Determine the visible rect
310 * @param aVisibleRect visible rectangle in twips
311 * @returns NS_OK if successful, otherwise NS_ERROR_FAILURE.
314 nsresult GetVisibleRect(nsRect& aVisibleRect);
316 void DoSetWindowDimensions(nscoord aWidth, nscoord aHeight)
318 nsRect oldDim;
319 nsRect newDim(0, 0, aWidth, aHeight);
320 mRootView->GetDimensions(oldDim);
321 // We care about resizes even when one dimension is already zero.
322 if (!oldDim.IsExactEqual(newDim)) {
323 // Don't resize the widget. It is already being set elsewhere.
324 mRootView->SetDimensions(newDim, PR_TRUE, PR_FALSE);
325 if (mObserver)
326 mObserver->ResizeReflow(mRootView, aWidth, aHeight);
330 // Safety helpers
331 void IncrementUpdateCount() {
332 NS_ASSERTION(IsRootVM(),
333 "IncrementUpdateCount called on non-root viewmanager");
334 ++mUpdateCnt;
337 void DecrementUpdateCount() {
338 NS_ASSERTION(IsRootVM(),
339 "DecrementUpdateCount called on non-root viewmanager");
340 --mUpdateCnt;
343 PRInt32 UpdateCount() const {
344 NS_ASSERTION(IsRootVM(),
345 "DecrementUpdateCount called on non-root viewmanager");
346 return mUpdateCnt;
349 void ClearUpdateCount() {
350 NS_ASSERTION(IsRootVM(),
351 "DecrementUpdateCount called on non-root viewmanager");
352 mUpdateCnt = 0;
355 PRBool IsPainting() const {
356 return RootViewManager()->mPainting;
359 void SetPainting(PRBool aPainting) {
360 RootViewManager()->mPainting = aPainting;
363 public: // NOT in nsIViewManager, so private to the view module
364 nsView* GetRootView() const { return mRootView; }
365 nsView* GetMouseEventGrabber() const {
366 return RootViewManager()->mMouseGrabber;
368 nsViewManager* RootViewManager() const { return mRootViewManager; }
369 PRBool IsRootVM() const { return this == RootViewManager(); }
371 nsEventStatus HandleEvent(nsView* aView, nsPoint aPoint, nsGUIEvent* aEvent,
372 PRBool aCaptured);
375 * Called to inform the view manager that a view is about to bit-blit.
376 * @param aView the view that will bit-blit
377 * @param aScrollAmount how much aView will scroll by
378 * @return always returns NS_OK
379 * @note
380 * This method used to return void, but MSVC 6.0 SP5 (without the
381 * Processor Pack) and SP6, and the MS eMbedded Visual C++ 4.0 SP4
382 * (for WINCE) hit an internal compiler error when compiling this
383 * method:
385 * @par
386 @verbatim
387 fatal error C1001: INTERNAL COMPILER ERROR
388 (compiler file 'E:\8966\vc98\p2\src\P2\main.c', line 494)
389 @endverbatim
391 * @par
392 * Making the method return nsresult worked around the internal
393 * compiler error. See Bugzilla bug 281158. (The WINCE internal
394 * compiler error was addressed by the patch in bug 291229 comment
395 * 14 although the bug report did not mention the problem.)
397 nsresult WillBitBlit(nsView* aView, nsPoint aScrollAmount);
400 * Called to inform the view manager that a view has scrolled via a
401 * bitblit.
402 * The view manager will invalidate any widgets which may need
403 * to be rerendered.
404 * @param aView view to paint. should be the nsScrollPortView that
405 * got scrolled.
406 * @param aUpdateRegion ensure that this part of the view is repainted
408 void UpdateViewAfterScroll(nsView *aView, const nsRegion& aUpdateRegion);
411 * Asks whether we can scroll a view using bitblt. If we say 'yes', we
412 * return in aUpdateRegion an area that must be updated (relative to aView
413 * after it has been scrolled).
415 PRBool CanScrollWithBitBlt(nsView* aView, nsPoint aDelta, nsRegion* aUpdateRegion);
417 nsresult CreateRegion(nsIRegion* *result);
419 PRBool IsRefreshEnabled() { return RootViewManager()->mRefreshEnabled; }
421 nsIViewObserver* GetViewObserver() { return mObserver; }
423 // Call this when you need to let the viewmanager know that it now has
424 // pending updates.
425 void PostPendingUpdate() { RootViewManager()->mHasPendingUpdates = PR_TRUE; }
426 private:
427 nsIDeviceContext *mContext;
428 nsIViewObserver *mObserver;
429 nsIScrollableView *mRootScrollable;
430 nscolor mDefaultBackgroundColor;
431 nsPoint mMouseLocation; // device units, relative to mRootView
433 // The size for a resize that we delayed until the root view becomes
434 // visible again.
435 nsSize mDelayedResize;
437 nsCOMPtr<nsIFactory> mRegionFactory;
438 nsView *mRootView;
439 // mRootViewManager is a strong ref unless it equals |this|. It's
440 // never null (if we have no ancestors, it will be |this|).
441 nsViewManager *mRootViewManager;
443 nsRevocableEventPtr<nsViewManagerEvent> mSynthMouseMoveEvent;
444 nsRevocableEventPtr<nsViewManagerEvent> mInvalidateEvent;
446 // The following members should not be accessed directly except by
447 // the root view manager. Some have accessor functions to enforce
448 // this, as noted.
450 // Use GrabMouseEvents() and GetMouseEventGrabber() to access mMouseGrabber.
451 nsView *mMouseGrabber;
452 // Use IncrementUpdateCount(), DecrementUpdateCount(), UpdateCount(),
453 // ClearUpdateCount() on the root viewmanager to access mUpdateCnt.
454 PRInt32 mUpdateCnt;
455 PRInt32 mUpdateBatchCnt;
456 PRUint32 mUpdateBatchFlags;
457 PRInt32 mScrollCnt;
458 // Use IsRefreshEnabled() to check the value of mRefreshEnabled.
459 PRPackedBool mRefreshEnabled;
460 // Use IsPainting() and SetPainting() to access mPainting.
461 PRPackedBool mPainting;
462 PRPackedBool mRecursiveRefreshPending;
463 PRPackedBool mHasPendingUpdates;
464 PRPackedBool mInScroll;
466 //from here to public should be static and locked... MMP
467 static PRInt32 mVMCount; //number of viewmanagers
469 //Rendering context used to cleanup the blending buffers
470 static nsIRenderingContext* gCleanupContext;
472 //list of view managers
473 static nsVoidArray *gViewManagers;
475 void PostInvalidateEvent();
477 #ifdef NS_VM_PERF_METRICS
478 MOZ_TIMER_DECLARE(mWatch) // Measures compositing+paint time for current document
479 #endif
482 //when the refresh happens, should it be double buffered?
483 #define NS_VMREFRESH_DOUBLE_BUFFER 0x0001
485 #endif /* nsViewManager_h___ */