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"
struct nsRect;
class nsAttrValue;
class nsPresContext;
class nsRenderingContext;
class nsDeviceContext;
@ -128,7 +129,8 @@ public:
{ return eUnknownTransparency; }
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;

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

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

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

@ -249,6 +249,9 @@ nsScrollbarFrame::MoveToNewPosition()
// get the max pos
int32_t maxpos = nsSliderFrame::GetMaxPosition(content);
// save the old curpos
int32_t oldCurpos = curpos;
// increment the given amount
if (mIncrement) {
curpos += mIncrement;
@ -297,7 +300,10 @@ nsScrollbarFrame::MoveToNewPosition()
nsITheme *theme = presContext->GetTheme();
if (theme && theme->ThemeSupportsWidget(presContext, this, disp->mAppearance)) {
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);

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

@ -69,7 +69,8 @@ public:
uint8_t aWidgetType,
mozilla::LayoutDeviceIntSize* aResult, bool* aIsOverridable) override;
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;
bool ThemeSupportsWidget(nsPresContext* aPresContext, nsIFrame* aFrame, uint8_t aWidgetType) override;
bool WidgetIsContainer(uint8_t aWidgetType) override;

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

@ -3588,7 +3588,8 @@ nsNativeThemeCocoa::GetMinimumWidgetSize(nsPresContext* aPresContext,
NS_IMETHODIMP
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.
switch (aWidgetType) {

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

@ -23,6 +23,7 @@
#include "nsIDOMHTMLInputElement.h"
#include "nsRenderingContext.h"
#include "nsGkAtoms.h"
#include "nsAttrValueInlines.h"
#include "mozilla/EventStates.h"
#include "mozilla/Services.h"
@ -176,6 +177,15 @@ nsNativeThemeGTK::GetTabMarginPixels(nsIFrame* aFrame)
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
nsNativeThemeGTK::GetGtkWidgetAndState(uint8_t aWidgetType, nsIFrame* aFrame,
GtkThemeWidgetType& aGtkWidgetType,
@ -308,12 +318,9 @@ nsNativeThemeGTK::GetGtkWidgetAndState(uint8_t aWidgetType, nsIFrame* aFrame,
// the beginning or the end, depending on the button type.
int32_t curpos = CheckIntAttr(aFrame, nsGkAtoms::curpos, 0);
int32_t maxpos = CheckIntAttr(aFrame, nsGkAtoms::maxpos, 100);
if ((curpos == 0 && (aWidgetType == NS_THEME_SCROLLBAR_BUTTON_UP ||
aWidgetType == NS_THEME_SCROLLBAR_BUTTON_LEFT)) ||
(curpos == maxpos &&
(aWidgetType == NS_THEME_SCROLLBAR_BUTTON_DOWN ||
aWidgetType == NS_THEME_SCROLLBAR_BUTTON_RIGHT)))
if (ShouldScrollbarButtonBeDisabled(curpos, maxpos, aWidgetType)) {
aState->disabled = true;
}
// In order to simulate native GTK scrollbar click behavior,
// we set the active attribute on the element to true if it's
@ -1644,7 +1651,8 @@ nsNativeThemeGTK::GetMinimumWidgetSize(nsPresContext* aPresContext,
NS_IMETHODIMP
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.
if (aWidgetType == NS_THEME_TOOLBOX ||
@ -1679,7 +1687,25 @@ nsNativeThemeGTK::WidgetStateChanged(nsIFrame* aFrame, uint8_t aWidgetType,
aWidgetType == NS_THEME_SCROLLBAR_BUTTON_RIGHT) &&
(aAttribute == nsGkAtoms::curpos ||
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;
}

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

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

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

@ -2574,7 +2574,8 @@ nsNativeThemeWin::GetMinimumWidgetSize(nsPresContext* aPresContext, nsIFrame* aF
NS_IMETHODIMP
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.
if (aWidgetType == NS_THEME_TOOLBOX ||

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

@ -56,7 +56,8 @@ public:
virtual Transparency GetWidgetTransparency(nsIFrame* aFrame, uint8_t aWidgetType) override;
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;