Line data Source code
1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 : * vim: set ts=2 sw=2 et tw=78:
3 : * This Source Code Form is subject to the terms of the Mozilla Public
4 : * License, v. 2.0. If a copy of the MPL was not distributed with this
5 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
6 : *
7 : * This Original Code has been modified by IBM Corporation.
8 : * Modifications made by IBM described herein are
9 : * Copyright (c) International Business Machines
10 : * Corporation, 2000
11 : *
12 : * Modifications to Mozilla code or documentation
13 : * identified per MPL Section 3.3
14 : *
15 : * Date Modified by Description of modification
16 : * 05/03/2000 IBM Corp. Observer events for reflow states
17 : */
18 :
19 : /* a presentation of a document, part 2 */
20 :
21 : #ifndef mozilla_PresShell_h
22 : #define mozilla_PresShell_h
23 :
24 : #include "MobileViewportManager.h"
25 : #include "mozilla/Attributes.h"
26 : #include "mozilla/EventForwards.h"
27 : #include "mozilla/MemoryReporting.h"
28 : #include "mozilla/StyleSetHandle.h"
29 : #include "mozilla/UniquePtr.h"
30 : #include "nsAutoPtr.h"
31 : #include "nsContentUtils.h" // For AddScriptBlocker().
32 : #include "nsCRT.h"
33 : #include "nsIObserver.h"
34 : #include "nsIPresShell.h"
35 : #include "nsISelectionController.h"
36 : #include "nsIWidget.h"
37 : #include "nsPresContext.h"
38 : #include "nsRefreshDriver.h"
39 : #include "nsStubDocumentObserver.h"
40 : #include "nsThreadUtils.h"
41 : #include "nsWeakReference.h"
42 : #include "TouchManager.h"
43 : #include "ZoomConstraintsClient.h"
44 :
45 : class nsIDocShell;
46 : class nsRange;
47 :
48 : struct RangePaintInfo;
49 : struct nsCallbackEventRequest;
50 : #ifdef MOZ_REFLOW_PERF
51 : class ReflowCountMgr;
52 : #endif
53 :
54 : class nsPresShellEventCB;
55 : class nsAutoCauseReflowNotifier;
56 :
57 : namespace mozilla {
58 :
59 : namespace dom {
60 : class Element;
61 : } // namespace dom
62 :
63 : class EventDispatchingCallback;
64 :
65 : // A set type for tracking visible frames, for use by the visibility code in
66 : // PresShell. The set contains nsIFrame* pointers.
67 : typedef nsTHashtable<nsPtrHashKey<nsIFrame>> VisibleFrames;
68 :
69 : // A hash table type for tracking visible regions, for use by the visibility
70 : // code in PresShell. The mapping is from view IDs to regions in the
71 : // coordinate system of that view's scrolled frame.
72 : typedef nsClassHashtable<nsUint64HashKey, mozilla::CSSIntRegion> VisibleRegions;
73 :
74 : // This is actually pref-controlled, but we use this value if we fail
75 : // to get the pref for any reason.
76 : #ifdef MOZ_WIDGET_ANDROID
77 : #define PAINTLOCK_EVENT_DELAY 250
78 : #else
79 : #define PAINTLOCK_EVENT_DELAY 5
80 : #endif
81 :
82 : class PresShell final : public nsIPresShell,
83 : public nsStubDocumentObserver,
84 : public nsISelectionController,
85 : public nsIObserver,
86 : public nsSupportsWeakReference
87 : {
88 : public:
89 : PresShell();
90 :
91 : // nsISupports
92 : NS_DECL_ISUPPORTS
93 :
94 : static bool AccessibleCaretEnabled(nsIDocShell* aDocShell);
95 :
96 : void Init(nsIDocument* aDocument, nsPresContext* aPresContext,
97 : nsViewManager* aViewManager, mozilla::StyleSetHandle aStyleSet);
98 : virtual void Destroy() override;
99 :
100 : virtual void UpdatePreferenceStyles() override;
101 :
102 : NS_IMETHOD GetSelection(RawSelectionType aRawSelectionType,
103 : nsISelection** aSelection) override;
104 : virtual mozilla::dom::Selection*
105 : GetCurrentSelection(SelectionType aSelectionType) override;
106 : virtual already_AddRefed<nsISelectionController>
107 : GetSelectionControllerForFocusedContent(
108 : nsIContent** aFocusedContent = nullptr) override;
109 :
110 : NS_IMETHOD SetDisplaySelection(int16_t aToggle) override;
111 : NS_IMETHOD GetDisplaySelection(int16_t *aToggle) override;
112 : NS_IMETHOD ScrollSelectionIntoView(RawSelectionType aRawSelectionType,
113 : SelectionRegion aRegion,
114 : int16_t aFlags) override;
115 : NS_IMETHOD RepaintSelection(RawSelectionType aRawSelectionType) override;
116 :
117 : virtual void BeginObservingDocument() override;
118 : virtual void EndObservingDocument() override;
119 : virtual nsresult Initialize(nscoord aWidth, nscoord aHeight) override;
120 : virtual nsresult ResizeReflow(nscoord aWidth, nscoord aHeight, nscoord aOldWidth = 0, nscoord aOldHeight = 0) override;
121 : virtual nsresult ResizeReflowIgnoreOverride(nscoord aWidth, nscoord aHeight, nscoord aOldWidth, nscoord aOldHeight) override;
122 : virtual nsIPageSequenceFrame* GetPageSequenceFrame() const override;
123 : virtual nsCanvasFrame* GetCanvasFrame() const override;
124 :
125 : virtual void FrameNeedsReflow(nsIFrame *aFrame, IntrinsicDirty aIntrinsicDirty,
126 : nsFrameState aBitToAdd,
127 : ReflowRootHandling aRootHandling =
128 : eInferFromBitToAdd) override;
129 : virtual void FrameNeedsToContinueReflow(nsIFrame *aFrame) override;
130 : virtual void CancelAllPendingReflows() override;
131 : virtual bool IsSafeToFlush() const override;
132 : virtual void DoFlushPendingNotifications(mozilla::FlushType aType) override;
133 : virtual void DoFlushPendingNotifications(mozilla::ChangesToFlush aType) override;
134 : virtual void DestroyFramesFor(nsIContent* aContent,
135 : nsIContent** aDestroyedFramesFor) override;
136 : virtual void CreateFramesFor(nsIContent* aContent) override;
137 :
138 : /**
139 : * Post a callback that should be handled after reflow has finished.
140 : */
141 : virtual nsresult PostReflowCallback(nsIReflowCallback* aCallback) override;
142 : virtual void CancelReflowCallback(nsIReflowCallback* aCallback) override;
143 :
144 : virtual void ClearFrameRefs(nsIFrame* aFrame) override;
145 : virtual already_AddRefed<gfxContext> CreateReferenceRenderingContext() override;
146 : virtual nsresult GoToAnchor(const nsAString& aAnchorName, bool aScroll,
147 : uint32_t aAdditionalScrollFlags = 0) override;
148 : virtual nsresult ScrollToAnchor() override;
149 :
150 : virtual nsresult ScrollContentIntoView(nsIContent* aContent,
151 : ScrollAxis aVertical,
152 : ScrollAxis aHorizontal,
153 : uint32_t aFlags) override;
154 : virtual bool ScrollFrameRectIntoView(nsIFrame* aFrame,
155 : const nsRect& aRect,
156 : ScrollAxis aVertical,
157 : ScrollAxis aHorizontal,
158 : uint32_t aFlags) override;
159 : virtual nsRectVisibility GetRectVisibility(nsIFrame *aFrame,
160 : const nsRect &aRect,
161 : nscoord aMinTwips) const override;
162 :
163 : virtual void SetIgnoreFrameDestruction(bool aIgnore) override;
164 : virtual void NotifyDestroyingFrame(nsIFrame* aFrame) override;
165 :
166 : virtual nsresult CaptureHistoryState(nsILayoutHistoryState** aLayoutHistoryState) override;
167 :
168 : virtual void UnsuppressPainting() override;
169 :
170 : virtual nsresult GetAgentStyleSheets(
171 : nsTArray<RefPtr<mozilla::StyleSheet>>& aSheets) override;
172 : virtual nsresult SetAgentStyleSheets(
173 : const nsTArray<RefPtr<mozilla::StyleSheet>>& aSheets) override;
174 :
175 : virtual nsresult AddOverrideStyleSheet(mozilla::StyleSheet* aSheet) override;
176 : virtual nsresult RemoveOverrideStyleSheet(mozilla::StyleSheet* aSheet) override;
177 :
178 : virtual nsresult HandleEventWithTarget(
179 : mozilla::WidgetEvent* aEvent,
180 : nsIFrame* aFrame,
181 : nsIContent* aContent,
182 : nsEventStatus* aStatus) override;
183 : virtual nsIFrame* GetEventTargetFrame() override;
184 : virtual already_AddRefed<nsIContent> GetEventTargetContent(
185 : mozilla::WidgetEvent* aEvent) override;
186 :
187 : virtual void NotifyCounterStylesAreDirty() override;
188 :
189 : virtual void ReconstructFrames(void) override;
190 : virtual void Freeze() override;
191 : virtual void Thaw() override;
192 : virtual void FireOrClearDelayedEvents(bool aFireEvents) override;
193 :
194 : virtual nsresult RenderDocument(const nsRect& aRect, uint32_t aFlags,
195 : nscolor aBackgroundColor,
196 : gfxContext* aThebesContext) override;
197 :
198 : virtual already_AddRefed<SourceSurface>
199 : RenderNode(nsIDOMNode* aNode,
200 : nsIntRegion* aRegion,
201 : const mozilla::LayoutDeviceIntPoint aPoint,
202 : mozilla::LayoutDeviceIntRect* aScreenRect,
203 : uint32_t aFlags) override;
204 :
205 : virtual already_AddRefed<SourceSurface>
206 : RenderSelection(nsISelection* aSelection,
207 : const mozilla::LayoutDeviceIntPoint aPoint,
208 : mozilla::LayoutDeviceIntRect* aScreenRect,
209 : uint32_t aFlags) override;
210 :
211 : virtual already_AddRefed<nsPIDOMWindowOuter> GetRootWindow() override;
212 :
213 : virtual already_AddRefed<nsPIDOMWindowOuter> GetFocusedDOMWindowInOurWindow() override;
214 :
215 : virtual LayerManager* GetLayerManager() override;
216 :
217 : virtual bool AsyncPanZoomEnabled() override;
218 :
219 : virtual void SetIgnoreViewportScrolling(bool aIgnore) override;
220 :
221 0 : virtual nsresult SetResolution(float aResolution) override {
222 0 : return SetResolutionImpl(aResolution, /* aScaleToResolution = */ false);
223 : }
224 0 : virtual nsresult SetResolutionAndScaleTo(float aResolution) override {
225 0 : return SetResolutionImpl(aResolution, /* aScaleToResolution = */ true);
226 : }
227 : virtual bool ScaleToResolution() const override;
228 : virtual float GetCumulativeResolution() override;
229 : virtual float GetCumulativeNonRootScaleResolution() override;
230 : virtual void SetRestoreResolution(float aResolution,
231 : mozilla::LayoutDeviceIntSize aDisplaySize) override;
232 :
233 : //nsIViewObserver interface
234 :
235 : virtual void Paint(nsView* aViewToPaint, const nsRegion& aDirtyRegion,
236 : uint32_t aFlags) override;
237 : virtual nsresult HandleEvent(nsIFrame* aFrame,
238 : mozilla::WidgetGUIEvent* aEvent,
239 : bool aDontRetargetEvents,
240 : nsEventStatus* aEventStatus,
241 : nsIContent** aTargetContent) override;
242 : virtual nsresult HandleDOMEventWithTarget(
243 : nsIContent* aTargetContent,
244 : mozilla::WidgetEvent* aEvent,
245 : nsEventStatus* aStatus) override;
246 : virtual nsresult HandleDOMEventWithTarget(nsIContent* aTargetContent,
247 : nsIDOMEvent* aEvent,
248 : nsEventStatus* aStatus) override;
249 : virtual bool ShouldIgnoreInvalidation() override;
250 : virtual void WillPaint() override;
251 : virtual void WillPaintWindow() override;
252 : virtual void DidPaintWindow() override;
253 : virtual void ScheduleViewManagerFlush(PaintType aType = PAINT_DEFAULT) override;
254 : virtual void DispatchSynthMouseMove(mozilla::WidgetGUIEvent* aEvent,
255 : bool aFlushOnHoverChange) override;
256 : virtual void ClearMouseCaptureOnView(nsView* aView) override;
257 : virtual bool IsVisible() override;
258 :
259 : virtual already_AddRefed<mozilla::AccessibleCaretEventHub> GetAccessibleCaretEventHub() const override;
260 :
261 : // caret handling
262 : virtual already_AddRefed<nsCaret> GetCaret() const override;
263 : NS_IMETHOD SetCaretEnabled(bool aInEnable) override;
264 : NS_IMETHOD SetCaretReadOnly(bool aReadOnly) override;
265 : NS_IMETHOD GetCaretEnabled(bool *aOutEnabled) override;
266 : NS_IMETHOD SetCaretVisibilityDuringSelection(bool aVisibility) override;
267 : NS_IMETHOD GetCaretVisible(bool *_retval) override;
268 : virtual void SetCaret(nsCaret *aNewCaret) override;
269 : virtual void RestoreCaret() override;
270 :
271 : NS_IMETHOD SetSelectionFlags(int16_t aInEnable) override;
272 : NS_IMETHOD GetSelectionFlags(int16_t *aOutEnable) override;
273 :
274 : // nsISelectionController
275 :
276 : NS_IMETHOD PhysicalMove(int16_t aDirection, int16_t aAmount, bool aExtend) override;
277 : NS_IMETHOD CharacterMove(bool aForward, bool aExtend) override;
278 : NS_IMETHOD CharacterExtendForDelete() override;
279 : NS_IMETHOD CharacterExtendForBackspace() override;
280 : NS_IMETHOD WordMove(bool aForward, bool aExtend) override;
281 : NS_IMETHOD WordExtendForDelete(bool aForward) override;
282 : NS_IMETHOD LineMove(bool aForward, bool aExtend) override;
283 : NS_IMETHOD IntraLineMove(bool aForward, bool aExtend) override;
284 : NS_IMETHOD PageMove(bool aForward, bool aExtend) override;
285 : NS_IMETHOD ScrollPage(bool aForward) override;
286 : NS_IMETHOD ScrollLine(bool aForward) override;
287 : NS_IMETHOD ScrollCharacter(bool aRight) override;
288 : NS_IMETHOD CompleteScroll(bool aForward) override;
289 : NS_IMETHOD CompleteMove(bool aForward, bool aExtend) override;
290 : NS_IMETHOD SelectAll() override;
291 : NS_IMETHOD CheckVisibility(nsIDOMNode *node, int16_t startOffset, int16_t EndOffset, bool *_retval) override;
292 : virtual nsresult CheckVisibilityContent(nsIContent* aNode, int16_t aStartOffset,
293 : int16_t aEndOffset, bool* aRetval) override;
294 :
295 : // nsIDocumentObserver
296 : NS_DECL_NSIDOCUMENTOBSERVER_BEGINUPDATE
297 : NS_DECL_NSIDOCUMENTOBSERVER_ENDUPDATE
298 : NS_DECL_NSIDOCUMENTOBSERVER_BEGINLOAD
299 : NS_DECL_NSIDOCUMENTOBSERVER_ENDLOAD
300 : NS_DECL_NSIDOCUMENTOBSERVER_CONTENTSTATECHANGED
301 : NS_DECL_NSIDOCUMENTOBSERVER_DOCUMENTSTATESCHANGED
302 : NS_DECL_NSIDOCUMENTOBSERVER_STYLESHEETADDED
303 : NS_DECL_NSIDOCUMENTOBSERVER_STYLESHEETREMOVED
304 : NS_DECL_NSIDOCUMENTOBSERVER_STYLESHEETAPPLICABLESTATECHANGED
305 : NS_DECL_NSIDOCUMENTOBSERVER_STYLERULECHANGED
306 : NS_DECL_NSIDOCUMENTOBSERVER_STYLERULEADDED
307 : NS_DECL_NSIDOCUMENTOBSERVER_STYLERULEREMOVED
308 :
309 : // nsIMutationObserver
310 : NS_DECL_NSIMUTATIONOBSERVER_CHARACTERDATACHANGED
311 : NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTEWILLCHANGE
312 : NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED
313 : NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED
314 : NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED
315 : NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
316 :
317 : NS_DECL_NSIOBSERVER
318 :
319 : #ifdef MOZ_REFLOW_PERF
320 : virtual void DumpReflows() override;
321 : virtual void CountReflows(const char * aName, nsIFrame * aFrame) override;
322 : virtual void PaintCount(const char * aName,
323 : gfxContext* aRenderingContext,
324 : nsPresContext* aPresContext,
325 : nsIFrame * aFrame,
326 : const nsPoint& aOffset,
327 : uint32_t aColor) override;
328 : virtual void SetPaintFrameCount(bool aOn) override;
329 : virtual bool IsPaintingFrameCounts() override;
330 : #endif
331 :
332 : #ifdef DEBUG
333 : virtual void ListStyleContexts(FILE *out, int32_t aIndent = 0) override;
334 :
335 : virtual void ListStyleSheets(FILE *out, int32_t aIndent = 0) override;
336 : virtual void VerifyStyleTree() override;
337 : #endif
338 :
339 : static mozilla::LazyLogModule gLog;
340 :
341 : virtual void DisableNonTestMouseEvents(bool aDisable) override;
342 :
343 : virtual void UpdateCanvasBackground() override;
344 :
345 : virtual void AddCanvasBackgroundColorItem(nsDisplayListBuilder& aBuilder,
346 : nsDisplayList& aList,
347 : nsIFrame* aFrame,
348 : const nsRect& aBounds,
349 : nscolor aBackstopColor,
350 : uint32_t aFlags) override;
351 :
352 : virtual void AddPrintPreviewBackgroundItem(nsDisplayListBuilder& aBuilder,
353 : nsDisplayList& aList,
354 : nsIFrame* aFrame,
355 : const nsRect& aBounds) override;
356 :
357 : virtual nscolor ComputeBackstopColor(nsView* aDisplayRoot) override;
358 :
359 : virtual nsresult SetIsActive(bool aIsActive) override;
360 :
361 2 : virtual bool GetIsViewportOverridden() override {
362 2 : return (mMobileViewportManager != nullptr);
363 : }
364 :
365 0 : virtual bool IsLayoutFlushObserver() override
366 : {
367 : return GetPresContext()->RefreshDriver()->
368 0 : IsLayoutFlushObserver(this);
369 : }
370 :
371 : virtual void LoadComplete() override;
372 :
373 : void AddSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf,
374 : nsArenaMemoryStats* aArenaObjectsSize,
375 : size_t* aPresShellSize,
376 : size_t* aStyleSetsSize,
377 : size_t* aTextRunsSize,
378 : size_t* aPresContextSize,
379 : size_t* aFramePropertiesSize) override;
380 : size_t SizeOfTextRuns(mozilla::MallocSizeOf aMallocSizeOf) const;
381 :
382 : // This data is stored as a content property (nsGkAtoms::scrolling) on
383 : // mContentToScrollTo when we have a pending ScrollIntoView.
384 1 : struct ScrollIntoViewData {
385 : ScrollAxis mContentScrollVAxis;
386 : ScrollAxis mContentScrollHAxis;
387 : uint32_t mContentToScrollToFlags;
388 : };
389 :
390 :
391 : //////////////////////////////////////////////////////////////////////////////
392 : // Approximate frame visibility tracking public API.
393 : //////////////////////////////////////////////////////////////////////////////
394 :
395 : void ScheduleApproximateFrameVisibilityUpdateSoon() override;
396 : void ScheduleApproximateFrameVisibilityUpdateNow() override;
397 :
398 : void RebuildApproximateFrameVisibilityDisplayList(const nsDisplayList& aList) override;
399 : void RebuildApproximateFrameVisibility(nsRect* aRect = nullptr,
400 : bool aRemoveOnly = false) override;
401 :
402 : void EnsureFrameInApproximatelyVisibleList(nsIFrame* aFrame) override;
403 : void RemoveFrameFromApproximatelyVisibleList(nsIFrame* aFrame) override;
404 :
405 : bool AssumeAllFramesVisible() override;
406 :
407 :
408 : virtual void RecordShadowStyleChange(mozilla::dom::ShadowRoot* aShadowRoot) override;
409 :
410 : virtual bool CanDispatchEvent(
411 : const mozilla::WidgetGUIEvent* aEvent = nullptr) const override;
412 :
413 1 : void SetNextPaintCompressed() { mNextPaintCompressed = true; }
414 :
415 : void NotifyStyleSheetServiceSheetAdded(mozilla::StyleSheet* aSheet,
416 : uint32_t aSheetType) override;
417 : void NotifyStyleSheetServiceSheetRemoved(mozilla::StyleSheet* aSheet,
418 : uint32_t aSheetType) override;
419 :
420 : protected:
421 : virtual ~PresShell();
422 :
423 : void HandlePostedReflowCallbacks(bool aInterruptible);
424 : void CancelPostedReflowCallbacks();
425 :
426 : void ScheduleBeforeFirstPaint();
427 : void UnsuppressAndInvalidate();
428 :
429 830 : void WillCauseReflow() {
430 830 : nsContentUtils::AddScriptBlocker();
431 830 : ++mChangeNestCount;
432 830 : }
433 : nsresult DidCauseReflow();
434 : friend class ::nsAutoCauseReflowNotifier;
435 :
436 : nsresult DispatchEventToDOM(mozilla::WidgetEvent* aEvent,
437 : nsEventStatus* aStatus,
438 : nsPresShellEventCB* aEventCB);
439 : void DispatchTouchEventToDOM(mozilla::WidgetEvent* aEvent,
440 : nsEventStatus* aStatus,
441 : nsPresShellEventCB* aEventCB,
442 : bool aTouchIsNew);
443 :
444 : void WillDoReflow();
445 :
446 : /**
447 : * Callback handler for whether reflow happened.
448 : *
449 : * @param aInterruptible Whether or not reflow interruption is allowed.
450 : */
451 : void DidDoReflow(bool aInterruptible);
452 : // ProcessReflowCommands returns whether we processed all our dirty roots
453 : // without interruptions.
454 : bool ProcessReflowCommands(bool aInterruptible);
455 : // MaybeScheduleReflow checks if posting a reflow is needed, then checks if
456 : // the last reflow was interrupted. In the interrupted case ScheduleReflow is
457 : // called off a timer, otherwise it is called directly.
458 : void MaybeScheduleReflow();
459 : // Actually schedules a reflow. This should only be called by
460 : // MaybeScheduleReflow and the reflow timer ScheduleReflowOffTimer
461 : // sets up.
462 : void ScheduleReflow();
463 :
464 : // DoReflow returns whether the reflow finished without interruption
465 : bool DoReflow(nsIFrame* aFrame, bool aInterruptible);
466 : #ifdef DEBUG
467 : void DoVerifyReflow();
468 : void VerifyHasDirtyRootAncestor(nsIFrame* aFrame);
469 : #endif
470 :
471 : // Helper for ScrollContentIntoView
472 : void DoScrollContentIntoView();
473 :
474 : /**
475 : * Initialize cached font inflation preference values and do an initial
476 : * computation to determine if font inflation is enabled.
477 : *
478 : * @see nsLayoutUtils::sFontSizeInflationEmPerLine
479 : * @see nsLayoutUtils::sFontSizeInflationMinTwips
480 : * @see nsLayoutUtils::sFontSizeInflationLineThreshold
481 : */
482 : void SetupFontInflation();
483 :
484 18 : struct RenderingState {
485 18 : explicit RenderingState(PresShell* aPresShell)
486 18 : : mResolution(aPresShell->mResolution)
487 18 : , mRenderFlags(aPresShell->mRenderFlags)
488 18 : { }
489 : Maybe<float> mResolution;
490 : RenderFlags mRenderFlags;
491 : };
492 :
493 : struct AutoSaveRestoreRenderingState {
494 18 : explicit AutoSaveRestoreRenderingState(PresShell* aPresShell)
495 18 : : mPresShell(aPresShell)
496 18 : , mOldState(aPresShell)
497 18 : {}
498 :
499 18 : ~AutoSaveRestoreRenderingState()
500 18 : {
501 18 : mPresShell->mRenderFlags = mOldState.mRenderFlags;
502 18 : mPresShell->mResolution = mOldState.mResolution;
503 18 : }
504 :
505 : PresShell* mPresShell;
506 : RenderingState mOldState;
507 : };
508 18 : static RenderFlags ChangeFlag(RenderFlags aFlags, bool aOnOff,
509 : eRenderFlag aFlag)
510 : {
511 18 : return aOnOff ? (aFlags | aFlag) : (aFlag & ~aFlag);
512 : }
513 :
514 :
515 : void SetRenderingState(const RenderingState& aState);
516 :
517 : friend class ::nsPresShellEventCB;
518 :
519 : bool mCaretEnabled;
520 :
521 : #ifdef DEBUG
522 : nsStyleSet* CloneStyleSet(nsStyleSet* aSet);
523 : bool VerifyIncrementalReflow();
524 : bool mInVerifyReflow;
525 : void ShowEventTargetDebug();
526 : #endif
527 :
528 : void RecordStyleSheetChange(mozilla::StyleSheet* aStyleSheet,
529 : StyleSheet::ChangeType);
530 :
531 : void RemovePreferenceStyles();
532 :
533 : // methods for painting a range to an offscreen buffer
534 :
535 : // given a display list, clip the items within the list to
536 : // the range
537 : nsRect ClipListToRange(nsDisplayListBuilder *aBuilder,
538 : nsDisplayList* aList,
539 : nsRange* aRange);
540 :
541 : // create a RangePaintInfo for the range aRange containing the
542 : // display list needed to paint the range to a surface
543 : mozilla::UniquePtr<RangePaintInfo>
544 : CreateRangePaintInfo(nsIDOMRange* aRange,
545 : nsRect& aSurfaceRect,
546 : bool aForPrimarySelection);
547 :
548 : /*
549 : * Paint the items to a new surface and return it.
550 : *
551 : * aSelection - selection being painted, if any
552 : * aRegion - clip region, if any
553 : * aArea - area that the surface occupies, relative to the root frame
554 : * aPoint - reference point, typically the mouse position
555 : * aScreenRect - [out] set to the area of the screen the painted area should
556 : * be displayed at
557 : * aFlags - set RENDER_AUTO_SCALE to scale down large images, but it must not
558 : * be set if a custom image was specified
559 : */
560 : already_AddRefed<SourceSurface>
561 : PaintRangePaintInfo(const nsTArray<mozilla::UniquePtr<RangePaintInfo>>& aItems,
562 : nsISelection* aSelection,
563 : nsIntRegion* aRegion,
564 : nsRect aArea,
565 : const mozilla::LayoutDeviceIntPoint aPoint,
566 : mozilla::LayoutDeviceIntRect* aScreenRect,
567 : uint32_t aFlags);
568 :
569 : /**
570 : * Methods to handle changes to user and UA sheet lists that we get
571 : * notified about.
572 : */
573 : void AddUserSheet(StyleSheet* aSheet);
574 : void AddAgentSheet(StyleSheet* aSheet);
575 : void AddAuthorSheet(StyleSheet* aSheet);
576 : void RemoveSheet(mozilla::SheetType aType, StyleSheet* aSheet);
577 :
578 : // Hide a view if it is a popup
579 : void HideViewIfPopup(nsView* aView);
580 :
581 : // Utility method to restore the root scrollframe state
582 : void RestoreRootScrollPosition();
583 :
584 : void MaybeReleaseCapturingContent();
585 :
586 0 : nsresult HandleRetargetedEvent(mozilla::WidgetEvent* aEvent,
587 : nsEventStatus* aStatus,
588 : nsIContent* aTarget)
589 : {
590 0 : PushCurrentEventInfo(nullptr, nullptr);
591 0 : mCurrentEventContent = aTarget;
592 0 : nsresult rv = NS_OK;
593 0 : if (GetCurrentEventFrame()) {
594 0 : rv = HandleEventInternal(aEvent, aStatus, true);
595 : }
596 0 : PopCurrentEventInfo();
597 0 : return rv;
598 : }
599 :
600 0 : class DelayedEvent
601 : {
602 : public:
603 0 : virtual ~DelayedEvent() { }
604 0 : virtual void Dispatch() { }
605 0 : virtual bool IsKeyPressEvent() { return false; }
606 : };
607 :
608 : class DelayedInputEvent : public DelayedEvent
609 : {
610 : public:
611 : virtual void Dispatch() override;
612 :
613 : protected:
614 : DelayedInputEvent();
615 : virtual ~DelayedInputEvent();
616 :
617 : mozilla::WidgetInputEvent* mEvent;
618 : };
619 :
620 0 : class DelayedMouseEvent : public DelayedInputEvent
621 : {
622 : public:
623 : explicit DelayedMouseEvent(mozilla::WidgetMouseEvent* aEvent);
624 : };
625 :
626 0 : class DelayedKeyEvent : public DelayedInputEvent
627 : {
628 : public:
629 : explicit DelayedKeyEvent(mozilla::WidgetKeyboardEvent* aEvent);
630 : virtual bool IsKeyPressEvent() override;
631 : };
632 :
633 : // Check if aEvent is a mouse event and record the mouse location for later
634 : // synth mouse moves.
635 : void RecordMouseLocation(mozilla::WidgetGUIEvent* aEvent);
636 : class nsSynthMouseMoveEvent final : public nsARefreshObserver {
637 : public:
638 1 : nsSynthMouseMoveEvent(PresShell* aPresShell, bool aFromScroll)
639 1 : : mPresShell(aPresShell), mFromScroll(aFromScroll) {
640 1 : NS_ASSERTION(mPresShell, "null parameter");
641 1 : }
642 :
643 : private:
644 : // Private destructor, to discourage deletion outside of Release():
645 2 : ~nsSynthMouseMoveEvent() {
646 1 : Revoke();
647 1 : }
648 :
649 : public:
650 7 : NS_INLINE_DECL_REFCOUNTING(nsSynthMouseMoveEvent, override)
651 :
652 1 : void Revoke() {
653 1 : if (mPresShell) {
654 1 : mPresShell->GetPresContext()->RefreshDriver()->
655 2 : RemoveRefreshObserver(this, FlushType::Display);
656 1 : mPresShell = nullptr;
657 : }
658 1 : }
659 1 : virtual void WillRefresh(mozilla::TimeStamp aTime) override {
660 1 : if (mPresShell) {
661 2 : RefPtr<PresShell> shell = mPresShell;
662 1 : shell->ProcessSynthMouseMoveEvent(mFromScroll);
663 : }
664 1 : }
665 : private:
666 : PresShell* mPresShell;
667 : bool mFromScroll;
668 : };
669 : void ProcessSynthMouseMoveEvent(bool aFromScroll);
670 :
671 : void QueryIsActive();
672 : nsresult UpdateImageLockingState();
673 :
674 : bool InZombieDocument(nsIContent *aContent);
675 : already_AddRefed<nsIPresShell> GetParentPresShellForEventHandling();
676 : nsIContent* GetCurrentEventContent();
677 : nsIFrame* GetCurrentEventFrame();
678 : nsresult RetargetEventToParent(mozilla::WidgetGUIEvent* aEvent,
679 : nsEventStatus* aEventStatus);
680 : void PushCurrentEventInfo(nsIFrame* aFrame, nsIContent* aContent);
681 : void PopCurrentEventInfo();
682 : /**
683 : * @param aIsHandlingNativeEvent true when the caller (perhaps) handles
684 : * an event which is caused by native
685 : * event. Otherwise, false.
686 : */
687 : nsresult HandleEventInternal(mozilla::WidgetEvent* aEvent,
688 : nsEventStatus* aStatus,
689 : bool aIsHandlingNativeEvent);
690 : nsresult HandlePositionedEvent(nsIFrame* aTargetFrame,
691 : mozilla::WidgetGUIEvent* aEvent,
692 : nsEventStatus* aEventStatus);
693 :
694 : /*
695 : * This and the next two helper methods are used to target and position the
696 : * context menu when the keyboard shortcut is used to open it.
697 : *
698 : * If another menu is open, the context menu is opened relative to the
699 : * active menuitem within the menu, or the menu itself if no item is active.
700 : * Otherwise, if the caret is visible, the menu is opened near the caret.
701 : * Otherwise, if a selectable list such as a listbox is focused, the
702 : * current item within the menu is opened relative to this item.
703 : * Otherwise, the context menu is opened at the topleft corner of the
704 : * view.
705 : *
706 : * Returns true if the context menu event should fire and false if it should
707 : * not.
708 : */
709 : bool AdjustContextMenuKeyEvent(mozilla::WidgetMouseEvent* aEvent);
710 :
711 : //
712 : bool PrepareToUseCaretPosition(nsIWidget* aEventWidget,
713 : mozilla::LayoutDeviceIntPoint& aTargetPt);
714 :
715 : // Get the selected item and coordinates in device pixels relative to root
716 : // document's root view for element, first ensuring the element is onscreen
717 : void GetCurrentItemAndPositionForElement(nsIDOMElement *aCurrentEl,
718 : nsIContent **aTargetToUse,
719 : mozilla::LayoutDeviceIntPoint& aTargetPt,
720 : nsIWidget *aRootWidget);
721 :
722 : void FireResizeEvent();
723 : static void AsyncResizeEventCallback(nsITimer* aTimer, void* aPresShell);
724 :
725 : virtual void SynthesizeMouseMove(bool aFromScroll) override;
726 :
727 : PresShell* GetRootPresShell();
728 :
729 : nscolor GetDefaultBackgroundColorToDraw();
730 :
731 : DOMHighResTimeStamp GetPerformanceNow();
732 :
733 : // The callback for the mPaintSuppressionTimer timer.
734 : static void sPaintSuppressionCallback(nsITimer* aTimer, void* aPresShell);
735 :
736 : // The callback for the mReflowContinueTimer timer.
737 : static void sReflowContinueCallback(nsITimer* aTimer, void* aPresShell);
738 : bool ScheduleReflowOffTimer();
739 :
740 : // Widget notificiations
741 : virtual void WindowSizeMoveDone() override;
742 0 : virtual void SysColorChanged() override { mPresContext->SysColorChanged(); }
743 0 : virtual void ThemeChanged() override { mPresContext->ThemeChanged(); }
744 0 : virtual void BackingScaleFactorChanged() override { mPresContext->UIResolutionChanged(); }
745 : virtual nsIDocument* GetPrimaryContentDocument() override;
746 :
747 : virtual void PausePainting() override;
748 : virtual void ResumePainting() override;
749 :
750 : void UpdateActivePointerState(mozilla::WidgetGUIEvent* aEvent);
751 :
752 :
753 : //////////////////////////////////////////////////////////////////////////////
754 : // Approximate frame visibility tracking implementation.
755 : //////////////////////////////////////////////////////////////////////////////
756 :
757 : void UpdateApproximateFrameVisibility();
758 : void DoUpdateApproximateFrameVisibility(bool aRemoveOnly);
759 :
760 : void ClearApproximatelyVisibleFramesList(const Maybe<mozilla::OnNonvisible>& aNonvisibleAction
761 : = Nothing());
762 : static void ClearApproximateFrameVisibilityVisited(nsView* aView, bool aClear);
763 : static void MarkFramesInListApproximatelyVisible(const nsDisplayList& aList,
764 : Maybe<VisibleRegions>& aVisibleRegions);
765 : void MarkFramesInSubtreeApproximatelyVisible(nsIFrame* aFrame,
766 : const nsRect& aRect,
767 : Maybe<VisibleRegions>& aVisibleRegions,
768 : bool aRemoveOnly = false);
769 :
770 : void DecApproximateVisibleCount(VisibleFrames& aFrames,
771 : const Maybe<OnNonvisible>& aNonvisibleAction = Nothing());
772 :
773 : nsRevocableEventPtr<nsRunnableMethod<PresShell>> mUpdateApproximateFrameVisibilityEvent;
774 :
775 : // A set of frames that were visible or could be visible soon at the time
776 : // that we last did an approximate frame visibility update.
777 : VisibleFrames mApproximatelyVisibleFrames;
778 :
779 : nsresult SetResolutionImpl(float aResolution, bool aScaleToResolution);
780 :
781 : #ifdef DEBUG
782 : // The reflow root under which we're currently reflowing. Null when
783 : // not in reflow.
784 : nsIFrame* mCurrentReflowRoot;
785 : uint32_t mUpdateCount;
786 : #endif
787 :
788 : #ifdef MOZ_REFLOW_PERF
789 : ReflowCountMgr* mReflowCountMgr;
790 : #endif
791 :
792 : // This is used for synthetic mouse events that are sent when what is under
793 : // the mouse pointer may have changed without the mouse moving (eg scrolling,
794 : // change to the document contents).
795 : // It is set only on a presshell for a root document, this value represents
796 : // the last observed location of the mouse relative to that root document. It
797 : // is set to (NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE) if the mouse isn't
798 : // over our window or there is no last observed mouse location for some
799 : // reason.
800 : nsPoint mMouseLocation;
801 : // This is an APZ state variable that tracks the target guid for the last
802 : // mouse event that was processed (corresponding to mMouseLocation). This is
803 : // needed for the synthetic mouse events.
804 : mozilla::layers::ScrollableLayerGuid mMouseEventTargetGuid;
805 :
806 : // mStyleSet owns it but we maintain a ref, may be null
807 : RefPtr<mozilla::StyleSheet> mPrefStyleSheet;
808 :
809 : // Set of frames that we should mark with NS_FRAME_HAS_DIRTY_CHILDREN after
810 : // we finish reflowing mCurrentReflowRoot.
811 : nsTHashtable<nsPtrHashKey<nsIFrame> > mFramesToDirty;
812 :
813 : // Reflow roots that need to be reflowed.
814 : nsTArray<nsIFrame*> mDirtyRoots;
815 :
816 : nsTArray<nsAutoPtr<DelayedEvent> > mDelayedEvents;
817 : nsRevocableEventPtr<nsRunnableMethod<PresShell> > mResizeEvent;
818 : nsCOMPtr<nsITimer> mAsyncResizeEventTimer;
819 : private:
820 : nsIFrame* mCurrentEventFrame;
821 : nsCOMPtr<nsIContent> mCurrentEventContent;
822 : nsTArray<nsIFrame*> mCurrentEventFrameStack;
823 : nsCOMArray<nsIContent> mCurrentEventContentStack;
824 : protected:
825 : nsRevocableEventPtr<nsSynthMouseMoveEvent> mSynthMouseMoveEvent;
826 : nsCOMPtr<nsIContent> mLastAnchorScrolledTo;
827 : RefPtr<nsCaret> mCaret;
828 : RefPtr<nsCaret> mOriginalCaret;
829 : nsCallbackEventRequest* mFirstCallbackEventRequest;
830 : nsCallbackEventRequest* mLastCallbackEventRequest;
831 :
832 : mozilla::TouchManager mTouchManager;
833 :
834 : RefPtr<ZoomConstraintsClient> mZoomConstraintsClient;
835 : RefPtr<MobileViewportManager> mMobileViewportManager;
836 :
837 : RefPtr<mozilla::AccessibleCaretEventHub> mAccessibleCaretEventHub;
838 :
839 : // This timer controls painting suppression. Until it fires
840 : // or all frames are constructed, we won't paint anything but
841 : // our <body> background and scrollbars.
842 : nsCOMPtr<nsITimer> mPaintSuppressionTimer;
843 :
844 : nsCOMPtr<nsITimer> mDelayedPaintTimer;
845 :
846 : // The `performance.now()` value when we last started to process reflows.
847 : DOMHighResTimeStamp mLastReflowStart;
848 :
849 : mozilla::TimeStamp mLoadBegin; // used to time loads
850 :
851 : // Information needed to properly handle scrolling content into view if the
852 : // pre-scroll reflow flush can be interrupted. mContentToScrollTo is
853 : // non-null between the initial scroll attempt and the first time we finish
854 : // processing all our dirty roots. mContentToScrollTo has a content property
855 : // storing the details for the scroll operation, see ScrollIntoViewData above.
856 : nsCOMPtr<nsIContent> mContentToScrollTo;
857 :
858 : nscoord mLastAnchorScrollPositionY;
859 :
860 : // Information about live content (which still stay in DOM tree).
861 : // Used in case we need re-dispatch event after sending pointer event,
862 : // when target of pointer event was deleted during executing user handlers.
863 : nsCOMPtr<nsIContent> mPointerEventTarget;
864 :
865 : // The focus sequence number of the last processed input event
866 : uint64_t mAPZFocusSequenceNumber;
867 : // The focus information needed for async keyboard scrolling
868 : FocusTarget mAPZFocusTarget;
869 :
870 : // This is used to protect ourselves from triggering reflow while in the
871 : // middle of frame construction and the like... it really shouldn't be
872 : // needed, one hopes, but it is for now.
873 : uint16_t mChangeNestCount;
874 :
875 : bool mDocumentLoading : 1;
876 : bool mIgnoreFrameDestruction : 1;
877 : bool mHaveShutDown : 1;
878 : bool mLastRootReflowHadUnconstrainedBSize : 1;
879 : bool mNoDelayedMouseEvents : 1;
880 : bool mNoDelayedKeyEvents : 1;
881 :
882 : // We've been disconnected from the document. We will refuse to paint the
883 : // document until either our timer fires or all frames are constructed.
884 : bool mIsDocumentGone : 1;
885 :
886 : // Indicates that it is safe to unlock painting once all pending reflows
887 : // have been processed.
888 : bool mShouldUnsuppressPainting : 1;
889 :
890 : bool mAsyncResizeTimerIsActive : 1;
891 : bool mInResize : 1;
892 :
893 : bool mApproximateFrameVisibilityVisited : 1;
894 :
895 : bool mNextPaintCompressed : 1;
896 :
897 : bool mHasCSSBackgroundColor : 1;
898 :
899 : // Whether content should be scaled by the resolution amount. If this is
900 : // not set, a transform that scales by the inverse of the resolution is
901 : // applied to rendered layers.
902 : bool mScaleToResolution : 1;
903 :
904 : // Whether the last chrome-only escape key event is consumed.
905 : bool mIsLastChromeOnlyEscapeKeyConsumed : 1;
906 :
907 : // Whether the widget has received a paint message yet.
908 : bool mHasReceivedPaintMessage : 1;
909 :
910 : bool mIsLastKeyDownCanceled : 1;
911 :
912 : static bool sDisableNonTestMouseEvents;
913 :
914 : mozilla::TimeStamp mLastOSWake;
915 :
916 : static mozilla::TimeStamp sLastInputCreated;
917 : static mozilla::TimeStamp sLastInputProcessed;
918 : };
919 :
920 : } // namespace mozilla
921 :
922 : #endif // mozilla_PresShell_h
|