mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 508816 - layout patch
This commit is contained in:
parent
8847abc54d
commit
e5ed17c7d6
@ -98,7 +98,7 @@ NS_IMPL_FRAMEARENA_HELPERS(nsHTMLScrollFrame)
|
||||
|
||||
nsHTMLScrollFrame::nsHTMLScrollFrame(nsIPresShell* aShell, nsStyleContext* aContext, PRBool aIsRoot)
|
||||
: nsHTMLContainerFrame(aContext),
|
||||
mInner(this, aIsRoot, PR_FALSE)
|
||||
mInner(this, aIsRoot)
|
||||
{
|
||||
}
|
||||
|
||||
@ -978,7 +978,7 @@ NS_IMPL_FRAMEARENA_HELPERS(nsXULScrollFrame)
|
||||
|
||||
nsXULScrollFrame::nsXULScrollFrame(nsIPresShell* aShell, nsStyleContext* aContext, PRBool aIsRoot)
|
||||
: nsBoxFrame(aShell, aContext, aIsRoot),
|
||||
mInner(this, aIsRoot, PR_TRUE)
|
||||
mInner(this, aIsRoot)
|
||||
{
|
||||
SetLayoutManager(nsnull);
|
||||
}
|
||||
@ -1351,8 +1351,7 @@ public:
|
||||
static ScrollFrameActivityTracker *gScrollFrameActivityTracker = nsnull;
|
||||
|
||||
nsGfxScrollFrameInner::nsGfxScrollFrameInner(nsContainerFrame* aOuter,
|
||||
PRBool aIsRoot,
|
||||
PRBool aIsXUL)
|
||||
PRBool aIsRoot)
|
||||
: mHScrollbarBox(nsnull),
|
||||
mVScrollbarBox(nsnull),
|
||||
mScrolledFrame(nsnull),
|
||||
@ -1371,7 +1370,6 @@ nsGfxScrollFrameInner::nsGfxScrollFrameInner(nsContainerFrame* aOuter,
|
||||
mFrameIsUpdatingScrollbar(PR_FALSE),
|
||||
mDidHistoryRestore(PR_FALSE),
|
||||
mIsRoot(aIsRoot),
|
||||
mIsXUL(aIsXUL),
|
||||
mSupppressScrollbarUpdate(PR_FALSE),
|
||||
mSkippedScrollbarLayout(PR_FALSE),
|
||||
mHadNonInitialReflow(PR_FALSE),
|
||||
@ -2101,18 +2099,21 @@ nsGfxScrollFrameInner::ScrollToRestoredPosition()
|
||||
// make sure our scroll position did not change for where we last put
|
||||
// it. if it does then the user must have moved it, and we no longer
|
||||
// need to restore.
|
||||
nsPoint scrollPos = GetScrollPosition();
|
||||
//
|
||||
// In the RTL case, we check whether the scroll position changed using the
|
||||
// logical scroll position, but we scroll to the physical scroll position in
|
||||
// all cases
|
||||
|
||||
// if we didn't move, we still need to restore
|
||||
if (scrollPos == mLastPos) {
|
||||
if (GetLogicalScrollPosition() == mLastPos) {
|
||||
// if our desired position is different to the scroll position, scroll.
|
||||
// remember that we could be incrementally loading so we may enter
|
||||
// and scroll many times.
|
||||
if (mRestorePos != scrollPos) {
|
||||
if (mRestorePos != GetScrollPosition()) {
|
||||
ScrollTo(mRestorePos, nsIScrollableFrame::INSTANT);
|
||||
// Re-get the scroll position, it might not be exactly equal to
|
||||
// mRestorePos due to rounding and clamping.
|
||||
mLastPos = GetScrollPosition();
|
||||
mLastPos = GetLogicalScrollPosition();
|
||||
} else {
|
||||
// if we reached the position then stop
|
||||
mRestorePos.y = -1;
|
||||
@ -2631,7 +2632,7 @@ nsXULScrollFrame::LayoutScrollArea(nsBoxLayoutState& aState,
|
||||
const nsPoint& aScrollPosition)
|
||||
{
|
||||
PRUint32 oldflags = aState.LayoutFlags();
|
||||
nsRect childRect = nsRect(mInner.mScrollPort.TopLeft() - aScrollPosition,
|
||||
nsRect childRect = nsRect(nsPoint(0, 0),
|
||||
mInner.mScrollPort.Size());
|
||||
PRInt32 flags = NS_FRAME_NO_MOVE_VIEW;
|
||||
|
||||
@ -2664,6 +2665,26 @@ nsXULScrollFrame::LayoutScrollArea(nsBoxLayoutState& aState,
|
||||
mInner.mScrolledFrame->SetBounds(aState, childRect, PR_TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
* After layout, restore the original position of the frame relative to the
|
||||
* scroll port.
|
||||
*
|
||||
* In the LTR case, restore the original physical position (top left).
|
||||
*
|
||||
* In the RTL case, restore the original logical position (top right), then
|
||||
* subtract the current width to find the physical position.
|
||||
* This can break the invariant that the scroll position is a multiple of
|
||||
* device pixels, so round off the result to the nearest device pixel.
|
||||
*/
|
||||
if (mInner.IsLTR())
|
||||
childRect.x = mInner.mScrollPort.x - aScrollPosition.x;
|
||||
else {
|
||||
childRect.x = PresContext()->RoundAppUnitsToNearestDevPixels(
|
||||
mInner.mScrollPort.XMost() - aScrollPosition.x - childRect.width);
|
||||
}
|
||||
childRect.y = mInner.mScrollPort.y - aScrollPosition.y;
|
||||
mInner.mScrolledFrame->SetBounds(aState, childRect);
|
||||
|
||||
nsRect finalRect = mInner.mScrolledFrame->GetRect();
|
||||
nsRect finalVisOverflow = mInner.mScrolledFrame->GetVisualOverflowRect();
|
||||
// The position of the scrolled frame shouldn't change, but if it does or
|
||||
@ -2784,7 +2805,7 @@ nsXULScrollFrame::Layout(nsBoxLayoutState& aState)
|
||||
GetClientRect(clientRect);
|
||||
|
||||
nsRect oldScrollAreaBounds = mInner.mScrollPort;
|
||||
nsPoint oldScrollPosition = mInner.GetScrollPosition();
|
||||
nsPoint oldScrollPosition = mInner.GetLogicalScrollPosition();
|
||||
|
||||
// the scroll area size starts off as big as our content area
|
||||
mInner.mScrollPort = clientRect;
|
||||
@ -2838,10 +2859,9 @@ nsXULScrollFrame::Layout(nsBoxLayoutState& aState)
|
||||
if (styles.mVertical != NS_STYLE_OVERFLOW_SCROLL) {
|
||||
// These are only good until the call to LayoutScrollArea.
|
||||
nsRect scrolledRect = mInner.GetScrolledRect();
|
||||
nsSize scrolledContentSize(scrolledRect.XMost(), scrolledRect.YMost());
|
||||
|
||||
// There are two cases to consider
|
||||
if (scrolledContentSize.height <= mInner.mScrollPort.height
|
||||
if (scrolledRect.height <= mInner.mScrollPort.height
|
||||
|| styles.mVertical != NS_STYLE_OVERFLOW_AUTO) {
|
||||
if (mInner.mHasVerticalScrollbar) {
|
||||
// We left room for the vertical scrollbar, but it's not needed;
|
||||
@ -2872,11 +2892,10 @@ nsXULScrollFrame::Layout(nsBoxLayoutState& aState)
|
||||
{
|
||||
// These are only good until the call to LayoutScrollArea.
|
||||
nsRect scrolledRect = mInner.GetScrolledRect();
|
||||
nsSize scrolledContentSize(scrolledRect.XMost(), scrolledRect.YMost());
|
||||
|
||||
// if the child is wider that the scroll area
|
||||
// and we don't have a scrollbar add one.
|
||||
if (scrolledContentSize.width > mInner.mScrollPort.width
|
||||
if ((scrolledRect.width > mInner.mScrollPort.width)
|
||||
&& styles.mHorizontal == NS_STYLE_OVERFLOW_AUTO) {
|
||||
|
||||
if (!mInner.mHasHorizontalScrollbar) {
|
||||
@ -2888,7 +2907,7 @@ nsXULScrollFrame::Layout(nsBoxLayoutState& aState)
|
||||
// there is a chance that by adding the horizontal scrollbar we will
|
||||
// suddenly need a vertical scrollbar. Is a special case but its
|
||||
// important.
|
||||
//if (!mHasVerticalScrollbar && scrolledContentSize.height > scrollAreaRect.height - sbSize.height)
|
||||
//if (!mHasVerticalScrollbar && scrolledRect.height > scrollAreaRect.height - sbSize.height)
|
||||
// printf("****Gfx Scrollbar Special case hit!!*****\n");
|
||||
|
||||
}
|
||||
@ -3371,7 +3390,7 @@ nsGfxScrollFrameInner::GetScrolledRectInternal(const nsRect& aScrolledFrameOverf
|
||||
y2 = aScrolledFrameOverflowArea.YMost();
|
||||
if (y1 < 0)
|
||||
y1 = 0;
|
||||
if (IsLTR() || mIsXUL) {
|
||||
if (IsLTR()) {
|
||||
if (x1 < 0)
|
||||
x1 = 0;
|
||||
} else {
|
||||
@ -3452,10 +3471,6 @@ nsGfxScrollFrameInner::SaveState(nsIStatefulFrame::SpecialStateID aStateID)
|
||||
}
|
||||
|
||||
nsPoint scrollPos = GetScrollPosition();
|
||||
// Don't save scroll position if we are at (0,0)
|
||||
if (scrollPos == nsPoint(0,0)) {
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsPresState* state = new nsPresState();
|
||||
if (!state) {
|
||||
@ -3474,7 +3489,7 @@ nsGfxScrollFrameInner::RestoreState(nsPresState* aState)
|
||||
mLastPos.x = -1;
|
||||
mLastPos.y = -1;
|
||||
mDidHistoryRestore = PR_TRUE;
|
||||
mLastPos = mScrolledFrame ? GetScrollPosition() : nsPoint(0,0);
|
||||
mLastPos = mScrolledFrame ? GetLogicalScrollPosition() : nsPoint(0,0);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -70,8 +70,7 @@ class nsGfxScrollFrameInner : public nsIReflowCallback {
|
||||
public:
|
||||
class AsyncScroll;
|
||||
|
||||
nsGfxScrollFrameInner(nsContainerFrame* aOuter, PRBool aIsRoot,
|
||||
PRBool aIsXUL);
|
||||
nsGfxScrollFrameInner(nsContainerFrame* aOuter, PRBool aIsRoot);
|
||||
~nsGfxScrollFrameInner();
|
||||
|
||||
typedef nsIScrollableFrame::ScrollbarStyles ScrollbarStyles;
|
||||
@ -154,6 +153,21 @@ public:
|
||||
nsPoint GetScrollPosition() const {
|
||||
return mScrollPort.TopLeft() - mScrolledFrame->GetPosition();
|
||||
}
|
||||
/**
|
||||
* For LTR frames, the logical scroll position is the offset of the top left
|
||||
* corner of the frame from the top left corner of the scroll port (same as
|
||||
* GetScrollPosition).
|
||||
* For RTL frames, it is the offset of the top right corner of the frame from
|
||||
* the top right corner of the scroll port
|
||||
*/
|
||||
nsPoint GetLogicalScrollPosition() const {
|
||||
nsPoint pt;
|
||||
pt.x = IsLTR() ?
|
||||
mScrollPort.x - mScrolledFrame->GetPosition().x :
|
||||
mScrollPort.XMost() - mScrolledFrame->GetRect().XMost();
|
||||
pt.y = mScrollPort.y - mScrolledFrame->GetPosition().y;
|
||||
return pt;
|
||||
}
|
||||
nsRect GetScrollRange() const;
|
||||
|
||||
nsPoint ClampAndRestrictToDevPixels(const nsPoint& aPt, nsIntPoint* aPtDevPx) const;
|
||||
@ -278,8 +292,6 @@ public:
|
||||
PRPackedBool mDidHistoryRestore:1;
|
||||
// Is this the scrollframe for the document's viewport?
|
||||
PRPackedBool mIsRoot:1;
|
||||
// Is mOuter an nsXULScrollFrame?
|
||||
PRPackedBool mIsXUL:1;
|
||||
// If true, don't try to layout the scrollbars in Reflow(). This can be
|
||||
// useful if multiple passes are involved, because we don't want to place the
|
||||
// scrollbars at the wrong size.
|
||||
@ -600,7 +612,8 @@ public:
|
||||
|
||||
virtual nsPoint GetPositionOfChildIgnoringScrolling(nsIFrame* aChild)
|
||||
{ nsPoint pt = aChild->GetPosition();
|
||||
if (aChild == mInner.GetScrolledFrame()) pt += GetScrollPosition();
|
||||
if (aChild == mInner.GetScrolledFrame())
|
||||
pt += mInner.GetLogicalScrollPosition();
|
||||
return pt;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user