From 6b6125f47385c24e84425655dd882991d4171e17 Mon Sep 17 00:00:00 2001 From: Doug Turner Date: Tue, 26 Jun 2012 05:51:24 -0700 Subject: [PATCH 01/63] Bug 767894 - Device Storage - move test from dom/tests/mochitest/devicestorage to dom/devicestorage. rs=bent --HG-- rename : dom/tests/mochitest/devicestorage/Makefile.in => dom/devicestorage/test/Makefile.in rename : dom/tests/mochitest/devicestorage/devicestorage_common.js => dom/devicestorage/test/devicestorage_common.js rename : dom/tests/mochitest/devicestorage/test_basic.html => dom/devicestorage/test/test_basic.html rename : dom/tests/mochitest/devicestorage/test_dotdot.html => dom/devicestorage/test/test_dotdot.html rename : dom/tests/mochitest/devicestorage/test_enumerate.html => dom/devicestorage/test/test_enumerate.html rename : dom/tests/mochitest/devicestorage/test_enumerateMultipleContinue.html => dom/devicestorage/test/test_enumerateMultipleContinue.html rename : dom/tests/mochitest/devicestorage/test_enumerateNoParam.html => dom/devicestorage/test/test_enumerateNoParam.html rename : dom/tests/mochitest/devicestorage/test_enumerateOptions.html => dom/devicestorage/test/test_enumerateOptions.html rename : dom/tests/mochitest/devicestorage/test_lastModificationFilter.html => dom/devicestorage/test/test_lastModificationFilter.html rename : dom/tests/mochitest/devicestorage/test_overwrite.html => dom/devicestorage/test/test_overwrite.html rename : dom/tests/mochitest/devicestorage/test_sanity.html => dom/devicestorage/test/test_sanity.html --- dom/devicestorage/Makefile.in | 2 ++ .../devicestorage => devicestorage/test}/Makefile.in | 4 ++-- .../test}/devicestorage_common.js | 0 .../devicestorage => devicestorage/test}/test_basic.html | 0 .../devicestorage => devicestorage/test}/test_dotdot.html | 0 .../devicestorage => devicestorage/test}/test_enumerate.html | 0 .../test}/test_enumerateMultipleContinue.html | 0 .../test}/test_enumerateNoParam.html | 0 .../test}/test_enumerateOptions.html | 0 .../test}/test_lastModificationFilter.html | 0 .../devicestorage => devicestorage/test}/test_overwrite.html | 0 .../devicestorage => devicestorage/test}/test_sanity.html | 0 dom/tests/mochitest/Makefile.in | 1 - 13 files changed, 4 insertions(+), 3 deletions(-) rename dom/{tests/mochitest/devicestorage => devicestorage/test}/Makefile.in (90%) rename dom/{tests/mochitest/devicestorage => devicestorage/test}/devicestorage_common.js (100%) rename dom/{tests/mochitest/devicestorage => devicestorage/test}/test_basic.html (100%) rename dom/{tests/mochitest/devicestorage => devicestorage/test}/test_dotdot.html (100%) rename dom/{tests/mochitest/devicestorage => devicestorage/test}/test_enumerate.html (100%) rename dom/{tests/mochitest/devicestorage => devicestorage/test}/test_enumerateMultipleContinue.html (100%) rename dom/{tests/mochitest/devicestorage => devicestorage/test}/test_enumerateNoParam.html (100%) rename dom/{tests/mochitest/devicestorage => devicestorage/test}/test_enumerateOptions.html (100%) rename dom/{tests/mochitest/devicestorage => devicestorage/test}/test_lastModificationFilter.html (100%) rename dom/{tests/mochitest/devicestorage => devicestorage/test}/test_overwrite.html (100%) rename dom/{tests/mochitest/devicestorage => devicestorage/test}/test_sanity.html (100%) diff --git a/dom/devicestorage/Makefile.in b/dom/devicestorage/Makefile.in index be8b0f586607..23bce76d9daf 100644 --- a/dom/devicestorage/Makefile.in +++ b/dom/devicestorage/Makefile.in @@ -32,6 +32,8 @@ LOCAL_INCLUDES = \ -I$(topsrcdir)/content/events/src \ $(NULL) +TEST_DIRS += test + include $(topsrcdir)/config/config.mk include $(topsrcdir)/ipc/chromium/chromium-config.mk include $(topsrcdir)/config/rules.mk diff --git a/dom/tests/mochitest/devicestorage/Makefile.in b/dom/devicestorage/test/Makefile.in similarity index 90% rename from dom/tests/mochitest/devicestorage/Makefile.in rename to dom/devicestorage/test/Makefile.in index 844f0f1e0621..7a2d5b843f3f 100644 --- a/dom/tests/mochitest/devicestorage/Makefile.in +++ b/dom/devicestorage/test/Makefile.in @@ -2,11 +2,11 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this file, # You can obtain one at http://mozilla.org/MPL/2.0/. -DEPTH = ../../../.. +DEPTH = ../../.. topsrcdir = @top_srcdir@ srcdir = @srcdir@ VPATH = @srcdir@ -relativesrcdir = dom/tests/mochitest/devicestorage +relativesrcdir = dom/devicestorage/test/ include $(DEPTH)/config/autoconf.mk diff --git a/dom/tests/mochitest/devicestorage/devicestorage_common.js b/dom/devicestorage/test/devicestorage_common.js similarity index 100% rename from dom/tests/mochitest/devicestorage/devicestorage_common.js rename to dom/devicestorage/test/devicestorage_common.js diff --git a/dom/tests/mochitest/devicestorage/test_basic.html b/dom/devicestorage/test/test_basic.html similarity index 100% rename from dom/tests/mochitest/devicestorage/test_basic.html rename to dom/devicestorage/test/test_basic.html diff --git a/dom/tests/mochitest/devicestorage/test_dotdot.html b/dom/devicestorage/test/test_dotdot.html similarity index 100% rename from dom/tests/mochitest/devicestorage/test_dotdot.html rename to dom/devicestorage/test/test_dotdot.html diff --git a/dom/tests/mochitest/devicestorage/test_enumerate.html b/dom/devicestorage/test/test_enumerate.html similarity index 100% rename from dom/tests/mochitest/devicestorage/test_enumerate.html rename to dom/devicestorage/test/test_enumerate.html diff --git a/dom/tests/mochitest/devicestorage/test_enumerateMultipleContinue.html b/dom/devicestorage/test/test_enumerateMultipleContinue.html similarity index 100% rename from dom/tests/mochitest/devicestorage/test_enumerateMultipleContinue.html rename to dom/devicestorage/test/test_enumerateMultipleContinue.html diff --git a/dom/tests/mochitest/devicestorage/test_enumerateNoParam.html b/dom/devicestorage/test/test_enumerateNoParam.html similarity index 100% rename from dom/tests/mochitest/devicestorage/test_enumerateNoParam.html rename to dom/devicestorage/test/test_enumerateNoParam.html diff --git a/dom/tests/mochitest/devicestorage/test_enumerateOptions.html b/dom/devicestorage/test/test_enumerateOptions.html similarity index 100% rename from dom/tests/mochitest/devicestorage/test_enumerateOptions.html rename to dom/devicestorage/test/test_enumerateOptions.html diff --git a/dom/tests/mochitest/devicestorage/test_lastModificationFilter.html b/dom/devicestorage/test/test_lastModificationFilter.html similarity index 100% rename from dom/tests/mochitest/devicestorage/test_lastModificationFilter.html rename to dom/devicestorage/test/test_lastModificationFilter.html diff --git a/dom/tests/mochitest/devicestorage/test_overwrite.html b/dom/devicestorage/test/test_overwrite.html similarity index 100% rename from dom/tests/mochitest/devicestorage/test_overwrite.html rename to dom/devicestorage/test/test_overwrite.html diff --git a/dom/tests/mochitest/devicestorage/test_sanity.html b/dom/devicestorage/test/test_sanity.html similarity index 100% rename from dom/tests/mochitest/devicestorage/test_sanity.html rename to dom/devicestorage/test/test_sanity.html diff --git a/dom/tests/mochitest/Makefile.in b/dom/tests/mochitest/Makefile.in index 481e24a89842..6411d139867c 100644 --- a/dom/tests/mochitest/Makefile.in +++ b/dom/tests/mochitest/Makefile.in @@ -18,7 +18,6 @@ DIRS += \ ajax \ bugs \ chrome \ - devicestorage \ general \ whatwg \ geolocation \ From e1a76d8a6259c9b3e506f5dd278080b99e2f3f10 Mon Sep 17 00:00:00 2001 From: Doug Turner Date: Tue, 26 Jun 2012 05:51:24 -0700 Subject: [PATCH 02/63] Bug 767905 - device storage - Move editable flag into DeviceStorageFile. r=bent --- dom/devicestorage/nsDeviceStorage.cpp | 51 +++++++++++++-------------- 1 file changed, 24 insertions(+), 27 deletions(-) diff --git a/dom/devicestorage/nsDeviceStorage.cpp b/dom/devicestorage/nsDeviceStorage.cpp index 5a9c20b36256..2a877c60e542 100644 --- a/dom/devicestorage/nsDeviceStorage.cpp +++ b/dom/devicestorage/nsDeviceStorage.cpp @@ -28,9 +28,11 @@ public: nsCOMPtr mFile; nsString mPath; + bool mEditable; DeviceStorageFile(nsIFile* aFile, const nsAString& aPath) : mPath(aPath) + , mEditable(false) { NS_ASSERTION(aFile, "Must not create a DeviceStorageFile with a null nsIFile"); // always take a clone @@ -43,6 +45,7 @@ public: } DeviceStorageFile(nsIFile* aFile) + : mEditable(false) { NS_ASSERTION(aFile, "Must not create a DeviceStorageFile with a null nsIFile"); // always take a clone @@ -56,6 +59,11 @@ public: NormalizeFilePath(); } + void + setEditable(bool aEditable) { + mEditable = aEditable; + } + NS_DECL_ISUPPORTS // we want to make sure that the names of file can't reach @@ -220,12 +228,12 @@ nsDOMDeviceStorage::SetRootFileForType(const nsAString& aType, const PRInt32 aIn return typeResult; } -static jsval nsIFileToJsval(nsPIDOMWindow* aWindow, DeviceStorageFile* aFile, bool aEditable) +static jsval nsIFileToJsval(nsPIDOMWindow* aWindow, DeviceStorageFile* aFile) { NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); NS_ASSERTION(aWindow, "Null Window"); - if (aEditable) { + if (aFile->mEditable) { // TODO - needs janv's file handle support. return JSVAL_NULL; } @@ -309,7 +317,6 @@ public: nsDOMDeviceStorageCursor(nsIDOMWindow* aWindow, nsIURI* aURI, DeviceStorageFile* aFile, - bool aEditable, PRUint64 aSince); private: @@ -321,7 +328,6 @@ protected: bool mOkToCallContinue; nsRefPtr mFile; nsCOMPtr mURI; - bool mEditable; PRUint64 mSince; // to access mFiles @@ -453,7 +459,7 @@ public: else { nsRefPtr file = cursor->mFiles[0]; cursor->mFiles.RemoveElementAt(0); - val = nsIFileToJsval(cursor->GetOwner(), file, cursor->mEditable); + val = nsIFileToJsval(cursor->GetOwner(), file); cursor->mOkToCallContinue = true; } @@ -578,13 +584,11 @@ NS_IMPL_RELEASE_INHERITED(nsDOMDeviceStorageCursor, DOMRequest) nsDOMDeviceStorageCursor::nsDOMDeviceStorageCursor(nsIDOMWindow* aWindow, nsIURI* aURI, DeviceStorageFile* aFile, - bool aEditable, PRUint64 aSince) : DOMRequest(aWindow) , mOkToCallContinue(false) , mFile(aFile) , mURI(aURI) - , mEditable(aEditable) , mSince(aSince) { } @@ -677,9 +681,8 @@ nsDOMDeviceStorageCursor::Continue() class PostResultEvent : public nsRunnable { public: - PostResultEvent(nsRefPtr& aRequest, bool aEditable, DeviceStorageFile* aFile) - : mEditable(aEditable) - , mFile(aFile) + PostResultEvent(nsRefPtr& aRequest, DeviceStorageFile* aFile) + : mFile(aFile) { mRequest.swap(aRequest); } @@ -698,7 +701,7 @@ public: jsval result = JSVAL_NULL; if (mFile) { - result = nsIFileToJsval(mRequest->GetOwner(), mFile, mEditable); + result = nsIFileToJsval(mRequest->GetOwner(), mFile); } else { result = StringToJsval(mRequest->GetOwner(), mPath); } @@ -709,7 +712,6 @@ public: } private: - bool mEditable; nsRefPtr mFile; nsString mPath; nsRefPtr mRequest; @@ -808,16 +810,12 @@ private: nsRefPtr mFile; nsRefPtr mRequest; }; - - class ReadFileEvent : public nsRunnable { public: ReadFileEvent(DeviceStorageFile* aFile, - bool aEditable, nsRefPtr& aRequest) : mFile(aFile) - , mEditable(aEditable) { mRequest.swap(aRequest); } @@ -830,7 +828,7 @@ public: nsRefPtr r; - if (!mEditable) { + if (!mFile->mEditable) { bool check = false; mFile->mFile->Exists(&check); if (!check) { @@ -839,7 +837,7 @@ public: } if (!r) { - r = new PostResultEvent(mRequest, mEditable, mFile); + r = new PostResultEvent(mRequest, mFile); } NS_DispatchToMainThread(r); return NS_OK; @@ -847,7 +845,6 @@ public: private: nsRefPtr mFile; - bool mEditable; nsRefPtr mRequest; }; @@ -902,14 +899,12 @@ public: nsIURI *aURI, DeviceStorageFile *aFile, DOMRequest* aRequest, - bool aEditable, nsIDOMBlob *aBlob = nsnull) : mRequestType(aRequestType) , mWindow(aWindow) , mURI(aURI) , mFile(aFile) , mRequest(aRequest) - , mEditable(aEditable) , mBlob(aBlob) {} NS_DECL_CYCLE_COLLECTING_ISUPPORTS @@ -982,7 +977,7 @@ public: } case DEVICE_STORAGE_REQUEST_READ: { - r = new ReadFileEvent(mFile, mEditable, mRequest); + r = new ReadFileEvent(mFile, mRequest); break; } case DEVICE_STORAGE_REQUEST_DELETE: @@ -1007,7 +1002,6 @@ private: nsRefPtr mFile; nsRefPtr mRequest; - bool mEditable; nsCOMPtr mBlob; }; @@ -1165,7 +1159,7 @@ nsDOMDeviceStorage::AddNamed(nsIDOMBlob *aBlob, } else { r = new DeviceStorageRequest(DeviceStorageRequest::DEVICE_STORAGE_REQUEST_WRITE, - win, mURI, dsf, request, true, aBlob); + win, mURI, dsf, request, aBlob); } NS_DispatchToMainThread(r); return NS_OK; @@ -1215,12 +1209,13 @@ nsDOMDeviceStorage::GetInternal(const JS::Value & aPath, } nsRefPtr dsf = new DeviceStorageFile(mFile, path); + dsf->setEditable(aEditable); if (!dsf->isSafePath()) { r = new PostErrorEvent(request, POST_ERROR_EVENT_ILLEGAL_FILE_NAME, dsf); } else { r = new DeviceStorageRequest(DeviceStorageRequest::DEVICE_STORAGE_REQUEST_READ, - win, mURI, dsf, request, aEditable); + win, mURI, dsf, request); } NS_DispatchToMainThread(r); return NS_OK; @@ -1255,7 +1250,7 @@ nsDOMDeviceStorage::Delete(const JS::Value & aPath, JSContext* aCx, nsIDOMDOMReq } else { r = new DeviceStorageRequest(DeviceStorageRequest::DEVICE_STORAGE_REQUEST_DELETE, - win, mURI, dsf, request, true); + win, mURI, dsf, request); } NS_DispatchToMainThread(r); return NS_OK; @@ -1336,7 +1331,9 @@ nsDOMDeviceStorage::EnumerateInternal(const JS::Value & aName, } nsRefPtr dsf = new DeviceStorageFile(mFile, path); - nsRefPtr cursor = new nsDOMDeviceStorageCursor(win, mURI, dsf, aEditable, since); + dsf->setEditable(aEditable); + + nsRefPtr cursor = new nsDOMDeviceStorageCursor(win, mURI, dsf, since); nsRefPtr r = new DeviceStorageCursorRequest(cursor); NS_ADDREF(*aRetval = cursor); From ad588803bae5738f4cf315ff4ccddf318b47b7ca Mon Sep 17 00:00:00 2001 From: Chris Lord Date: Tue, 26 Jun 2012 14:42:57 +0100 Subject: [PATCH 03/63] Bug 758620 - Layout fixed-position frames to the set scroll-port. r=roc If a scroll position clamping scroll-port size has been set, layout fixed position frames with respect to this instead of the calculated containing block size. --- layout/base/nsPresShell.cpp | 20 +++++++++++++++++--- layout/generic/nsViewportFrame.cpp | 14 ++++++++++++-- 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp index 6f7d9d8d4cf8..f1f1bab0a7fe 100644 --- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -8965,9 +8965,23 @@ PresShell::SizeOfTextRuns(nsMallocSizeOfFun aMallocSizeOf) const void nsIPresShell::SetScrollPositionClampingScrollPortSize(nscoord aWidth, nscoord aHeight) { - mScrollPositionClampingScrollPortSizeSet = true; - mScrollPositionClampingScrollPortSize.width = aWidth; - mScrollPositionClampingScrollPortSize.height = aHeight; + if (!mScrollPositionClampingScrollPortSizeSet || + mScrollPositionClampingScrollPortSize.width != aWidth || + mScrollPositionClampingScrollPortSize.height != aHeight) { + mScrollPositionClampingScrollPortSizeSet = true; + mScrollPositionClampingScrollPortSize.width = aWidth; + mScrollPositionClampingScrollPortSize.height = aHeight; + + // Reflow fixed position children. + nsIFrame* rootFrame = mFrameConstructor->GetRootFrame(); + if (rootFrame) { + const nsFrameList& childList = rootFrame->GetChildList(nsIFrame::kFixedList); + for (nsIFrame* child = childList.FirstChild(); child; + child = child->GetNextSibling()) { + FrameNeedsReflow(child, eResize, NS_FRAME_IS_DIRTY); + } + } + } } void diff --git a/layout/generic/nsViewportFrame.cpp b/layout/generic/nsViewportFrame.cpp index c5eb836ee7d1..35049eecbb81 100644 --- a/layout/generic/nsViewportFrame.cpp +++ b/layout/generic/nsViewportFrame.cpp @@ -234,10 +234,20 @@ ViewportFrame::Reflow(nsPresContext* aPresContext, "We don't handle correct positioning of fixed frames with " "scrollbars in odd positions"); + // If a scroll position clamping scroll-port size has been set, layout + // fixed position elements to this size instead of the computed size. + nscoord width = reflowState.ComputedWidth(); + nscoord height = reflowState.ComputedHeight(); + if (aPresContext->PresShell()->IsScrollPositionClampingScrollPortSizeSet()) { + nsSize size = aPresContext->PresShell()-> + GetScrollPositionClampingScrollPortSize(); + width = size.width; + height = size.height; + } + // Just reflow all the fixed-pos frames. rv = GetAbsoluteContainingBlock()->Reflow(this, aPresContext, reflowState, aStatus, - reflowState.ComputedWidth(), - reflowState.ComputedHeight(), + width, height, false, true, true, // XXX could be optimized &aDesiredSize.mOverflowAreas); } From d68b636b068dc049f4a69b7a1dc3a9cff392250a Mon Sep 17 00:00:00 2001 From: Chris Lord Date: Tue, 26 Jun 2012 14:43:11 +0100 Subject: [PATCH 04/63] Bug 758620 - Force fixed-position frames to have their own layers. r=roc Introduce a new display-list item 'nsDisplayFixedPosition' that represents fixed-position elements. This item cannot be merged, which forces fixed position elements to have their own layer, and has a BuildLayer implementation that sets the necessary metadata on a Layer to be able to maintain its position correctly during composition when asynchronously panning and zooming. --- gfx/layers/Layers.h | 11 +++++ gfx/layers/ipc/PLayers.ipdl | 2 + gfx/layers/ipc/ShadowLayers.cpp | 1 + gfx/layers/ipc/ShadowLayersParent.cpp | 1 + ipc/glue/IPCMessageUtils.h | 21 +++++++++ layout/base/nsDisplayList.cpp | 62 +++++++++++++++++++++++++++ layout/base/nsDisplayList.h | 19 ++++++++ layout/generic/nsFrame.cpp | 12 +++++- 8 files changed, 127 insertions(+), 2 deletions(-) diff --git a/gfx/layers/Layers.h b/gfx/layers/Layers.h index 10d41690e333..595b23bc862b 100644 --- a/gfx/layers/Layers.h +++ b/gfx/layers/Layers.h @@ -731,6 +731,15 @@ public: */ void SetIsFixedPosition(bool aFixedPosition) { mIsFixedPosition = aFixedPosition; } + /** + * CONSTRUCTION PHASE ONLY + * If a layer is "fixed position", this determines which point on the layer + * is considered the "anchor" point, that is, the point which remains in the + * same position when compositing the layer tree with a transformation + * (such as when asynchronously scrolling and zooming). + */ + void SetFixedPositionAnchor(const gfxPoint& aAnchor) { mAnchor = aAnchor; } + // These getters can be used anytime. float GetOpacity() { return mOpacity; } const nsIntRect* GetClipRect() { return mUseClipRect ? &mClipRect : nsnull; } @@ -743,6 +752,7 @@ public: virtual Layer* GetLastChild() { return nsnull; } const gfx3DMatrix& GetTransform() { return mTransform; } bool GetIsFixedPosition() { return mIsFixedPosition; } + gfxPoint GetFixedPositionAnchor() { return mAnchor; } Layer* GetMaskLayer() { return mMaskLayer; } /** @@ -992,6 +1002,7 @@ protected: bool mUseClipRect; bool mUseTileSourceRect; bool mIsFixedPosition; + gfxPoint mAnchor; DebugOnly mDebugColorIndex; }; diff --git a/gfx/layers/ipc/PLayers.ipdl b/gfx/layers/ipc/PLayers.ipdl index 28dbb7269336..365094f31bba 100644 --- a/gfx/layers/ipc/PLayers.ipdl +++ b/gfx/layers/ipc/PLayers.ipdl @@ -12,6 +12,7 @@ include protocol PRenderFrame; include "gfxipc/ShadowLayerUtils.h"; using gfx3DMatrix; +using gfxPoint; using gfxRGBA; using nsIntPoint; using nsIntRect; @@ -85,6 +86,7 @@ struct CommonLayerAttributes { bool useClipRect; nsIntRect clipRect; bool isFixedPosition; + gfxPoint fixedPositionAnchor; nullable PLayer maskLayer; }; diff --git a/gfx/layers/ipc/ShadowLayers.cpp b/gfx/layers/ipc/ShadowLayers.cpp index 7783c4131527..e0def0444339 100644 --- a/gfx/layers/ipc/ShadowLayers.cpp +++ b/gfx/layers/ipc/ShadowLayers.cpp @@ -291,6 +291,7 @@ ShadowLayerForwarder::EndTransaction(InfallibleTArray* aReplies) common.clipRect() = (common.useClipRect() ? *mutant->GetClipRect() : nsIntRect()); common.isFixedPosition() = mutant->GetIsFixedPosition(); + common.fixedPositionAnchor() = mutant->GetFixedPositionAnchor(); if (Layer* maskLayer = mutant->GetMaskLayer()) { common.maskLayerChild() = Shadow(maskLayer->AsShadowableLayer()); } else { diff --git a/gfx/layers/ipc/ShadowLayersParent.cpp b/gfx/layers/ipc/ShadowLayersParent.cpp index 755545476ea2..e7d921daea3b 100644 --- a/gfx/layers/ipc/ShadowLayersParent.cpp +++ b/gfx/layers/ipc/ShadowLayersParent.cpp @@ -207,6 +207,7 @@ ShadowLayersParent::RecvUpdate(const InfallibleTArray& cset, static bool fixedPositionLayersEnabled = getenv("MOZ_ENABLE_FIXED_POSITION_LAYERS") != 0; if (fixedPositionLayersEnabled) { layer->SetIsFixedPosition(common.isFixedPosition()); + layer->SetFixedPositionAnchor(common.fixedPositionAnchor()); } if (PLayerParent* maskLayer = common.maskLayerParent()) { layer->SetMaskLayer(cast(maskLayer)->AsLayer()); diff --git a/ipc/glue/IPCMessageUtils.h b/ipc/glue/IPCMessageUtils.h index 5f8cfe32171f..99018b56743b 100644 --- a/ipc/glue/IPCMessageUtils.h +++ b/ipc/glue/IPCMessageUtils.h @@ -427,6 +427,27 @@ struct ParamTraits } }; +template<> +struct ParamTraits +{ + typedef gfxPoint paramType; + + static void Write(Message* aMsg, const paramType& aParam) + { + WriteParam(aMsg, aParam.x); + WriteParam(aMsg, aParam.y); + } + + static bool Read(const Message* aMsg, void** aIter, paramType* aResult) + { + if (ReadParam(aMsg, aIter, &aResult->x) && + ReadParam(aMsg, aIter, &aResult->y)) + return true; + + return false; + } +}; + template<> struct ParamTraits { diff --git a/layout/base/nsDisplayList.cpp b/layout/base/nsDisplayList.cpp index ca45a931b039..ab388534214f 100644 --- a/layout/base/nsDisplayList.cpp +++ b/layout/base/nsDisplayList.cpp @@ -2002,6 +2002,68 @@ nsDisplayOwnLayer::BuildLayer(nsDisplayListBuilder* aBuilder, return layer.forget(); } +nsDisplayFixedPosition::nsDisplayFixedPosition(nsDisplayListBuilder* aBuilder, + nsIFrame* aFrame, + nsDisplayList* aList) + : nsDisplayOwnLayer(aBuilder, aFrame, aList) { + MOZ_COUNT_CTOR(nsDisplayFixedPosition); +} + +#ifdef NS_BUILD_REFCNT_LOGGING +nsDisplayFixedPosition::~nsDisplayFixedPosition() { + MOZ_COUNT_DTOR(nsDisplayFixedPosition); +} +#endif + +already_AddRefed +nsDisplayFixedPosition::BuildLayer(nsDisplayListBuilder* aBuilder, + LayerManager* aManager, + const ContainerParameters& aContainerParameters) { + nsRefPtr layer = + nsDisplayOwnLayer::BuildLayer(aBuilder, aManager, aContainerParameters); + + // Work out the anchor point for this fixed position layer. We assume that + // any positioning set (left/top/right/bottom) indicates that the + // corresponding side of its container should be the anchor point, + // defaulting to top-left. + nsIFrame* viewportFrame = mFrame->GetParent(); + nsPresContext *presContext = viewportFrame->PresContext(); + + // Fixed position frames are reflowed into the scroll-port size if one has + // been set. + nsSize containingBlockSize = viewportFrame->GetSize(); + if (presContext->PresShell()->IsScrollPositionClampingScrollPortSizeSet()) { + containingBlockSize = presContext->PresShell()-> + GetScrollPositionClampingScrollPortSize(); + } + + // Find out the rect of the viewport frame relative to the reference frame. + // This, in conjunction with the container scale, will correspond to the + // coordinate-space of the built layer. + float factor = presContext->AppUnitsPerDevPixel(); + nsPoint origin = aBuilder->ToReferenceFrame(viewportFrame); + gfxRect anchorRect(NSAppUnitsToFloatPixels(origin.x, factor) * + aContainerParameters.mXScale, + NSAppUnitsToFloatPixels(origin.y, factor) * + aContainerParameters.mYScale, + NSAppUnitsToFloatPixels(containingBlockSize.width, factor) * + aContainerParameters.mXScale, + NSAppUnitsToFloatPixels(containingBlockSize.height, factor) * + aContainerParameters.mYScale); + + gfxPoint anchor(anchorRect.x, anchorRect.y); + + const nsStylePosition* position = mFrame->GetStylePosition(); + if (position->mOffset.GetRightUnit() != eStyleUnit_Auto) + anchor.x = anchorRect.XMost(); + if (position->mOffset.GetBottomUnit() != eStyleUnit_Auto) + anchor.y = anchorRect.YMost(); + + layer->SetFixedPositionAnchor(anchor); + + return layer.forget(); +} + nsDisplayScrollLayer::nsDisplayScrollLayer(nsDisplayListBuilder* aBuilder, nsDisplayList* aList, nsIFrame* aForFrame, diff --git a/layout/base/nsDisplayList.h b/layout/base/nsDisplayList.h index 77bcfa3ddccd..e263d2f051d6 100644 --- a/layout/base/nsDisplayList.h +++ b/layout/base/nsDisplayList.h @@ -1909,6 +1909,25 @@ public: NS_DISPLAY_DECL_NAME("OwnLayer", TYPE_OWN_LAYER) }; +/** + * A display item used to represent fixed position elements. This will ensure + * the contents gets its own layer, and that the built layer will have + * position-related metadata set on it. + */ +class nsDisplayFixedPosition : public nsDisplayOwnLayer { +public: + nsDisplayFixedPosition(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, + nsDisplayList* aList); +#ifdef NS_BUILD_REFCNT_LOGGING + virtual ~nsDisplayFixedPosition(); +#endif + + virtual already_AddRefed BuildLayer(nsDisplayListBuilder* aBuilder, + LayerManager* aManager, + const ContainerParameters& aContainerParameters); + NS_DISPLAY_DECL_NAME("FixedPosition", TYPE_OWN_LAYER) +}; + /** * This potentially creates a layer for the given list of items, whose * visibility is determined by the displayport for the given frame instead of diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index 523d05c614b5..87dd6490f2d1 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -2168,8 +2168,16 @@ nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder, // Genuine stacking contexts, and positioned pseudo-stacking-contexts, // go in this level. if (!list.IsEmpty()) { - rv = aLists.PositionedDescendants()->AppendNewToTop(new (aBuilder) - nsDisplayWrapList(aBuilder, child, &list)); + // Make sure the root of a fixed position frame sub-tree gets the + // correct displaylist item type. + nsDisplayItem* item; + if (!child->GetParent()->GetParent() && + disp->mPosition == NS_STYLE_POSITION_FIXED) { + item = new (aBuilder) nsDisplayFixedPosition(aBuilder, child, &list); + } else { + item = new (aBuilder) nsDisplayWrapList(aBuilder, child, &list); + } + rv = aLists.PositionedDescendants()->AppendNewToTop(item); NS_ENSURE_SUCCESS(rv, rv); } } else if (disp->IsFloating()) { From 26c38c29080018364593d23691e924b728ad41ce Mon Sep 17 00:00:00 2001 From: Chris Lord Date: Tue, 26 Jun 2012 14:43:18 +0100 Subject: [PATCH 05/63] Bug 758620 - Respect the Layers' anchor points in CompositorParent. r=ajuma When asynchronously zooming, respect a Layer's anchor point so that it stays in the correct position. --- gfx/layers/ipc/CompositorParent.cpp | 50 +++++++++++++++++++++-------- gfx/layers/ipc/CompositorParent.h | 11 +++++-- 2 files changed, 44 insertions(+), 17 deletions(-) diff --git a/gfx/layers/ipc/CompositorParent.cpp b/gfx/layers/ipc/CompositorParent.cpp index 14151d622091..29965a99767c 100644 --- a/gfx/layers/ipc/CompositorParent.cpp +++ b/gfx/layers/ipc/CompositorParent.cpp @@ -313,27 +313,35 @@ Translate2D(gfx3DMatrix& aTransform, const gfxPoint& aOffset) } void -CompositorParent::TranslateFixedLayers(Layer* aLayer, - const gfxPoint& aTranslation) +CompositorParent::TransformFixedLayers(Layer* aLayer, + const gfxPoint& aTranslation, + const gfxPoint& aScaleDiff) { if (aLayer->GetIsFixedPosition() && !aLayer->GetParent()->GetIsFixedPosition()) { + // When a scale has been applied to a layer, it focuses around (0,0). + // The anchor position is used here as a scale focus point (assuming that + // aScaleDiff has already been applied) to re-focus the scale. + const gfxPoint& anchor = aLayer->GetFixedPositionAnchor(); + gfxPoint translation(aTranslation.x - (anchor.x - anchor.x / aScaleDiff.x), + aTranslation.y - (anchor.y - anchor.y / aScaleDiff.y)); + gfx3DMatrix layerTransform = aLayer->GetTransform(); - Translate2D(layerTransform, aTranslation); + Translate2D(layerTransform, translation); ShadowLayer* shadow = aLayer->AsShadowLayer(); shadow->SetShadowTransform(layerTransform); const nsIntRect* clipRect = aLayer->GetClipRect(); if (clipRect) { nsIntRect transformedClipRect(*clipRect); - transformedClipRect.MoveBy(aTranslation.x, aTranslation.y); + transformedClipRect.MoveBy(translation.x, translation.y); shadow->SetShadowClipRect(&transformedClipRect); } } for (Layer* child = aLayer->GetFirstChild(); child; child = child->GetNextSibling()) { - TranslateFixedLayers(child, aTranslation); + TransformFixedLayers(child, aTranslation, aScaleDiff); } } @@ -411,16 +419,30 @@ CompositorParent::TransformShadowTree() ViewTransform treeTransform(-scrollCompensation, mXScale, mYScale); shadow->SetShadowTransform(gfx3DMatrix(treeTransform) * currentTransform); - // Alter the scroll offset so that fixed position layers remain within - // the page area. - float offsetX = mScrollOffset.x / tempScaleDiffX; - float offsetY = mScrollOffset.y / tempScaleDiffY; - offsetX = NS_MAX((float)mContentRect.x, NS_MIN(offsetX, (float)(mContentRect.XMost() - mWidgetSize.width))); - offsetY = NS_MAX((float)mContentRect.y, NS_MIN(offsetY, (float)(mContentRect.YMost() - mWidgetSize.height))); - gfxPoint reverseViewTranslation(offsetX - metricsScrollOffset.x, - offsetY - metricsScrollOffset.y); + // Translate fixed position layers so that they stay in the correct position + // when mScrollOffset and metricsScrollOffset differ. + gfxPoint scaleDiff(tempScaleDiffX, tempScaleDiffY); + gfxPoint offset(clamped(mScrollOffset.x / tempScaleDiffX, mContentRect.x / tempScaleDiffX, + (mContentRect.XMost() - mWidgetSize.width / tempScaleDiffX)) - + metricsScrollOffset.x, + clamped(mScrollOffset.y / tempScaleDiffY, mContentRect.y / tempScaleDiffY, + (mContentRect.YMost() - mWidgetSize.height / tempScaleDiffY)) - + metricsScrollOffset.y); - TranslateFixedLayers(layer, reverseViewTranslation); + // If the contents can fit entirely within the widget area on a particular + // dimenson, we need to translate and scale so that the fixed layers remain + // within the page boundaries. + if (mContentRect.width * tempScaleDiffX < mWidgetSize.width) { + offset.x = -metricsScrollOffset.x; + scaleDiff.x = NS_MIN(1.0f, mWidgetSize.width / (float)mContentRect.width); + } + + if (mContentRect.height * tempScaleDiffY < mWidgetSize.height) { + offset.y = -metricsScrollOffset.y; + scaleDiff.y = NS_MIN(1.0f, mWidgetSize.height / (float)mContentRect.height); + } + + TransformFixedLayers(layer, offset, scaleDiff); } void diff --git a/gfx/layers/ipc/CompositorParent.h b/gfx/layers/ipc/CompositorParent.h index ed2c6a8f8bdd..a8abbe37e1f6 100644 --- a/gfx/layers/ipc/CompositorParent.h +++ b/gfx/layers/ipc/CompositorParent.h @@ -107,10 +107,15 @@ private: Layer* GetPrimaryScrollableLayer(); /** - * Recursively applies the given translation to all fixed position layers - * that aren't children of other fixed position layers. + * Recursively applies the given translation to all top-level fixed position + * layers that are descendants of the given layer. + * aScaleDiff is considered to be the scale transformation applied when + * displaying the layers, and is used to make sure the anchor points of + * fixed position layers remain in the same position. */ - void TranslateFixedLayers(Layer* aLayer, const gfxPoint& aTranslation); + void TransformFixedLayers(Layer* aLayer, + const gfxPoint& aTranslation, + const gfxPoint& aScaleDiff); nsRefPtr mLayerManager; nsIWidget* mWidget; From 8367a07fc5d2ef4d5ef6c7b0defdba7d24316e85 Mon Sep 17 00:00:00 2001 From: Chris Lord Date: Tue, 26 Jun 2012 14:43:32 +0100 Subject: [PATCH 06/63] Bug 758620 - Clamp scroll port to content size in android fennec. r=kats Fixed position elements are laid out to the scroll-port size, so setting a scroll port larger than the content size causes fixed position elements to be pushed off of the page. --- mobile/android/chrome/content/browser.js | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/mobile/android/chrome/content/browser.js b/mobile/android/chrome/content/browser.js index b01d837d31e3..515f29c463cc 100644 --- a/mobile/android/chrome/content/browser.js +++ b/mobile/android/chrome/content/browser.js @@ -2328,11 +2328,17 @@ Tab.prototype = { let x = aViewport.x / aViewport.zoom; let y = aViewport.y / aViewport.zoom; - // Set scroll position + // Set scroll position and scroll-port clamping size + let [pageWidth, pageHeight] = this.getPageSize(this.browser.contentDocument, + aViewport.width, aViewport.height); + let scrollPortWidth = Math.min(gScreenWidth / aViewport.zoom, pageWidth); + let scrollPortHeight = Math.min(gScreenHeight / aViewport.zoom, pageHeight); + let win = this.browser.contentWindow; - win.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils).setScrollPositionClampingScrollPortSize( - gScreenWidth / aViewport.zoom, gScreenHeight / aViewport.zoom); + win.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils). + setScrollPositionClampingScrollPortSize(scrollPortWidth, scrollPortHeight); win.scrollTo(x, y); + this.userScrollPos.x = win.scrollX; this.userScrollPos.y = win.scrollY; this.setResolution(aViewport.zoom, false); From 1844dbb17473000519c559263b94a972234e6503 Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Tue, 26 Jun 2012 16:01:53 +0200 Subject: [PATCH 07/63] Bug 766878 - IME prototype doesn't work with