From e04a74ec14d1019cc3dc0848d5fcba5f4aff7f3c Mon Sep 17 00:00:00 2001 From: Mats Palmgren Date: Thu, 12 May 2016 12:07:45 +1200 Subject: [PATCH] Bug 881832 - Make inner document reflow asynchronous. r=tnikkel --HG-- extra : rebase_source : 9987e19e3318d5bc58ac8214496893041bc1775c --- docshell/base/nsDocShell.cpp | 14 +++++++++----- docshell/base/nsIContentViewer.idl | 6 ++++++ dom/base/nsFrameLoader.cpp | 3 ++- dom/ipc/TabChild.cpp | 4 ++-- dom/ipc/TabParent.cpp | 3 ++- embedding/browser/nsDocShellTreeOwner.cpp | 2 +- embedding/browser/nsWebBrowser.cpp | 14 ++++++++------ layout/base/nsDocumentViewer.cpp | 11 +++++++++-- layout/xul/nsResizerFrame.cpp | 3 ++- view/nsViewManager.cpp | 4 ++-- view/nsViewManager.h | 3 ++- widget/nsIBaseWindow.idl | 8 +++++++- xpfe/appshell/nsChromeTreeOwner.cpp | 6 +++--- xpfe/appshell/nsContentTreeOwner.cpp | 9 +++++---- xpfe/appshell/nsWebShellWindow.cpp | 2 +- xpfe/appshell/nsXULWindow.cpp | 4 ++-- 16 files changed, 63 insertions(+), 33 deletions(-) diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index 3e9b6adc3db0..152e8f8c9235 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -5592,7 +5592,7 @@ nsDocShell::InitWindow(nativeWindow aParentNativeWindow, int32_t aWidth, int32_t aHeight) { SetParentWidget(aParentWidget); - SetPositionAndSize(aX, aY, aWidth, aHeight, false); + SetPositionAndSize(aX, aY, aWidth, aHeight, 0); return NS_OK; } @@ -5838,7 +5838,8 @@ nsDocShell::SetSize(int32_t aWidth, int32_t aHeight, bool aRepaint) { int32_t x = 0, y = 0; GetPosition(&x, &y); - return SetPositionAndSize(x, y, aWidth, aHeight, aRepaint); + return SetPositionAndSize(x, y, aWidth, aHeight, + aRepaint ? nsIBaseWindow::eRepaint : 0); } NS_IMETHODIMP @@ -5849,7 +5850,7 @@ nsDocShell::GetSize(int32_t* aWidth, int32_t* aHeight) NS_IMETHODIMP nsDocShell::SetPositionAndSize(int32_t aX, int32_t aY, int32_t aWidth, - int32_t aHeight, bool aFRepaint) + int32_t aHeight, uint32_t aFlags) { mBounds.x = aX; mBounds.y = aY; @@ -5859,8 +5860,11 @@ nsDocShell::SetPositionAndSize(int32_t aX, int32_t aY, int32_t aWidth, // Hold strong ref, since SetBounds can make us null out mContentViewer nsCOMPtr viewer = mContentViewer; if (viewer) { + uint32_t cvflags = (aFlags & nsIBaseWindow::eDelayResize) ? + nsIContentViewer::eDelayResize : 0; // XXX Border figured in here or is that handled elsewhere? - NS_ENSURE_SUCCESS(viewer->SetBounds(mBounds), NS_ERROR_FAILURE); + nsresult rv = viewer->SetBoundsWithFlags(mBounds, cvflags); + NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE); } return NS_OK; @@ -5874,7 +5878,7 @@ nsDocShell::GetPositionAndSize(int32_t* aX, int32_t* aY, int32_t* aWidth, // ensure size is up-to-date if window has changed resolution LayoutDeviceIntRect r; mParentWidget->GetClientBounds(r); - SetPositionAndSize(mBounds.x, mBounds.y, r.width, r.height, false); + SetPositionAndSize(mBounds.x, mBounds.y, r.width, r.height, 0); } // We should really consider just getting this information from diff --git a/docshell/base/nsIContentViewer.idl b/docshell/base/nsIContentViewer.idl index 7291178aa894..68c424e46222 100644 --- a/docshell/base/nsIContentViewer.idl +++ b/docshell/base/nsIContentViewer.idl @@ -104,6 +104,12 @@ interface nsIContentViewer : nsISupports [noscript] void getBounds(in nsIntRectRef aBounds); [noscript] void setBounds([const] in nsIntRectRef aBounds); + /** + * The 'aFlags' argument to setBoundsWithFlags is a set of these bits. + */ + const unsigned long eDelayResize = 1; + [noscript] void setBoundsWithFlags([const] in nsIntRectRef aBounds, + in unsigned long aFlags); /** * The previous content viewer, which has been |close|d but not diff --git a/dom/base/nsFrameLoader.cpp b/dom/base/nsFrameLoader.cpp index 9edb7aa8ebaf..540345d0cf9d 100644 --- a/dom/base/nsFrameLoader.cpp +++ b/dom/base/nsFrameLoader.cpp @@ -2311,7 +2311,8 @@ nsFrameLoader::UpdateBaseWindowPositionAndSize(nsSubDocumentFrame *aIFrame) ScreenIntSize size = aIFrame->GetSubdocumentSize(); - baseWindow->SetPositionAndSize(x, y, size.width, size.height, false); + baseWindow->SetPositionAndSize(x, y, size.width, size.height, + nsIBaseWindow::eDelayResize); } } diff --git a/dom/ipc/TabChild.cpp b/dom/ipc/TabChild.cpp index 94afc3af0b24..841dd31fb172 100644 --- a/dom/ipc/TabChild.cpp +++ b/dom/ipc/TabChild.cpp @@ -1694,7 +1694,7 @@ TabChild::RecvUpdateDimensions(const CSSRect& rect, const CSSSize& size, // size from the content viewer when it computes a new CSS viewport. nsCOMPtr baseWin = do_QueryInterface(WebNavigation()); baseWin->SetPositionAndSize(0, 0, screenSize.width, screenSize.height, - true); + nsIBaseWindow::eRepaint); mPuppetWidget->Resize(screenRect.x + clientOffset.x + chromeDisp.x, screenRect.y + clientOffset.y + chromeDisp.y, @@ -3059,7 +3059,7 @@ TabChild::RecvUIResolutionChanged(const float& aDpi, const double& aScale) nsCOMPtr baseWin = do_QueryInterface(WebNavigation()); baseWin->SetPositionAndSize(0, 0, screenSize.width, screenSize.height, - true); + nsIBaseWindow::eRepaint); } return true; diff --git a/dom/ipc/TabParent.cpp b/dom/ipc/TabParent.cpp index 2d16e97787d9..24572ade0fff 100644 --- a/dom/ipc/TabParent.cpp +++ b/dom/ipc/TabParent.cpp @@ -870,7 +870,8 @@ TabParent::RecvSetDimensions(const uint32_t& aFlags, if (aFlags & nsIEmbeddingSiteWindow::DIM_FLAGS_POSITION && aFlags & nsIEmbeddingSiteWindow::DIM_FLAGS_SIZE_OUTER) { - treeOwnerAsWin->SetPositionAndSize(x, y, cx, cy, true); + treeOwnerAsWin->SetPositionAndSize(x, y, cx, cy, + nsIBaseWindow::eRepaint); return true; } diff --git a/embedding/browser/nsDocShellTreeOwner.cpp b/embedding/browser/nsDocShellTreeOwner.cpp index cc029db0f6d9..38b7332a0199 100644 --- a/embedding/browser/nsDocShellTreeOwner.cpp +++ b/embedding/browser/nsDocShellTreeOwner.cpp @@ -647,7 +647,7 @@ nsDocShellTreeOwner::GetSize(int32_t* aCX, int32_t* aCY) NS_IMETHODIMP nsDocShellTreeOwner::SetPositionAndSize(int32_t aX, int32_t aY, int32_t aCX, - int32_t aCY, bool aRepaint) + int32_t aCY, uint32_t aFlags) { nsCOMPtr ownerWin = GetOwnerWin(); if (ownerWin) { diff --git a/embedding/browser/nsWebBrowser.cpp b/embedding/browser/nsWebBrowser.cpp index 532b443ed52a..501b271e81eb 100644 --- a/embedding/browser/nsWebBrowser.cpp +++ b/embedding/browser/nsWebBrowser.cpp @@ -1150,7 +1150,7 @@ nsWebBrowser::InitWindow(nativeWindow aParentNativeWindow, NS_ENSURE_SUCCESS(SetParentNativeWindow(aParentNativeWindow), NS_ERROR_FAILURE); - NS_ENSURE_SUCCESS(SetPositionAndSize(aX, aY, aCX, aCY, false), + NS_ENSURE_SUCCESS(SetPositionAndSize(aX, aY, aCX, aCY, 0), NS_ERROR_FAILURE); return NS_OK; @@ -1325,7 +1325,7 @@ nsWebBrowser::SetPosition(int32_t aX, int32_t aY) GetSize(&cx, &cy); - return SetPositionAndSize(aX, aY, cx, cy, false); + return SetPositionAndSize(aX, aY, cx, cy, 0); } NS_IMETHODIMP @@ -1342,7 +1342,8 @@ nsWebBrowser::SetSize(int32_t aCX, int32_t aCY, bool aRepaint) GetPosition(&x, &y); - return SetPositionAndSize(x, y, aCX, aCY, aRepaint); + return SetPositionAndSize(x, y, aCX, aCY, + aRepaint ? nsIBaseWindow::eRepaint : 0); } NS_IMETHODIMP @@ -1353,7 +1354,7 @@ nsWebBrowser::GetSize(int32_t* aCX, int32_t* aCY) NS_IMETHODIMP nsWebBrowser::SetPositionAndSize(int32_t aX, int32_t aY, - int32_t aCX, int32_t aCY, bool aRepaint) + int32_t aCX, int32_t aCY, uint32_t aFlags) { if (!mDocShell) { mInitInfo->x = aX; @@ -1369,12 +1370,13 @@ nsWebBrowser::SetPositionAndSize(int32_t aX, int32_t aY, // We also need to resize our widget then. if (mInternalWidget) { doc_x = doc_y = 0; - NS_ENSURE_SUCCESS(mInternalWidget->Resize(aX, aY, aCX, aCY, aRepaint), + NS_ENSURE_SUCCESS(mInternalWidget->Resize(aX, aY, aCX, aCY, + !!(aFlags & nsIBaseWindow::eRepaint)), NS_ERROR_FAILURE); } // Now reposition/ resize the doc NS_ENSURE_SUCCESS( - mDocShellAsWin->SetPositionAndSize(doc_x, doc_y, aCX, aCY, aRepaint), + mDocShellAsWin->SetPositionAndSize(doc_x, doc_y, aCX, aCY, aFlags), NS_ERROR_FAILURE); } diff --git a/layout/base/nsDocumentViewer.cpp b/layout/base/nsDocumentViewer.cpp index b334ebf67247..988c7df099ce 100644 --- a/layout/base/nsDocumentViewer.cpp +++ b/layout/base/nsDocumentViewer.cpp @@ -1909,7 +1909,7 @@ nsDocumentViewer::SetPreviousViewer(nsIContentViewer* aViewer) } NS_IMETHODIMP -nsDocumentViewer::SetBounds(const nsIntRect& aBounds) +nsDocumentViewer::SetBoundsWithFlags(const nsIntRect& aBounds, uint32_t aFlags) { NS_ENSURE_TRUE(mDocument, NS_ERROR_NOT_AVAILABLE); @@ -1924,7 +1924,8 @@ nsDocumentViewer::SetBounds(const nsIntRect& aBounds) } else if (mPresContext && mViewManager) { int32_t p2a = mPresContext->AppUnitsPerDevPixel(); mViewManager->SetWindowDimensions(NSIntPixelsToAppUnits(mBounds.width, p2a), - NSIntPixelsToAppUnits(mBounds.height, p2a)); + NSIntPixelsToAppUnits(mBounds.height, p2a), + !!(aFlags & nsIContentViewer::eDelayResize)); } // If there's a previous viewer, it's the one that's actually showing, @@ -1942,6 +1943,12 @@ nsDocumentViewer::SetBounds(const nsIntRect& aBounds) return NS_OK; } +NS_IMETHODIMP +nsDocumentViewer::SetBounds(const nsIntRect& aBounds) +{ + return SetBoundsWithFlags(aBounds, 0); +} + NS_IMETHODIMP nsDocumentViewer::Move(int32_t aX, int32_t aY) { diff --git a/layout/xul/nsResizerFrame.cpp b/layout/xul/nsResizerFrame.cpp index 0e56da00b195..77dabd552ea1 100644 --- a/layout/xul/nsResizerFrame.cpp +++ b/layout/xul/nsResizerFrame.cpp @@ -285,7 +285,8 @@ nsResizerFrame::HandleEvent(nsPresContext* aPresContext, } } else { - window->SetPositionAndSize(rect.x, rect.y, rect.width, rect.height, true); // do the repaint. + window->SetPositionAndSize(rect.x, rect.y, rect.width, rect.height, + nsIBaseWindow::eRepaint); // do the repaint. } doDefault = false; diff --git a/view/nsViewManager.cpp b/view/nsViewManager.cpp index 74a5be96fafb..4b80ad67c6c9 100644 --- a/view/nsViewManager.cpp +++ b/view/nsViewManager.cpp @@ -212,10 +212,10 @@ nsViewManager::ShouldDelayResize() const } void -nsViewManager::SetWindowDimensions(nscoord aWidth, nscoord aHeight) +nsViewManager::SetWindowDimensions(nscoord aWidth, nscoord aHeight, bool aDelayResize) { if (mRootView) { - if (!ShouldDelayResize()) { + if (!ShouldDelayResize() && !aDelayResize) { if (mDelayedResize != nsSize(NSCOORD_NONE, NSCOORD_NONE) && mDelayedResize != nsSize(aWidth, aHeight)) { // We have a delayed resize; that now obsolete size may already have diff --git a/view/nsViewManager.h b/view/nsViewManager.h index 037abd1de5fa..ca379d4b0758 100644 --- a/view/nsViewManager.h +++ b/view/nsViewManager.h @@ -89,7 +89,8 @@ public: * @param aWidth of window in twips * @param aHeight of window in twips */ - void SetWindowDimensions(nscoord aWidth, nscoord aHeight); + void SetWindowDimensions(nscoord aWidth, nscoord aHeight, + bool aDelayResize = false); /** * Do any resizes that are pending. diff --git a/widget/nsIBaseWindow.idl b/widget/nsIBaseWindow.idl index 24289a70b38a..7da3fe1dcfe9 100644 --- a/widget/nsIBaseWindow.idl +++ b/widget/nsIBaseWindow.idl @@ -113,12 +113,18 @@ interface nsIBaseWindow : nsISupports */ void getSize(out long cx, out long cy); + /** + * The 'flags' argument to setPositionAndSize is a set of these bits. + */ + const unsigned long eRepaint = 1; + const unsigned long eDelayResize = 2; + /* Convenience function combining the SetPosition and SetSize into one call. Also is more efficient than calling both. */ void setPositionAndSize(in long x, in long y, in long cx, in long cy, - in boolean fRepaint); + in unsigned long flags); /* Convenience function combining the GetPosition and GetSize into one call. diff --git a/xpfe/appshell/nsChromeTreeOwner.cpp b/xpfe/appshell/nsChromeTreeOwner.cpp index 22e7dbc6bd04..688137cb1a63 100644 --- a/xpfe/appshell/nsChromeTreeOwner.cpp +++ b/xpfe/appshell/nsChromeTreeOwner.cpp @@ -357,7 +357,7 @@ NS_IMETHODIMP nsChromeTreeOwner::InitWindow(nativeWindow aParentNativeWindow, nsIWidget* parentWidget, int32_t x, int32_t y, int32_t cx, int32_t cy) { // Ignore widget parents for now. Don't think those are a vaild thing to call. - NS_ENSURE_SUCCESS(SetPositionAndSize(x, y, cx, cy, false), NS_ERROR_FAILURE); + NS_ENSURE_SUCCESS(SetPositionAndSize(x, y, cx, cy, 0), NS_ERROR_FAILURE); return NS_OK; } @@ -417,10 +417,10 @@ NS_IMETHODIMP nsChromeTreeOwner::GetSize(int32_t* cx, int32_t* cy) } NS_IMETHODIMP nsChromeTreeOwner::SetPositionAndSize(int32_t x, int32_t y, int32_t cx, - int32_t cy, bool fRepaint) + int32_t cy, uint32_t aFlags) { NS_ENSURE_STATE(mXULWindow); - return mXULWindow->SetPositionAndSize(x, y, cx, cy, fRepaint); + return mXULWindow->SetPositionAndSize(x, y, cx, cy, aFlags); } NS_IMETHODIMP nsChromeTreeOwner::GetPositionAndSize(int32_t* x, int32_t* y, int32_t* cx, diff --git a/xpfe/appshell/nsContentTreeOwner.cpp b/xpfe/appshell/nsContentTreeOwner.cpp index 695c76880706..f7473a904765 100644 --- a/xpfe/appshell/nsContentTreeOwner.cpp +++ b/xpfe/appshell/nsContentTreeOwner.cpp @@ -599,7 +599,7 @@ NS_IMETHODIMP nsContentTreeOwner::InitWindow(nativeWindow aParentNativeWindow, nsIWidget* parentWidget, int32_t x, int32_t y, int32_t cx, int32_t cy) { // Ignore wigdet parents for now. Don't think those are a vaild thing to call. - NS_ENSURE_SUCCESS(SetPositionAndSize(x, y, cx, cy, false), NS_ERROR_FAILURE); + NS_ENSURE_SUCCESS(SetPositionAndSize(x, y, cx, cy, 0), NS_ERROR_FAILURE); return NS_OK; } @@ -659,10 +659,10 @@ NS_IMETHODIMP nsContentTreeOwner::GetSize(int32_t* aCX, int32_t* aCY) } NS_IMETHODIMP nsContentTreeOwner::SetPositionAndSize(int32_t aX, int32_t aY, - int32_t aCX, int32_t aCY, bool aRepaint) + int32_t aCX, int32_t aCY, uint32_t aFlags) { NS_ENSURE_STATE(mXULWindow); - return mXULWindow->SetPositionAndSize(aX, aY, aCX, aCY, aRepaint); + return mXULWindow->SetPositionAndSize(aX, aY, aCX, aCY, aFlags); } NS_IMETHODIMP nsContentTreeOwner::GetPositionAndSize(int32_t* aX, int32_t* aY, @@ -1058,7 +1058,8 @@ nsSiteWindow::SetDimensions(uint32_t aFlags, int32_t aX, int32_t aY, int32_t aCX, int32_t aCY) { // XXX we're ignoring aFlags - return mAggregator->SetPositionAndSize(aX, aY, aCX, aCY, true); + return mAggregator->SetPositionAndSize(aX, aY, aCX, aCY, + nsIBaseWindow::eRepaint); } NS_IMETHODIMP diff --git a/xpfe/appshell/nsWebShellWindow.cpp b/xpfe/appshell/nsWebShellWindow.cpp index 46352447fe78..271de3093f24 100644 --- a/xpfe/appshell/nsWebShellWindow.cpp +++ b/xpfe/appshell/nsWebShellWindow.cpp @@ -281,7 +281,7 @@ nsWebShellWindow::WindowResized(nsIWidget* aWidget, int32_t aWidth, int32_t aHei { nsCOMPtr shellAsWin(do_QueryInterface(mDocShell)); if (shellAsWin) { - shellAsWin->SetPositionAndSize(0, 0, aWidth, aHeight, false); + shellAsWin->SetPositionAndSize(0, 0, aWidth, aHeight, 0); } // Persist size, but not immediately, in case this OS is firing // repeated size events as the user drags the sizing handle diff --git a/xpfe/appshell/nsXULWindow.cpp b/xpfe/appshell/nsXULWindow.cpp index ea23e6124f97..139406581a2a 100644 --- a/xpfe/appshell/nsXULWindow.cpp +++ b/xpfe/appshell/nsXULWindow.cpp @@ -641,7 +641,7 @@ NS_IMETHODIMP nsXULWindow::GetSize(int32_t* aCX, int32_t* aCY) } NS_IMETHODIMP nsXULWindow::SetPositionAndSize(int32_t aX, int32_t aY, - int32_t aCX, int32_t aCY, bool aRepaint) + int32_t aCX, int32_t aCY, uint32_t aFlags) { /* any attempt to set the window's size or position overrides the window's zoom state. this is important when these two states are competing while @@ -653,7 +653,7 @@ NS_IMETHODIMP nsXULWindow::SetPositionAndSize(int32_t aX, int32_t aY, DesktopToLayoutDeviceScale scale = mWindow->GetDesktopToDeviceScale(); DesktopRect rect = LayoutDeviceIntRect(aX, aY, aCX, aCY) / scale; nsresult rv = mWindow->Resize(rect.x, rect.y, rect.width, rect.height, - aRepaint); + !!(aFlags & nsIBaseWindow::eRepaint)); NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE); if (!mChromeLoaded) { // If we're called before the chrome is loaded someone obviously wants this