author | Timothy Nikkel <tnikkel@gmail.com> |
Mon, 04 May 2015 14:29:19 -0500 | |
changeset 242304 | f58aab6a4e62d9ca2c0c9098c0eed84024adf85e |
parent 242303 | 10c082aa3a6338ec53a092a1700242a6ad66ff7a |
child 242305 | ad9035f138676306c5ea78b90f417349b67d35ee |
push id | 28689 |
push user | cbook@mozilla.com |
push date | Tue, 05 May 2015 10:05:09 +0000 |
treeherder | mozilla-central@754579ec0e68 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | mats |
bugs | 1159772 |
milestone | 40.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/layout/base/nsCSSFrameConstructor.cpp +++ b/layout/base/nsCSSFrameConstructor.cpp @@ -2683,17 +2683,17 @@ nsCSSFrameConstructor::ConstructRootFram // Bind the viewport frame to the root view nsView* rootView = mPresShell->GetViewManager()->GetRootView(); viewportFrame->SetView(rootView); nsContainerFrame::SyncFrameViewProperties(mPresShell->GetPresContext(), viewportFrame, viewportPseudoStyle, rootView); nsContainerFrame::SyncWindowProperties(mPresShell->GetPresContext(), viewportFrame, - rootView); + rootView, nullptr, nsContainerFrame::SET_ASYNC); // Make it an absolute container for fixed-pos elements viewportFrame->AddStateBits(NS_FRAME_CAN_HAVE_ABSPOS_CHILDREN); viewportFrame->MarkAsAbsoluteContainingBlock(); return viewportFrame; }
--- a/layout/base/nsIPresShell.h +++ b/layout/base/nsIPresShell.h @@ -135,18 +135,18 @@ typedef struct CapturingContentInfo { bool mPointerLock; bool mRetargetToElement; bool mPreventDrag; mozilla::StaticRefPtr<nsIContent> mContent; } CapturingContentInfo; // d910f009-d209-74c1-6b04-30c83c051c78 #define NS_IPRESSHELL_IID \ - { 0xd910f009, 0xd209, 0x74c1, \ - { 0x6b, 0x04, 0x30, 0xc8, 0x3c, 0x05, 0x1c, 0x78 } } + { 0x025264c6, 0x0b12, 0x4804, \ + { 0xa3, 0x3e, 0xb7, 0x73, 0xf2, 0x19, 0x48, 0x90 } } // debug VerifyReflow flags #define VERIFY_REFLOW_ON 0x01 #define VERIFY_REFLOW_NOISY 0x02 #define VERIFY_REFLOW_ALL 0x04 #define VERIFY_REFLOW_DUMP_COMMANDS 0x08 #define VERIFY_REFLOW_NOISY_RC 0x10 #define VERIFY_REFLOW_REALLY_NOISY_RC 0x20 @@ -1656,16 +1656,18 @@ public: void SetNeverPainting(bool aNeverPainting) { mIsNeverPainting = aNeverPainting; } bool HasPendingReflow() const { return mReflowScheduled || mReflowContinueTimer; } + void SyncWindowProperties(nsView* aView); + protected: friend class nsRefreshDriver; // IMPORTANT: The ownership implicit in the following member variables // has been explicitly checked. If you add any members to this class, // please make the ownership explicit (pinkerton, scc). // These are the same Document and PresContext owned by the DocViewer.
--- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -9240,17 +9240,18 @@ PresShell::DoReflow(nsIFrame* target, bo // Always use boundsRelativeToTarget here, not desiredSize.GetVisualOverflowArea(), // because for root frames (where they could be different, since root frames // are allowed to have overflow) the root view bounds need to match the // viewport bounds; the view manager "window dimensions" code depends on it. nsContainerFrame::SyncFrameViewAfterReflow(mPresContext, target, target->GetView(), boundsRelativeToTarget); nsContainerFrame::SyncWindowProperties(mPresContext, target, - target->GetView(), &rcx); + target->GetView(), &rcx, + nsContainerFrame::SET_ASYNC); target->DidReflow(mPresContext, nullptr, nsDidReflowStatus::FINISHED); if (target == rootFrame && size.BSize(wm) == NS_UNCONSTRAINEDSIZE) { mPresContext->SetVisibleArea(boundsRelativeToTarget); } #ifdef DEBUG mCurrentReflowRoot = nullptr; @@ -11076,8 +11077,18 @@ void PresShell::ResumePainting() { if (GetPresContext()->RefreshDriver()->PresContext() != GetPresContext()) return; mPaintingIsFrozen = false; GetPresContext()->RefreshDriver()->Thaw(); } + +void +nsIPresShell::SyncWindowProperties(nsView* aView) +{ + nsIFrame* frame = aView->GetFrame(); + if (frame && mPresContext) { + nsRenderingContext rcx(CreateReferenceRenderingContext()); + nsContainerFrame::SyncWindowProperties(mPresContext, frame, aView, &rcx, 0); + } +}
--- a/layout/generic/nsContainerFrame.cpp +++ b/layout/generic/nsContainerFrame.cpp @@ -604,24 +604,25 @@ IsTopLevelWidget(nsIWidget* aWidget) windowType == eWindowType_dialog || windowType == eWindowType_sheet; // popups aren't toplevel so they're not handled here } void nsContainerFrame::SyncWindowProperties(nsPresContext* aPresContext, nsIFrame* aFrame, - nsView* aView, - nsRenderingContext* aRC) + nsView* aView, + nsRenderingContext* aRC, + uint32_t aFlags) { #ifdef MOZ_XUL if (!aView || !nsCSSRendering::IsCanvasFrame(aFrame) || !aView->HasWidget()) return; - nsIWidget* windowWidget = GetPresContextContainerWidget(aPresContext); + nsCOMPtr<nsIWidget> windowWidget = GetPresContextContainerWidget(aPresContext); if (!windowWidget || !IsTopLevelWidget(windowWidget)) return; nsViewManager* vm = aView->GetViewManager(); nsView* rootView = vm->GetRootView(); if (aView != rootView) return; @@ -645,24 +646,37 @@ nsContainerFrame::SyncWindowProperties(n // even if the HTML doesn't have a background-color set. return; } nsIFrame *rootFrame = aPresContext->PresShell()->FrameConstructor()->GetRootElementStyleFrame(); if (!rootFrame) return; + if (aFlags & SET_ASYNC) { + aView->SetNeedsWindowPropertiesSync(); + return; + } + + nsRefPtr<nsPresContext> kungFuDeathGrip(aPresContext); + nsWeakFrame weak(rootFrame); + nsTransparencyMode mode = nsLayoutUtils::GetFrameTransparency(aFrame, rootFrame); - nsIWidget* viewWidget = aView->GetWidget(); + int32_t shadow = rootFrame->StyleUIReset()->mWindowShadow; + nsCOMPtr<nsIWidget> viewWidget = aView->GetWidget(); viewWidget->SetTransparencyMode(mode); - windowWidget->SetWindowShadowStyle(rootFrame->StyleUIReset()->mWindowShadow); + windowWidget->SetWindowShadowStyle(shadow); if (!aRC) return; - + + if (!weak.IsAlive()) { + return; + } + nsBoxLayoutState aState(aPresContext, aRC); nsSize minSize = rootFrame->GetMinSize(aState); nsSize maxSize = rootFrame->GetMaxSize(aState); SetSizeConstraints(aPresContext, windowWidget, minSize, maxSize); #endif }
--- a/layout/generic/nsContainerFrame.h +++ b/layout/generic/nsContainerFrame.h @@ -175,20 +175,26 @@ public: static void SyncFrameViewAfterReflow(nsPresContext* aPresContext, nsIFrame* aFrame, nsView* aView, const nsRect& aVisualOverflowArea, uint32_t aFlags = 0); // Syncs properties to the top level view and window, like transparency and // shadow. + // The SET_ASYNC indicates that the actual nsIWidget calls to sync the window + // properties should be done async. + enum { + SET_ASYNC = 0x01, + }; static void SyncWindowProperties(nsPresContext* aPresContext, nsIFrame* aFrame, - nsView* aView, - nsRenderingContext* aRC = nullptr); + nsView* aView, + nsRenderingContext* aRC, + uint32_t aFlags); // Sets the view's attributes from the frame style. // - visibility // - clip // Call this when one of these styles changes or when the view has just // been created. // @param aStyleContext can be null, in which case the frame's style context is used static void SyncFrameViewProperties(nsPresContext* aPresContext,
--- a/view/nsView.cpp +++ b/view/nsView.cpp @@ -668,16 +668,26 @@ nsView::InitializeWindow(bool aEnableDra //make sure visibility state is accurate if (aResetVisibility) { SetVisibility(GetVisibility()); } } +void +nsView::SetNeedsWindowPropertiesSync() +{ + mNeedsWindowPropertiesSync = true; + if (mViewManager) { + mViewManager->PostPendingUpdate(); + } +} + + // Attach to a top level widget and start receiving mirrored events. nsresult nsView::AttachToTopLevelWidget(nsIWidget* aWidget) { NS_PRECONDITION(nullptr != aWidget, "null widget ptr"); /// XXXjimm This is a temporary workaround to an issue w/document // viewer (bug 513162). nsIWidgetListener* listener = aWidget->GetAttachedWidgetListener(); if (listener) {
--- a/view/nsView.h +++ b/view/nsView.h @@ -285,16 +285,18 @@ public: * Returns true if the view has a widget associated with it. */ bool HasWidget() const { return mWindow != nullptr; } void SetForcedRepaint(bool aForceRepaint) { mForcedRepaint = aForceRepaint; } + void SetNeedsWindowPropertiesSync(); + /** * Make aWidget direct its events to this view. * The caller must call DetachWidgetEventHandler before this view * is destroyed. */ void AttachWidgetEventHandler(nsIWidget* aWidget); /** * Stop aWidget directing its events to this view. @@ -458,11 +460,12 @@ private: nscoord mPosX, mPosY; // relative to parent, but in our appunits nsRect mDimBounds; // in our appunits nsPoint mViewToWidgetOffset; uint32_t mVFlags; bool mWidgetIsTopLevel; bool mForcedRepaint; + bool mNeedsWindowPropertiesSync; }; #endif
--- a/view/nsViewManager.cpp +++ b/view/nsViewManager.cpp @@ -363,16 +363,27 @@ nsViewManager::ProcessPendingUpdatesForV } nsCOMPtr<nsIPresShell> rootShell(mPresShell); nsTArray<nsCOMPtr<nsIWidget> > widgets; aView->GetViewManager()->ProcessPendingUpdatesRecurse(aView, widgets); for (uint32_t i = 0; i < widgets.Length(); ++i) { nsView* view = nsView::GetViewFor(widgets[i]); if (view) { + if (view->mNeedsWindowPropertiesSync) { + view->mNeedsWindowPropertiesSync = false; + if (nsViewManager* vm = view->GetViewManager()) { + if (nsIPresShell* ps = vm->GetPresShell()) { + ps->SyncWindowProperties(view); + } + } + } + } + view = nsView::GetViewFor(widgets[i]); + if (view) { view->ResetWidgetBounds(false, true); } } if (rootShell->GetViewManager() != this) { return; // 'this' might have been destroyed } if (aFlushDirtyRegion) { profiler_tracing("Paint", "DisplayList", TRACING_INTERVAL_START);