Skip to content

Commit

Permalink
Bug 879565 - Add metrofx support for overlay scrollbars. Patch also r…
Browse files Browse the repository at this point in the history
…eplaces various static overlay metrics with LookAndFeel values. (Debug osx assertions fixed.) r=mstange
  • Loading branch information
jmathies committed Jul 2, 2013
1 parent 4ecaa27 commit 3376430
Show file tree
Hide file tree
Showing 7 changed files with 158 additions and 52 deletions.
111 changes: 73 additions & 38 deletions layout/generic/ScrollbarActivity.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
Expand All @@ -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
Expand All @@ -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--;

Expand All @@ -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;
Expand Down Expand Up @@ -151,59 +165,77 @@ 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());

if (scrollAreaTarget) {
scrollAreaTarget->AddEventListener(NS_LITERAL_STRING("mousemove"), this,
true);
}
StartListeningForEventsOnScrollbar(mHorizontalScrollbar);
StartListeningForEventsOnScrollbar(mVerticalScrollbar);
mListeningForEvents = true;
AddScrollbarEventListeners(mHorizontalScrollbar);
AddScrollbarEventListeners(mVerticalScrollbar);

mListeningForScrollbarEvents = true;
}

void
ScrollbarActivity::StartListeningForEventsOnScrollbar(nsIDOMEventTarget* aScrollbar)
ScrollbarActivity::StopListeningForScrollbarEvents()
{
if (aScrollbar) {
aScrollbar->AddEventListener(NS_LITERAL_STRING("mousedown"), this, true);
aScrollbar->AddEventListener(NS_LITERAL_STRING("mouseup"), this, true);
aScrollbar->AddEventListener(NS_LITERAL_STRING("mouseover"), this, true);
aScrollbar->AddEventListener(NS_LITERAL_STRING("mouseout"), this, true);
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);
}
mListeningForScrollAreaEvents = true;
}

void
ScrollbarActivity::StopListeningForEvents()
ScrollbarActivity::StopListeningForScrollAreaEvents()
{
if (!mListeningForEvents)
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);
}
StopListeningForEventsOnScrollbar(mHorizontalScrollbar);
StopListeningForEventsOnScrollbar(mVerticalScrollbar);
mListeningForScrollAreaEvents = false;
}

mHorizontalScrollbar = nullptr;
mVerticalScrollbar = nullptr;
mListeningForEvents = false;
void
ScrollbarActivity::AddScrollbarEventListeners(nsIDOMEventTarget* aScrollbar)
{
if (aScrollbar) {
aScrollbar->AddEventListener(NS_LITERAL_STRING("mousedown"), this, true);
aScrollbar->AddEventListener(NS_LITERAL_STRING("mouseup"), this, true);
aScrollbar->AddEventListener(NS_LITERAL_STRING("mouseover"), this, true);
aScrollbar->AddEventListener(NS_LITERAL_STRING("mouseout"), this, true);
}
}

void
ScrollbarActivity::StopListeningForEventsOnScrollbar(nsIDOMEventTarget* aScrollbar)
ScrollbarActivity::RemoveScrollbarEventListeners(nsIDOMEventTarget* aScrollbar)
{
if (aScrollbar) {
aScrollbar->RemoveEventListener(NS_LITERAL_STRING("mousedown"), this, true);
Expand Down Expand Up @@ -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");
Expand Down Expand Up @@ -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);
}

Expand All @@ -384,7 +420,6 @@ ScrollbarActivity::CancelFadeBeginTimer()
{
if (mFadeBeginTimer) {
mFadeBeginTimer->Cancel();
mFadeBeginTimer = nullptr;
}
}

Expand Down
38 changes: 26 additions & 12 deletions layout/generic/ScrollbarActivity.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,16 @@ class ScrollbarActivity : public nsIDOMEventListener,
, 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
Expand All @@ -85,14 +91,12 @@ class ScrollbarActivity : public nsIDOMEventListener,
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,
Expand All @@ -107,10 +111,14 @@ class ScrollbarActivity : public nsIDOMEventListener,

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();

Expand All @@ -122,8 +130,8 @@ class ScrollbarActivity : public nsIDOMEventListener,
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;
Expand All @@ -134,9 +142,15 @@ class ScrollbarActivity : public nsIDOMEventListener,
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
Expand Down
12 changes: 12 additions & 0 deletions toolkit/themes/windows/global/xulscrollbars.css
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
16 changes: 14 additions & 2 deletions widget/LookAndFeel.h
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,7 @@ class LookAndFeel
*/
eIntID_ScrollbarButtonAutoRepeatBehavior,
/**
* Dealy before showing a tooltip.
* Delay before showing a tooltip.
*/
eIntID_TooltipDelay,
/*
Expand All @@ -375,7 +375,19 @@ class LookAndFeel
* 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
};

/**
Expand Down
9 changes: 9 additions & 0 deletions widget/cocoa/nsLookAndFeel.mm
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,15 @@ static nscolor GetColorFromNSColor(NSColor* aColor)
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;
Expand Down
15 changes: 15 additions & 0 deletions widget/windows/nsLookAndFeel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
9 changes: 9 additions & 0 deletions widget/xpwidgets/nsXPLookAndFeel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 },
Expand Down

0 comments on commit 3376430

Please sign in to comment.