Bug 1255214 - Only repaint GTK scrollbar button if its enablement actually changed. r=mstange

MozReview-Commit-ID: ITLeksQzvVM

--HG--
extra : rebase_source : 1a3779ab7154282388c2e57251886863e818b168
This commit is contained in:
Botond Ballo 2016-04-20 19:49:09 -04:00
Родитель 7320608b23
Коммит 25a9b005e6
9 изменённых файлов: 56 добавлений и 16 удалений

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

@ -15,6 +15,7 @@
#include "Units.h" #include "Units.h"
struct nsRect; struct nsRect;
class nsAttrValue;
class nsPresContext; class nsPresContext;
class nsRenderingContext; class nsRenderingContext;
class nsDeviceContext; class nsDeviceContext;
@ -128,7 +129,8 @@ public:
{ return eUnknownTransparency; } { return eUnknownTransparency; }
NS_IMETHOD WidgetStateChanged(nsIFrame* aFrame, uint8_t aWidgetType, NS_IMETHOD WidgetStateChanged(nsIFrame* aFrame, uint8_t aWidgetType,
nsIAtom* aAttribute, bool* aShouldRepaint)=0; nsIAtom* aAttribute, bool* aShouldRepaint,
const nsAttrValue* aOldValue)=0;
NS_IMETHOD ThemeChanged()=0; NS_IMETHOD ThemeChanged()=0;

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

