Bug 461843 - Show indication of where on the page you are when scrolling with Fennec. r=roc a=blocking-fennec

This commit is contained in:
Vivien Nicolas 2010-10-21 14:07:55 +02:00
Родитель 9a20d36be1
Коммит de584bde3d
4 изменённых файлов: 64 добавлений и 25 удалений

Просмотреть файл

@ -76,10 +76,10 @@
#ifdef ACCESSIBILITY
#include "nsIAccessibilityService.h"
#endif
#include "nsDisplayList.h"
#include "nsBidiUtils.h"
#include "nsFrameManager.h"
#include "nsIPrefService.h"
#include "nsILookAndFeel.h"
#include "mozilla/dom/Element.h"
using namespace mozilla::dom;
@ -1319,6 +1319,12 @@ nsGfxScrollFrameInner::nsGfxScrollFrameInner(nsContainerFrame* aOuter,
mUpdateScrollbarAttributes(PR_FALSE),
mScrollingActive(PR_FALSE)
{
// lookup if we're allowed to overlap the content from the look&feel object
PRBool canOverlap;
nsPresContext* presContext = mOuter->PresContext();
presContext->LookAndFeel()->
GetMetric(nsILookAndFeel::eMetric_ScrollbarsCanOverlapContent, canOverlap);
mScrollbarsCanOverlapContent = canOverlap;
}
nsGfxScrollFrameInner::~nsGfxScrollFrameInner()
@ -1707,6 +1713,34 @@ AppendToTop(nsDisplayListBuilder* aBuilder, nsDisplayList* aDest,
}
}
nsresult
nsGfxScrollFrameInner::AppendScrollPartsTo(nsDisplayListBuilder* aBuilder,
const nsRect& aDirtyRect,
const nsDisplayListSet& aLists,
const nsDisplayListCollection& aDest,
PRBool& aCreateLayer)
{
nsresult rv = NS_OK;
PRBool hasResizer = HasResizer();
for (nsIFrame* kid = mOuter->GetFirstChild(nsnull); kid; kid = kid->GetNextSibling()) {
if (kid != mScrolledFrame) {
if (kid == mScrollCornerBox && hasResizer) {
// skip the resizer as this will be drawn later on top of the scrolled content
continue;
}
rv = mOuter->BuildDisplayListForChild(aBuilder, kid, aDirtyRect, aDest,
nsIFrame::DISPLAY_CHILD_FORCE_STACKING_CONTEXT);
NS_ENSURE_SUCCESS(rv, rv);
// DISPLAY_CHILD_FORCE_STACKING_CONTEXT put everything into the
// PositionedDescendants list.
::AppendToTop(aBuilder, aLists.BorderBackground(),
aDest.PositionedDescendants(), kid,
aCreateLayer);
}
}
return rv;
}
nsresult
nsGfxScrollFrameInner::BuildDisplayList(nsDisplayListBuilder* aBuilder,
const nsRect& aDirtyRect,
@ -1727,12 +1761,6 @@ nsGfxScrollFrameInner::BuildDisplayList(nsDisplayListBuilder* aBuilder,
aDirtyRect, aLists);
}
// Now display the scrollbars and scrollcorner. These parts are drawn
// in the border-background layer, on top of our own background and
// borders and underneath borders and backgrounds of later elements
// in the tree.
PRBool hasResizer = HasResizer();
nsDisplayListCollection scrollParts;
// We put scrollbars in their own layers when this is the root scroll
// frame and we are a toplevel content document. In this situation, the
// scrollbar(s) would normally be assigned their own layer anyway, since
@ -1743,23 +1771,16 @@ nsGfxScrollFrameInner::BuildDisplayList(nsDisplayListBuilder* aBuilder,
// scrollbar works around the problem.
PRBool createLayersForScrollbars = mIsRoot &&
mOuter->PresContext()->IsRootContentDocument();
for (nsIFrame* kid = mOuter->GetFirstChild(nsnull); kid; kid = kid->GetNextSibling()) {
if (kid != mScrolledFrame) {
if (kid == mScrollCornerBox && hasResizer) {
// skip the resizer as this will be drawn later on top of the scrolled content
continue;
}
rv = mOuter->BuildDisplayListForChild(aBuilder, kid, aDirtyRect, scrollParts,
nsIFrame::DISPLAY_CHILD_FORCE_STACKING_CONTEXT);
NS_ENSURE_SUCCESS(rv, rv);
// DISPLAY_CHILD_FORCE_STACKING_CONTEXT put everything into the
// PositionedDescendants list.
::AppendToTop(aBuilder, aLists.BorderBackground(),
scrollParts.PositionedDescendants(), kid,
createLayersForScrollbars);
}
}
nsDisplayListCollection scrollParts;
if (!mScrollbarsCanOverlapContent) {
// Now display the scrollbars and scrollcorner. These parts are drawn
// in the border-background layer, on top of our own background and
// borders and underneath borders and backgrounds of later elements
// in the tree.
AppendScrollPartsTo(aBuilder, aDirtyRect, aLists,
scrollParts, createLayersForScrollbars);
}
// Overflow clipping can never clip frames outside our subtree, so there
// is no need to worry about whether we are a moving frame that might clip
@ -1771,7 +1792,7 @@ nsGfxScrollFrameInner::BuildDisplayList(nsDisplayListBuilder* aBuilder,
// MarkOutOfFlowChildrenForDisplayList, so it's safe to restrict our
// dirty rect here.
dirtyRect.IntersectRect(aDirtyRect, mScrollPort);
nsDisplayListCollection set;
rv = mOuter->BuildDisplayListForChild(aBuilder, mScrolledFrame, dirtyRect, set);
NS_ENSURE_SUCCESS(rv, rv);
@ -1789,11 +1810,16 @@ nsGfxScrollFrameInner::BuildDisplayList(nsDisplayListBuilder* aBuilder,
PR_TRUE, mIsRoot);
NS_ENSURE_SUCCESS(rv, rv);
if (mScrollbarsCanOverlapContent) {
AppendScrollPartsTo(aBuilder, aDirtyRect, aLists,
scrollParts, createLayersForScrollbars);
}
// Place the resizer in the display list in our Content() list above
// scrolled content in the Content() list.
// This ensures that the resizer appears above the content and the mouse can
// still target the resizer even when scrollbars are hidden.
if (hasResizer && mScrollCornerBox) {
if (HasResizer() && mScrollCornerBox) {
rv = mOuter->BuildDisplayListForChild(aBuilder, mScrollCornerBox, aDirtyRect, scrollParts,
nsIFrame::DISPLAY_CHILD_FORCE_STACKING_CONTEXT);
NS_ENSURE_SUCCESS(rv, rv);

Просмотреть файл

@ -43,6 +43,7 @@
#include "nsHTMLContainerFrame.h"
#include "nsIAnonymousContentCreator.h"
#include "nsBoxFrame.h"
#include "nsDisplayList.h"
#include "nsIScrollableFrame.h"
#include "nsIScrollPositionListener.h"
#include "nsIStatefulFrame.h"
@ -91,6 +92,12 @@ public:
const nsRect& aDirtyRect,
const nsDisplayListSet& aLists);
nsresult AppendScrollPartsTo(nsDisplayListBuilder* aBuilder,
const nsRect& aDirtyRect,
const nsDisplayListSet& aLists,
const nsDisplayListCollection& aDest,
PRBool& aCreateLayer);
PRBool GetBorderRadii(nscoord aRadii[8]) const;
// nsIReflowCallback
@ -295,6 +302,9 @@ public:
// If true, we should be prepared to scroll using this scrollframe
// by placing descendant content into its own layer(s)
PRPackedBool mScrollingActive:1;
// If true, scrollbars are stacked on the top of the display list and can
// float above the content as a result
PRPackedBool mScrollbarsCanOverlapContent:1;
};
/**

Просмотреть файл

@ -184,6 +184,7 @@ public:
eMetric_SelectTextfieldsOnKeyFocus, // select textfields when focused via tab/accesskey?
eMetric_SubmenuDelay, // delay before submenus open
eMetric_MenusCanOverlapOSBar, // can popups overlap menu/task bar?
eMetric_ScrollbarsCanOverlapContent, // can scrollbars float above content?
eMetric_SkipNavigatingDisabledMenuItem, // skip navigating to disabled menu item?
eMetric_DragThresholdX, // begin a drag if the mouse is moved further than the threshold while the button is down
eMetric_DragThresholdY,

Просмотреть файл

@ -64,6 +64,8 @@ nsLookAndFeelIntPref nsXPLookAndFeel::sIntPrefs[] =
{ "ui.dragThresholdX", eMetric_DragThresholdX, PR_FALSE, nsLookAndFeelTypeInt, 0 },
{ "ui.dragThresholdY", eMetric_DragThresholdY, PR_FALSE, nsLookAndFeelTypeInt, 0 },
{ "ui.useAccessibilityTheme", eMetric_UseAccessibilityTheme, PR_FALSE, nsLookAndFeelTypeInt, 0 },
{ "ui.scrollbarsCanOverlapContent", eMetric_ScrollbarsCanOverlapContent,
PR_FALSE, nsLookAndFeelTypeInt, 0 },
{ "ui.menusCanOverlapOSBar", eMetric_MenusCanOverlapOSBar,
PR_FALSE, nsLookAndFeelTypeInt, 0 },
{ "ui.skipNavigatingDisabledMenuItem", eMetric_SkipNavigatingDisabledMenuItem, PR_FALSE, nsLookAndFeelTypeInt, 0 },