Bug 1383659 - LookAndFeel::GetInt(LookAndFeel::eIntID_CaretBlinkTime) should cache caret blink rate. r?jimm
WebKit's Speedometer benchmark updates textbox to emulate text input. So it also updates caret position with focus. And, nsCaret always gets current blink time when reseting caret via LookAndFeel.
When profiling speedometer benchmark, GetCaretBlinkTime somestimes show profiling stack. This API gets data from kernel mode, so this isn't faster.
So, we should cache caret blink rate.
And when changing this rate via control panel, WM_SETTINGCHANGE is posted. So we should update this cache via this message.
MozReview-Commit-ID: IEIi25RvR1g
--- a/widget/windows/nsLookAndFeel.cpp
+++ b/widget/windows/nsLookAndFeel.cpp
@@ -60,16 +60,17 @@ static int32_t GetSystemParam(long flag,
return ::SystemParametersInfo(flag, 0, &value, 0) ? value : def;
}
nsLookAndFeel::nsLookAndFeel()
: nsXPLookAndFeel()
, mUseAccessibilityTheme(0)
, mUseDefaultTheme(0)
, mNativeThemeId(eWindowsTheme_Generic)
+ , mCaretBlinkTime(-1)
{
mozilla::Telemetry::Accumulate(mozilla::Telemetry::TOUCH_ENABLED_DEVICE,
WinUtils::IsTouchDeviceSupportPresent());
}
nsLookAndFeel::~nsLookAndFeel()
{
}
@@ -328,17 +329,22 @@ nsLookAndFeel::GetIntImpl(IntID aID, int
{
nsresult res = nsXPLookAndFeel::GetIntImpl(aID, aResult);
if (NS_SUCCEEDED(res))
return res;
res = NS_OK;
switch (aID) {
case eIntID_CaretBlinkTime:
- aResult = (int32_t)::GetCaretBlinkTime();
+ // eIntID_CaretBlinkTime is often called by updating editable text
+ // that has focus. So it should be cached to improve performance.
+ if (mCaretBlinkTime < 0) {
+ mCaretBlinkTime = static_cast<int32_t>(::GetCaretBlinkTime());
+ }
+ aResult = mCaretBlinkTime;
break;
case eIntID_CaretWidth:
aResult = 1;
break;
case eIntID_ShowCaretDuringSelection:
aResult = 0;
break;
case eIntID_SelectTextfieldsOnKeyFocus:
@@ -734,16 +740,17 @@ nsLookAndFeel::GetFontImpl(FontID anID,
nsLookAndFeel::RefreshImpl()
{
nsXPLookAndFeel::RefreshImpl();
for (auto e = mSystemFontCache.begin(), end = mSystemFontCache.end();
e != end; ++e) {
e->mCacheValid = false;
}
+ mCaretBlinkTime = -1;
}
/* virtual */
char16_t
nsLookAndFeel::GetPasswordCharacterImpl()
{
#define UNICODE_BLACK_CIRCLE_CHAR 0x25cf
return UNICODE_BLACK_CIRCLE_CHAR;
--- a/widget/windows/nsLookAndFeel.h
+++ b/widget/windows/nsLookAndFeel.h
@@ -71,16 +71,17 @@ private:
*/
nsresult GetAccentColorText(nscolor& aColor);
// Content process cached values that get shipped over from the browser
// process.
int32_t mUseAccessibilityTheme;
int32_t mUseDefaultTheme; // is the current theme a known default?
int32_t mNativeThemeId; // see LookAndFeel enum 'WindowsTheme'
+ int32_t mCaretBlinkTime;
struct CachedSystemFont {
CachedSystemFont()
: mCacheValid(false)
{}
bool mCacheValid;
bool mHaveFont;
--- a/widget/windows/nsWindow.cpp
+++ b/widget/windows/nsWindow.cpp
@@ -5205,16 +5205,21 @@ nsWindow::ProcessMessage(UINT msg, WPARA
fontEnum->UpdateFontList(&didChange);
ForceFontUpdate();
} //if (NS_SUCCEEDED(rv))
}
break;
case WM_SETTINGCHANGE:
{
+ if (wParam == SPI_SETKEYBOARDDELAY) {
+ // CaretBlinkTime is cached in nsLookAndFeel
+ NotifyThemeChanged();
+ break;
+ }
if (lParam) {
auto lParamString = reinterpret_cast<const wchar_t*>(lParam);
if (!wcscmp(lParamString, L"ImmersiveColorSet")) {
// WM_SYSCOLORCHANGE is not dispatched for accent color changes
OnSysColorChanged();
break;
}
if (IsWin10OrLater() && mWindowType == eWindowType_invisible) {