@ -1191,7 +1191,7 @@ RestyleManager::ContentStateChanged(nsIContent* aContent,
if (theme && theme->ThemeSupportsWidget(mPresContext, if (theme && theme->ThemeSupportsWidget(mPresContext,
primaryFrame, app)) { primaryFrame, app)) {
bool repaint = false; bool repaint = false;
theme->WidgetStateChanged(primaryFrame, app, nullptr, &repaint); theme->WidgetStateChanged(primaryFrame, app, nullptr, &repaint, nullptr);
if (repaint) { if (repaint) {
NS_UpdateHint(hint, nsChangeHint_RepaintFrame); NS_UpdateHint(hint, nsChangeHint_RepaintFrame);
} }
@ -1320,7 +1320,8 @@ RestyleManager::AttributeChanged(Element* aElement,
nsITheme *theme = mPresContext->GetTheme(); nsITheme *theme = mPresContext->GetTheme();
if (theme && theme->ThemeSupportsWidget(mPresContext, primaryFrame, disp->mAppearance)) { if (theme && theme->ThemeSupportsWidget(mPresContext, primaryFrame, disp->mAppearance)) {
bool repaint = false; bool repaint = false;
theme->WidgetStateChanged(primaryFrame, disp->mAppearance, aAttribute, &repaint); theme->WidgetStateChanged(primaryFrame, disp->mAppearance, aAttribute,
&repaint, aOldValue);
if (repaint) if (repaint)
NS_UpdateHint(hint, nsChangeHint_RepaintFrame); NS_UpdateHint(hint, nsChangeHint_RepaintFrame);
} }

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

@ -249,6 +249,9 @@ nsScrollbarFrame::MoveToNewPosition()
// get the max pos // get the max pos
int32_t maxpos = nsSliderFrame::GetMaxPosition(content); int32_t maxpos = nsSliderFrame::GetMaxPosition(content);
// save the old curpos
int32_t oldCurpos = curpos;
// increment the given amount // increment the given amount
if (mIncrement) { if (mIncrement) {
curpos += mIncrement; curpos += mIncrement;
@ -297,7 +300,10 @@ nsScrollbarFrame::MoveToNewPosition()
nsITheme *theme = presContext->GetTheme(); nsITheme *theme = presContext->GetTheme();
if (theme && theme->ThemeSupportsWidget(presContext, this, disp->mAppearance)) { if (theme && theme->ThemeSupportsWidget(presContext, this, disp->mAppearance)) {
bool repaint; bool repaint;
theme->WidgetStateChanged(this, disp->mAppearance, nsGkAtoms::curpos, &repaint); nsAttrValue oldValue;
oldValue.SetTo(oldCurpos);
theme->WidgetStateChanged(this, disp->mAppearance, nsGkAtoms::curpos,
&repaint, &oldValue);
} }
} }
content->UnsetAttr(kNameSpaceID_None, nsGkAtoms::smooth, false); content->UnsetAttr(kNameSpaceID_None, nsGkAtoms::smooth, false);

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

@ -69,7 +69,8 @@ public:
uint8_t aWidgetType, uint8_t aWidgetType,
mozilla::LayoutDeviceIntSize* aResult, bool* aIsOverridable) override; mozilla::LayoutDeviceIntSize* aResult, bool* aIsOverridable) override;
NS_IMETHOD WidgetStateChanged(nsIFrame* aFrame, uint8_t aWidgetType, NS_IMETHOD WidgetStateChanged(nsIFrame* aFrame, uint8_t aWidgetType,
nsIAtom* aAttribute, bool* aShouldRepaint) override; nsIAtom* aAttribute, bool* aShouldRepaint,
const nsAttrValue* aOldValue) override;
NS_IMETHOD ThemeChanged() override; NS_IMETHOD ThemeChanged() override;
bool ThemeSupportsWidget(nsPresContext* aPresContext, nsIFrame* aFrame, uint8_t aWidgetType) override; bool ThemeSupportsWidget(nsPresContext* aPresContext, nsIFrame* aFrame, uint8_t aWidgetType) override;
bool WidgetIsContainer(uint8_t aWidgetType) override; bool WidgetIsContainer(uint8_t aWidgetType) override;

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

@ -3588,7 +3588,8 @@ nsNativeThemeCocoa::GetMinimumWidgetSize(nsPresContext* aPresContext,
NS_IMETHODIMP NS_IMETHODIMP
nsNativeThemeCocoa::WidgetStateChanged(nsIFrame* aFrame, uint8_t aWidgetType, nsNativeThemeCocoa::WidgetStateChanged(nsIFrame* aFrame, uint8_t aWidgetType,
nsIAtom* aAttribute, bool* aShouldRepaint) nsIAtom* aAttribute, bool* aShouldRepaint,
const nsAttrValue* aOldValue)
{ {
// Some widget types just never change state. // Some widget types just never change state.
switch (aWidgetType) { switch (aWidgetType) {

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

@ -23,6 +23,7 @@
#include "nsIDOMHTMLInputElement.h" #include "nsIDOMHTMLInputElement.h"
#include "nsRenderingContext.h" #include "nsRenderingContext.h"
#include "nsGkAtoms.h" #include "nsGkAtoms.h"
#include "nsAttrValueInlines.h"
#include "mozilla/EventStates.h" #include "mozilla/EventStates.h"
#include "mozilla/Services.h" #include "mozilla/Services.h"
@ -176,6 +177,15 @@ nsNativeThemeGTK::GetTabMarginPixels(nsIFrame* aFrame)
aFrame->PresContext()->AppUnitsToDevPixels(-margin))); aFrame->PresContext()->AppUnitsToDevPixels(-margin)));
} }
static bool ShouldScrollbarButtonBeDisabled(int32_t aCurpos, int32_t aMaxpos,
uint8_t aWidgetType)
{
return ((aCurpos == 0 && (aWidgetType == NS_THEME_SCROLLBAR_BUTTON_UP ||
aWidgetType == NS_THEME_SCROLLBAR_BUTTON_LEFT))
|| (aCurpos == aMaxpos && (aWidgetType == NS_THEME_SCROLLBAR_BUTTON_DOWN ||
aWidgetType == NS_THEME_SCROLLBAR_BUTTON_RIGHT)));
}
bool bool
nsNativeThemeGTK::GetGtkWidgetAndState(uint8_t aWidgetType, nsIFrame* aFrame, nsNativeThemeGTK::GetGtkWidgetAndState(uint8_t aWidgetType, nsIFrame* aFrame,
GtkThemeWidgetType& aGtkWidgetType, GtkThemeWidgetType& aGtkWidgetType,
@ -308,12 +318,9 @@ nsNativeThemeGTK::GetGtkWidgetAndState(uint8_t aWidgetType, nsIFrame* aFrame,
// the beginning or the end, depending on the button type. // the beginning or the end, depending on the button type.
int32_t curpos = CheckIntAttr(aFrame, nsGkAtoms::curpos, 0); int32_t curpos = CheckIntAttr(aFrame, nsGkAtoms::curpos, 0);
int32_t maxpos = CheckIntAttr(aFrame, nsGkAtoms::maxpos, 100); int32_t maxpos = CheckIntAttr(aFrame, nsGkAtoms::maxpos, 100);
if ((curpos == 0 && (aWidgetType == NS_THEME_SCROLLBAR_BUTTON_UP || if (ShouldScrollbarButtonBeDisabled(curpos, maxpos, aWidgetType)) {
aWidgetType == NS_THEME_SCROLLBAR_BUTTON_LEFT)) ||
(curpos == maxpos &&
(aWidgetType == NS_THEME_SCROLLBAR_BUTTON_DOWN ||
aWidgetType == NS_THEME_SCROLLBAR_BUTTON_RIGHT)))
aState->disabled = true; aState->disabled = true;
}
// In order to simulate native GTK scrollbar click behavior, // In order to simulate native GTK scrollbar click behavior,
// we set the active attribute on the element to true if it's // we set the active attribute on the element to true if it's
@ -1644,7 +1651,8 @@ nsNativeThemeGTK::GetMinimumWidgetSize(nsPresContext* aPresContext,
NS_IMETHODIMP NS_IMETHODIMP
nsNativeThemeGTK::WidgetStateChanged(nsIFrame* aFrame, uint8_t aWidgetType, nsNativeThemeGTK::WidgetStateChanged(nsIFrame* aFrame, uint8_t aWidgetType,
nsIAtom* aAttribute, bool* aShouldRepaint) nsIAtom* aAttribute, bool* aShouldRepaint,
const nsAttrValue* aOldValue)
{ {
// Some widget types just never change state. // Some widget types just never change state.
if (aWidgetType == NS_THEME_TOOLBOX || if (aWidgetType == NS_THEME_TOOLBOX ||
@ -1679,7 +1687,25 @@ nsNativeThemeGTK::WidgetStateChanged(nsIFrame* aFrame, uint8_t aWidgetType,
aWidgetType == NS_THEME_SCROLLBAR_BUTTON_RIGHT) && aWidgetType == NS_THEME_SCROLLBAR_BUTTON_RIGHT) &&
(aAttribute == nsGkAtoms::curpos || (aAttribute == nsGkAtoms::curpos ||
aAttribute == nsGkAtoms::maxpos)) { aAttribute == nsGkAtoms::maxpos)) {
*aShouldRepaint = true; // If 'curpos' has changed and we are passed its old value, we can
// determine whether the button's enablement actually needs to change.
if (aAttribute == nsGkAtoms::curpos && aOldValue) {
int32_t curpos = CheckIntAttr(aFrame, nsGkAtoms::curpos, 0);
int32_t maxpos = CheckIntAttr(aFrame, nsGkAtoms::maxpos, 0);
nsAutoString str;
aOldValue->ToString(str);
nsresult err;
int32_t oldCurpos = str.ToInteger(&err);
if (str.IsEmpty() || NS_FAILED(err)) {
*aShouldRepaint = true;
} else {
bool disabledBefore = ShouldScrollbarButtonBeDisabled(oldCurpos, maxpos, aWidgetType);
bool disabledNow = ShouldScrollbarButtonBeDisabled(curpos, maxpos, aWidgetType);
*aShouldRepaint = (disabledBefore != disabledNow);
}
} else {
*aShouldRepaint = true;
}
return NS_OK; return NS_OK;
} }

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

@ -50,7 +50,8 @@ public:
NS_IMETHOD WidgetStateChanged(nsIFrame* aFrame, uint8_t aWidgetType, NS_IMETHOD WidgetStateChanged(nsIFrame* aFrame, uint8_t aWidgetType,
nsIAtom* aAttribute, nsIAtom* aAttribute,
bool* aShouldRepaint) override; bool* aShouldRepaint,
const nsAttrValue* aOldValue) override;
NS_IMETHOD ThemeChanged() override; NS_IMETHOD ThemeChanged() override;

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

@ -2574,7 +2574,8 @@ nsNativeThemeWin::GetMinimumWidgetSize(nsPresContext* aPresContext, nsIFrame* aF
NS_IMETHODIMP NS_IMETHODIMP
nsNativeThemeWin::WidgetStateChanged(nsIFrame* aFrame, uint8_t aWidgetType, nsNativeThemeWin::WidgetStateChanged(nsIFrame* aFrame, uint8_t aWidgetType,
nsIAtom* aAttribute, bool* aShouldRepaint) nsIAtom* aAttribute, bool* aShouldRepaint,
const nsAttrValue* aOldValue)
{ {
// Some widget types just never change state. // Some widget types just never change state.
if (aWidgetType == NS_THEME_TOOLBOX || if (aWidgetType == NS_THEME_TOOLBOX ||

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

@ -56,7 +56,8 @@ public:
virtual Transparency GetWidgetTransparency(nsIFrame* aFrame, uint8_t aWidgetType) override; virtual Transparency GetWidgetTransparency(nsIFrame* aFrame, uint8_t aWidgetType) override;
NS_IMETHOD WidgetStateChanged(nsIFrame* aFrame, uint8_t aWidgetType, NS_IMETHOD WidgetStateChanged(nsIFrame* aFrame, uint8_t aWidgetType,
nsIAtom* aAttribute, bool* aShouldRepaint) override; nsIAtom* aAttribute, bool* aShouldRepaint,
const nsAttrValue* aOldValue) override;
NS_IMETHOD ThemeChanged() override; NS_IMETHOD ThemeChanged() override;