Bug 869314: Fix missing dropmarkers in non-native styled combobox controls when overlay scrollbars are used. r=roc

This commit is contained in:
Stephen Pohl 2013-05-26 15:05:10 -07:00
Родитель 5f012bbde6
Коммит be93c1016d
6 изменённых файлов: 71 добавлений и 6 удалений

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

@ -157,6 +157,9 @@
#define NS_THEME_SCROLLBAR_THUMB_HORIZONTAL 88 #define NS_THEME_SCROLLBAR_THUMB_HORIZONTAL 88
#define NS_THEME_SCROLLBAR_THUMB_VERTICAL 89 #define NS_THEME_SCROLLBAR_THUMB_VERTICAL 89
// A non-disappearing scrollbar.
#define NS_THEME_SCROLLBAR_NON_DISAPPEARING 90
// A textfield or text area // A textfield or text area
#define NS_THEME_TEXTFIELD 95 #define NS_THEME_TEXTFIELD 95

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

@ -56,6 +56,7 @@
#include "mozilla/Likely.h" #include "mozilla/Likely.h"
#include <algorithm> #include <algorithm>
#include "nsTextNode.h" #include "nsTextNode.h"
#include "mozilla/LookAndFeel.h"
using namespace mozilla; using namespace mozilla;
@ -738,8 +739,8 @@ nsComboboxControlFrame::GetIntrinsicWidth(nsRenderingContext* aRenderingContext,
if (mListControlFrame) { if (mListControlFrame) {
nsIScrollableFrame* scrollable = do_QueryFrame(mListControlFrame); nsIScrollableFrame* scrollable = do_QueryFrame(mListControlFrame);
NS_ASSERTION(scrollable, "List must be a scrollable frame"); NS_ASSERTION(scrollable, "List must be a scrollable frame");
scrollbarWidth = scrollbarWidth = scrollable->GetNondisappearingScrollbarWidth(
scrollable->GetDesiredScrollbarSizes(presContext, aRenderingContext).LeftRight(); presContext, aRenderingContext);
} }
nscoord displayWidth = 0; nscoord displayWidth = 0;
@ -751,11 +752,19 @@ nsComboboxControlFrame::GetIntrinsicWidth(nsRenderingContext* aRenderingContext,
if (mDropdownFrame) { if (mDropdownFrame) {
nscoord dropdownContentWidth; nscoord dropdownContentWidth;
bool isUsingOverlayScrollbars =
LookAndFeel::GetInt(LookAndFeel::eIntID_UseOverlayScrollbars) != 0;
if (aType == nsLayoutUtils::MIN_WIDTH) { if (aType == nsLayoutUtils::MIN_WIDTH) {
dropdownContentWidth = mDropdownFrame->GetMinWidth(aRenderingContext); dropdownContentWidth = mDropdownFrame->GetMinWidth(aRenderingContext);
if (isUsingOverlayScrollbars) {
dropdownContentWidth += scrollbarWidth;
}
} else { } else {
NS_ASSERTION(aType == nsLayoutUtils::PREF_WIDTH, "Unexpected type"); NS_ASSERTION(aType == nsLayoutUtils::PREF_WIDTH, "Unexpected type");
dropdownContentWidth = mDropdownFrame->GetPrefWidth(aRenderingContext); dropdownContentWidth = mDropdownFrame->GetPrefWidth(aRenderingContext);
if (isUsingOverlayScrollbars) {
dropdownContentWidth += scrollbarWidth;
}
} }
dropdownContentWidth = NSCoordSaturatingSubtract(dropdownContentWidth, dropdownContentWidth = NSCoordSaturatingSubtract(dropdownContentWidth,
scrollbarWidth, scrollbarWidth,
@ -850,9 +859,8 @@ nsComboboxControlFrame::Reflow(nsPresContext* aPresContext,
else { else {
nsIScrollableFrame* scrollable = do_QueryFrame(mListControlFrame); nsIScrollableFrame* scrollable = do_QueryFrame(mListControlFrame);
NS_ASSERTION(scrollable, "List must be a scrollable frame"); NS_ASSERTION(scrollable, "List must be a scrollable frame");
buttonWidth = buttonWidth = scrollable->GetNondisappearingScrollbarWidth(
scrollable->GetDesiredScrollbarSizes(PresContext(), PresContext(), aReflowState.rendContext);
aReflowState.rendContext).LeftRight();
if (buttonWidth > aReflowState.ComputedWidth()) { if (buttonWidth > aReflowState.ComputedWidth()) {
buttonWidth = 0; buttonWidth = 0;
} }

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

@ -932,6 +932,40 @@ nsGfxScrollFrameInner::GetDesiredScrollbarSizes(nsBoxLayoutState* aState)
return result; return result;
} }
nscoord
nsGfxScrollFrameInner::GetNondisappearingScrollbarWidth(nsBoxLayoutState* aState)
{
NS_ASSERTION(aState && aState->GetRenderingContext(),
"Must have rendering context in layout state for size "
"computations");
if (LookAndFeel::GetInt(LookAndFeel::eIntID_UseOverlayScrollbars) != 0) {
// We're using overlay scrollbars, so we need to get the width that
// non-disappearing scrollbars would have.
nsITheme* theme = aState->PresContext()->GetTheme();
if (theme &&
theme->ThemeSupportsWidget(aState->PresContext(),
mVScrollbarBox,
NS_THEME_SCROLLBAR_NON_DISAPPEARING)) {
nsIntSize size;
nsRenderingContext* rendContext = aState->GetRenderingContext();
if (rendContext) {
bool canOverride = true;
theme->GetMinimumWidgetSize(rendContext,
mVScrollbarBox,
NS_THEME_SCROLLBAR_NON_DISAPPEARING,
&size,
&canOverride);
if (size.width) {
return aState->PresContext()->DevPixelsToAppUnits(size.width);
}
}
}
}
return GetDesiredScrollbarSizes(aState).LeftRight();
}
nsresult nsresult
nsXULScrollFrame::CreateAnonymousContent(nsTArray<ContentInfo>& aElements) nsXULScrollFrame::CreateAnonymousContent(nsTArray<ContentInfo>& aElements)
{ {

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

@ -235,6 +235,7 @@ public:
} }
nsMargin GetActualScrollbarSizes() const; nsMargin GetActualScrollbarSizes() const;
nsMargin GetDesiredScrollbarSizes(nsBoxLayoutState* aState); nsMargin GetDesiredScrollbarSizes(nsBoxLayoutState* aState);
nscoord GetNondisappearingScrollbarWidth(nsBoxLayoutState* aState);
bool IsLTR() const; bool IsLTR() const;
bool IsScrollbarOnRight() const; bool IsScrollbarOnRight() const;
bool IsScrollingActive() const { return mScrollingActive || ShouldBuildLayer(); } bool IsScrollingActive() const { return mScrollingActive || ShouldBuildLayer(); }
@ -486,6 +487,11 @@ public:
nsBoxLayoutState bls(aPresContext, aRC, 0); nsBoxLayoutState bls(aPresContext, aRC, 0);
return GetDesiredScrollbarSizes(&bls); return GetDesiredScrollbarSizes(&bls);
} }
virtual nscoord GetNondisappearingScrollbarWidth(nsPresContext* aPresContext,
nsRenderingContext* aRC) MOZ_OVERRIDE {
nsBoxLayoutState bls(aPresContext, aRC, 0);
return mInner.GetNondisappearingScrollbarWidth(&bls);
}
virtual nsRect GetScrollPortRect() const MOZ_OVERRIDE { virtual nsRect GetScrollPortRect() const MOZ_OVERRIDE {
return mInner.GetScrollPortRect(); return mInner.GetScrollPortRect();
} }
@ -744,6 +750,11 @@ public:
nsBoxLayoutState bls(aPresContext, aRC, 0); nsBoxLayoutState bls(aPresContext, aRC, 0);
return GetDesiredScrollbarSizes(&bls); return GetDesiredScrollbarSizes(&bls);
} }
virtual nscoord GetNondisappearingScrollbarWidth(nsPresContext* aPresContext,
nsRenderingContext* aRC) MOZ_OVERRIDE {
nsBoxLayoutState bls(aPresContext, aRC, 0);
return mInner.GetNondisappearingScrollbarWidth(&bls);
}
virtual nsRect GetScrollPortRect() const MOZ_OVERRIDE { virtual nsRect GetScrollPortRect() const MOZ_OVERRIDE {
return mInner.GetScrollPortRect(); return mInner.GetScrollPortRect();
} }

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

@ -81,7 +81,11 @@ public:
*/ */
virtual nsMargin GetDesiredScrollbarSizes(nsPresContext* aPresContext, virtual nsMargin GetDesiredScrollbarSizes(nsPresContext* aPresContext,
nsRenderingContext* aRC) = 0; nsRenderingContext* aRC) = 0;
/**
* Return the width for non-disappearing scrollbars.
*/
virtual nscoord GetNondisappearingScrollbarWidth(nsPresContext* aPresContext,
nsRenderingContext* aRC) = 0;
/** /**
* Get the area of the scrollport relative to the origin of this frame's * Get the area of the scrollport relative to the origin of this frame's
* border-box. * border-box.

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

@ -2846,7 +2846,11 @@ nsNativeThemeCocoa::GetMinimumWidgetSize(nsRenderingContext* aContext,
aResult->SizeTo(16, 16); aResult->SizeTo(16, 16);
break; break;
} }
// Intentional fallthrough to next case.
}
case NS_THEME_SCROLLBAR_NON_DISAPPEARING:
{
// yeah, i know i'm cheating a little here, but i figure that it // yeah, i know i'm cheating a little here, but i figure that it
// really doesn't matter if the scrollbar is vertical or horizontal // really doesn't matter if the scrollbar is vertical or horizontal
// and the width metric is a really good metric for every piece // and the width metric is a really good metric for every piece
@ -3056,6 +3060,7 @@ nsNativeThemeCocoa::ThemeSupportsWidget(nsPresContext* aPresContext, nsIFrame* a
case NS_THEME_SCROLLBAR_THUMB_VERTICAL: case NS_THEME_SCROLLBAR_THUMB_VERTICAL:
case NS_THEME_SCROLLBAR_TRACK_VERTICAL: case NS_THEME_SCROLLBAR_TRACK_VERTICAL:
case NS_THEME_SCROLLBAR_TRACK_HORIZONTAL: case NS_THEME_SCROLLBAR_TRACK_HORIZONTAL:
case NS_THEME_SCROLLBAR_NON_DISAPPEARING:
case NS_THEME_DROPDOWN: case NS_THEME_DROPDOWN:
case NS_THEME_DROPDOWN_BUTTON: case NS_THEME_DROPDOWN_BUTTON: