Bug 879565 - Add metrofx support for overlay scrollbars. Patch also replaces various static overlay metrics with LookAndFeel values. (Debug osx assertions fixed.) r=mstange

This commit is contained in:
Jim Mathies 2013-07-01 21:42:00 -05:00
parent 9a7dc847c8
commit f49be481e5
7 changed files with 161 additions and 55 deletions

View File

@ -14,16 +14,32 @@
#include "nsAString.h"
#include "nsQueryFrame.h"
#include "nsComponentManagerUtils.h"
#include "mozilla/LookAndFeel.h"
namespace mozilla {
namespace layout {
NS_IMPL_ISUPPORTS1(ScrollbarActivity, nsIDOMEventListener)
void
ScrollbarActivity::QueryLookAndFeelVals()
{
// Fade animation constants
mScrollbarFadeBeginDelay =
LookAndFeel::GetInt(LookAndFeel::eIntID_ScrollbarFadeBeginDelay);
mScrollbarFadeDuration =
LookAndFeel::GetInt(LookAndFeel::eIntID_ScrollbarFadeDuration);
// Controls whether we keep the mouse move listener so we can display the
// scrollbars whenever the user moves the mouse within the scroll area.
mDisplayOnMouseMove =
LookAndFeel::GetInt(LookAndFeel::eIntID_ScrollbarDisplayOnMouseMove);
}
void
ScrollbarActivity::Destroy()
{
StopListeningForEvents();
StopListeningForScrollbarEvents();
StopListeningForScrollAreaEvents();
UnregisterFromRefreshDriver();
CancelFadeBeginTimer();
}
@ -44,12 +60,12 @@ ScrollbarActivity::ActivityStarted()
return;
}
UnregisterFromRefreshDriver();
StartListeningForEvents();
StartListeningForScrollbarEvents();
StartListeningForScrollAreaEvents();
SetIsActive(true);
NS_ASSERTION(mIsActive, "need to be active during activity");
NS_ASSERTION(!mIsFading, "must not be fading during activity");
NS_ASSERTION(!mFadeBeginTimer, "fade begin timer shouldn't be running");
}
void
@ -58,7 +74,6 @@ ScrollbarActivity::ActivityStopped()
NS_ASSERTION(IsActivityOngoing(), "activity stopped while none was going on");
NS_ASSERTION(mIsActive, "need to be active during activity");
NS_ASSERTION(!mIsFading, "must not be fading during ongoing activity");
NS_ASSERTION(!mFadeBeginTimer, "must not be waiting for fade during ongoing activity");
mNestedActivityCounter--;
@ -67,14 +82,13 @@ ScrollbarActivity::ActivityStopped()
NS_ASSERTION(mIsActive, "need to be active right after activity");
NS_ASSERTION(!mIsFading, "must not be fading right after activity");
NS_ASSERTION(mFadeBeginTimer, "fade begin timer should be running");
}
}
NS_IMETHODIMP
ScrollbarActivity::HandleEvent(nsIDOMEvent* aEvent)
{
if (!mIsActive)
if (!mDisplayOnMouseMove && !mIsActive)
return NS_OK;
nsAutoString type;
@ -151,28 +165,66 @@ ScrollbarActivity::HandleEventForScrollbar(const nsAString& aType,
}
void
ScrollbarActivity::StartListeningForEvents()
ScrollbarActivity::StartListeningForScrollbarEvents()
{
if (mListeningForEvents)
if (mListeningForScrollbarEvents)
return;
nsIFrame* scrollArea = do_QueryFrame(mScrollableFrame);
nsCOMPtr<nsIDOMEventTarget> scrollAreaTarget = do_QueryInterface(
scrollArea->GetContent());
mHorizontalScrollbar = do_QueryInterface(GetHorizontalScrollbar());
mVerticalScrollbar = do_QueryInterface(GetVerticalScrollbar());
AddScrollbarEventListeners(mHorizontalScrollbar);
AddScrollbarEventListeners(mVerticalScrollbar);
mListeningForScrollbarEvents = true;
}
void
ScrollbarActivity::StopListeningForScrollbarEvents()
{
if (!mListeningForScrollbarEvents)
return;
RemoveScrollbarEventListeners(mHorizontalScrollbar);
RemoveScrollbarEventListeners(mVerticalScrollbar);
mHorizontalScrollbar = nullptr;
mVerticalScrollbar = nullptr;
mListeningForScrollbarEvents = false;
}
void
ScrollbarActivity::StartListeningForScrollAreaEvents()
{
if (mListeningForScrollAreaEvents)
return;
nsIFrame* scrollArea = do_QueryFrame(mScrollableFrame);
nsCOMPtr<nsIDOMEventTarget> scrollAreaTarget
= do_QueryInterface(scrollArea->GetContent());
if (scrollAreaTarget) {
scrollAreaTarget->AddEventListener(NS_LITERAL_STRING("mousemove"), this,
true);
}
StartListeningForEventsOnScrollbar(mHorizontalScrollbar);
StartListeningForEventsOnScrollbar(mVerticalScrollbar);
mListeningForEvents = true;
mListeningForScrollAreaEvents = true;
}
void
ScrollbarActivity::StartListeningForEventsOnScrollbar(nsIDOMEventTarget* aScrollbar)
ScrollbarActivity::StopListeningForScrollAreaEvents()
{
if (!mListeningForScrollAreaEvents)
return;
nsIFrame* scrollArea = do_QueryFrame(mScrollableFrame);
nsCOMPtr<nsIDOMEventTarget> scrollAreaTarget = do_QueryInterface(scrollArea->GetContent());
if (scrollAreaTarget) {
scrollAreaTarget->RemoveEventListener(NS_LITERAL_STRING("mousemove"), this, true);
}
mListeningForScrollAreaEvents = false;
}
void
ScrollbarActivity::AddScrollbarEventListeners(nsIDOMEventTarget* aScrollbar)
{
if (aScrollbar) {
aScrollbar->AddEventListener(NS_LITERAL_STRING("mousedown"), this, true);
@ -183,27 +235,7 @@ ScrollbarActivity::StartListeningForEventsOnScrollbar(nsIDOMEventTarget* aScroll
}
void
ScrollbarActivity::StopListeningForEvents()
{
if (!mListeningForEvents)
return;
nsIFrame* scrollArea = do_QueryFrame(mScrollableFrame);
nsCOMPtr<nsIDOMEventTarget> scrollAreaTarget = do_QueryInterface(scrollArea->GetContent());
if (scrollAreaTarget) {
scrollAreaTarget->RemoveEventListener(NS_LITERAL_STRING("mousemove"), this, true);
}
StopListeningForEventsOnScrollbar(mHorizontalScrollbar);
StopListeningForEventsOnScrollbar(mVerticalScrollbar);
mHorizontalScrollbar = nullptr;
mVerticalScrollbar = nullptr;
mListeningForEvents = false;
}
void
ScrollbarActivity::StopListeningForEventsOnScrollbar(nsIDOMEventTarget* aScrollbar)
ScrollbarActivity::RemoveScrollbarEventListeners(nsIDOMEventTarget* aScrollbar)
{
if (aScrollbar) {
aScrollbar->RemoveEventListener(NS_LITERAL_STRING("mousedown"), this, true);
@ -242,7 +274,10 @@ ScrollbarActivity::EndFade()
}
SetIsActive(false);
UnregisterFromRefreshDriver();
StopListeningForEvents();
StopListeningForScrollbarEvents();
if (!mDisplayOnMouseMove) {
StopListeningForScrollAreaEvents();
}
NS_ASSERTION(!mIsActive, "should have gone inactive after fade end");
NS_ASSERTION(!mIsFading, "shouldn't be fading anymore");
@ -372,10 +407,11 @@ ScrollbarActivity::SetIsFading(bool aNewFading)
void
ScrollbarActivity::StartFadeBeginTimer()
{
NS_ASSERTION(!mFadeBeginTimer, "timer already alive!");
mFadeBeginTimer = do_CreateInstance("@mozilla.org/timer;1");
if (!mFadeBeginTimer) {
mFadeBeginTimer = do_CreateInstance("@mozilla.org/timer;1");
}
mFadeBeginTimer->InitWithFuncCallback(FadeBeginTimerFired, this,
kScrollbarFadeBeginDelay,
mScrollbarFadeBeginDelay,
nsITimer::TYPE_ONE_SHOT);
}
@ -384,7 +420,6 @@ ScrollbarActivity::CancelFadeBeginTimer()
{
if (mFadeBeginTimer) {
mFadeBeginTimer->Cancel();
mFadeBeginTimer = nullptr;
}
}

View File

@ -63,10 +63,16 @@ public:
, mNestedActivityCounter(0)
, mIsActive(false)
, mIsFading(false)
, mListeningForEvents(false)
, mListeningForScrollbarEvents(false)
, mListeningForScrollAreaEvents(false)
, mHScrollbarHovered(false)
, mVScrollbarHovered(false)
{}
, mDisplayOnMouseMove(false)
, mScrollbarFadeBeginDelay(0)
, mScrollbarFadeDuration(0)
{
QueryLookAndFeelVals();
}
NS_DECL_ISUPPORTS
NS_DECL_NSIDOMEVENTLISTENER
@ -85,14 +91,12 @@ public:
reinterpret_cast<ScrollbarActivity*>(aSelf)->BeginFade();
}
static const uint32_t kScrollbarFadeBeginDelay = 450; // milliseconds
static const uint32_t kScrollbarFadeDuration = 200; // milliseconds
protected:
bool IsActivityOngoing()
{ return mNestedActivityCounter > 0; }
bool IsStillFading(TimeStamp aTime);
void QueryLookAndFeelVals();
void HandleEventForScrollbar(const nsAString& aType,
nsIContent* aTarget,
@ -107,10 +111,14 @@ protected:
void StartFadeBeginTimer();
void CancelFadeBeginTimer();
void StartListeningForEvents();
void StartListeningForEventsOnScrollbar(nsIDOMEventTarget* aScrollbar);
void StopListeningForEvents();
void StopListeningForEventsOnScrollbar(nsIDOMEventTarget* aScrollbar);
void StartListeningForScrollbarEvents();
void StartListeningForScrollAreaEvents();
void StopListeningForScrollbarEvents();
void StopListeningForScrollAreaEvents();
void AddScrollbarEventListeners(nsIDOMEventTarget* aScrollbar);
void RemoveScrollbarEventListeners(nsIDOMEventTarget* aScrollbar);
void RegisterWithRefreshDriver();
void UnregisterFromRefreshDriver();
@ -122,8 +130,8 @@ protected:
nsIContent* GetHorizontalScrollbar() { return GetScrollbarContent(false); }
nsIContent* GetVerticalScrollbar() { return GetScrollbarContent(true); }
static const TimeDuration FadeDuration() {
return TimeDuration::FromMilliseconds(kScrollbarFadeDuration);
const TimeDuration FadeDuration() {
return TimeDuration::FromMilliseconds(mScrollbarFadeDuration);
}
nsIScrollbarOwner* mScrollableFrame;
@ -134,9 +142,15 @@ protected:
int mNestedActivityCounter;
bool mIsActive;
bool mIsFading;
bool mListeningForEvents;
bool mListeningForScrollbarEvents;
bool mListeningForScrollAreaEvents;
bool mHScrollbarHovered;
bool mVScrollbarHovered;
// LookAndFeel values we load on creation
bool mDisplayOnMouseMove;
int mScrollbarFadeBeginDelay;
int mScrollbarFadeDuration;
};
} // namespace layout

View File

@ -23,6 +23,18 @@ scrollbar[orient="vertical"]
-moz-appearance: scrollbartrack-vertical;
}
@media all and (-moz-overlay-scrollbars) {
scrollbar {
position: relative;
z-index: 2147483647;
}
scrollbar:not([active="true"]),
scrollbar[disabled="true"] {
visibility: hidden;
}
}
/* ::::: borders for thumb and buttons ::::: */
thumb,

View File

@ -361,7 +361,7 @@ public:
*/
eIntID_ScrollbarButtonAutoRepeatBehavior,
/**
* Dealy before showing a tooltip.
* Delay before showing a tooltip.
*/
eIntID_TooltipDelay,
/*
@ -375,7 +375,19 @@ public:
* home button. Used on gaia to determine whether a home button
* is shown.
*/
eIntID_PhysicalHomeButton
eIntID_PhysicalHomeButton,
/*
* Controls whether overlay scrollbars display when the user moves
* the mouse in a scrollable frame.
*/
eIntID_ScrollbarDisplayOnMouseMove,
/*
* Overlay scrollbar animation constants.
*/
eIntID_ScrollbarFadeBeginDelay,
eIntID_ScrollbarFadeDuration
};
/**

View File

@ -358,6 +358,15 @@ nsLookAndFeel::GetIntImpl(IntID aID, int32_t &aResult)
case eIntID_AllowOverlayScrollbarsOverlap:
aResult = AllowOverlayScrollbarsOverlap() ? 1 : 0;
break;
case eIntID_ScrollbarDisplayOnMouseMove:
aResult = 0;
break;
case eIntID_ScrollbarFadeBeginDelay:
aResult = 450;
break;
case eIntID_ScrollbarFadeDuration:
aResult = 200;
break;
case eIntID_TreeOpenDelay:
aResult = 1000;
break;

View File

@ -482,6 +482,21 @@ nsLookAndFeel::GetIntImpl(IntID aID, int32_t &aResult)
case eIntID_SwipeAnimationEnabled:
aResult = 0;
break;
case eIntID_UseOverlayScrollbars:
aResult = (XRE_GetWindowsEnvironment() == WindowsEnvironmentType_Metro);
break;
case eIntID_AllowOverlayScrollbarsOverlap:
aResult = 0;
break;
case eIntID_ScrollbarDisplayOnMouseMove:
aResult = 1;
break;
case eIntID_ScrollbarFadeBeginDelay:
aResult = 2500;
break;
case eIntID_ScrollbarFadeDuration:
aResult = 350;
break;
default:
aResult = 0;
res = NS_ERROR_FAILURE;

View File

@ -51,6 +51,15 @@ nsLookAndFeelIntPref nsXPLookAndFeel::sIntPrefs[] =
{ "ui.useOverlayScrollbars",
eIntID_UseOverlayScrollbars,
false, 0 },
{ "ui.scrollbarDisplayOnMouseMove",
eIntID_ScrollbarDisplayOnMouseMove,
false, 0 },
{ "ui.scrollbarFadeBeginDelay",
eIntID_ScrollbarFadeBeginDelay,
false, 0 },
{ "ui.scrollbarFadeDuration",
eIntID_ScrollbarFadeDuration,
false, 0 },
{ "ui.showHideScrollbars",
eIntID_ShowHideScrollbars,
false, 0 },