Bug 1640191 - Simplify system colors change notification. r=jmathies

The current notification enumerates all windows and calls
SysColorChanged on them.

The current implementation of SysColorChanged is not quite sound, as it
really needs most if not all of what ThemeChanged does: SVGs can use
system colors, so we need to also invalidate the image cache for
example.

It's also not clear it deals correctly with propagating system color
changes to other documents.

In some cases we were even firing both theme changes and system color
changes at the same time. Unify this code paths.

Differential Revision: https://phabricator.services.mozilla.com/D76487
This commit is contained in:
Emilio Cobos Álvarez 2020-06-10 15:18:25 +00:00
parent ddb8979c67
commit 416e50d907
6 changed files with 12 additions and 82 deletions

View File

@ -1282,7 +1282,6 @@ class PresShell final : public nsStubDocumentObserver,
// Widget notificiations
void WindowSizeMoveDone();
void SysColorChanged() { mPresContext->SysColorChanged(); }
void ThemeChanged() { mPresContext->ThemeChanged(); }
void BackingScaleFactorChanged() { mPresContext->UIResolutionChangedSync(); }

View File

@ -202,7 +202,6 @@ nsPresContext::nsPresContext(dom::Document* aDocument, nsPresContextType aType)
mIsRootPaginatedDocument(false),
mPrefBidiDirection(false),
mPrefScrollbarSide(0),
mPendingSysColorChanged(false),
mPendingThemeChanged(false),
mPendingUIResolutionChanged(false),
mPrefChangePendingNeedsReflow(false),
@ -1365,51 +1364,21 @@ void nsPresContext::ThemeChangedInternal() {
}
}
RefreshSystemMetrics();
PreferenceSheet::Refresh();
}
void nsPresContext::SysColorChanged() {
if (!mPendingSysColorChanged) {
sLookAndFeelChanged = true;
nsCOMPtr<nsIRunnable> ev =
NewRunnableMethod("nsPresContext::SysColorChangedInternal", this,
&nsPresContext::SysColorChangedInternal);
nsresult rv = Document()->Dispatch(TaskCategory::Other, ev.forget());
if (NS_SUCCEEDED(rv)) {
mPendingSysColorChanged = true;
}
}
}
void nsPresContext::SysColorChangedInternal() {
mPendingSysColorChanged = false;
if (sLookAndFeelChanged) {
// Don't use the cached values for the system colors
LookAndFeel::Refresh();
sLookAndFeelChanged = false;
}
// Invalidate cached '-moz-windows-accent-color-applies' media query:
RefreshSystemMetrics();
// Reset default background and foreground colors for the document since they
// may be using system colors
PreferenceSheet::Refresh();
}
void nsPresContext::RefreshSystemMetrics() {
// This will force the system metrics to be generated the next time they're
// used.
nsMediaFeatures::FreeSystemMetrics();
// Changes to system metrics can change media queries on them.
// Reset default background and foreground colors for the document since they
// may be using system colors.
PreferenceSheet::Refresh();
// Changes to system metrics and other look and feel values can change media
// queries on them.
//
// Changes in theme can change system colors (whose changes are
// properly reflected in computed style data), system fonts (whose
// changes are not), and -moz-appearance (whose changes likewise are
// not), so we need to recascade for the first, and reflow for the rest.
// Changes in theme can change system colors (whose changes are properly
// reflected in computed style data), system fonts (whose changes are not),
// and -moz-appearance (whose changes likewise are not), so we need to
// recascade for the first, and reflow for the rest.
MediaFeatureValuesChangedAllDocuments({
RestyleHint::RecascadeSubtree(),
NS_STYLE_HINT_REFLOW,

View File

@ -807,11 +807,6 @@ class nsPresContext : public nsISupports,
*/
void UIResolutionChangedSync();
/*
* Notify the pres context that a system color has changed
*/
void SysColorChanged();
/** Printing methods below should only be used for Medium() == print **/
void SetPrintSettings(nsIPrintSettings* aPrintSettings);
@ -1071,7 +1066,6 @@ class nsPresContext : public nsISupports,
protected:
friend class nsRunnableMethod<nsPresContext>;
void ThemeChangedInternal();
void SysColorChangedInternal();
void RefreshSystemMetrics();
// update device context's resolution from the widget
@ -1280,7 +1274,6 @@ class nsPresContext : public nsISupports,
unsigned mIsRootPaginatedDocument : 1;
unsigned mPrefBidiDirection : 1;
unsigned mPrefScrollbarSide : 2;
unsigned mPendingSysColorChanged : 1;
unsigned mPendingThemeChanged : 1;
unsigned mPendingUIResolutionChanged : 1;
unsigned mPrefChangePendingNeedsReflow : 1;

View File

@ -1661,15 +1661,6 @@ void nsBaseWidget::NotifySizeMoveDone() {
}
}
void nsBaseWidget::NotifySysColorChanged() {
if (!mWidgetListener) {
return;
}
if (PresShell* presShell = mWidgetListener->GetPresShell()) {
presShell->SysColorChanged();
}
}
void nsBaseWidget::NotifyThemeChanged() {
if (!mWidgetListener) {
return;

View File

@ -346,7 +346,6 @@ class nsBaseWidget : public nsIWidget, public nsSupportsWeakReference {
// Should be called by derived implementations to notify on system color and
// theme changes.
void NotifySysColorChanged();
void NotifyThemeChanged();
void NotifyUIStateChanged(UIStateChangeType aShowFocusRings);

View File

@ -5202,7 +5202,7 @@ bool nsWindow::ProcessMessage(UINT msg, WPARAM& wParam, LPARAM& lParam,
break;
case WM_SYSCOLORCHANGE:
OnSysColorChanged();
NotifyThemeChanged();
break;
case WM_THEMECHANGED: {
@ -5265,14 +5265,7 @@ bool nsWindow::ProcessMessage(UINT msg, WPARAM& wParam, LPARAM& lParam,
if (lParam) {
auto lParamString = reinterpret_cast<const wchar_t*>(lParam);
if (!wcscmp(lParamString, L"ImmersiveColorSet")) {
// This might be the Win10 dark mode setting; only way to tell
// is to actually force a theme change, since we don't get
// WM_THEMECHANGED or WM_SYSCOLORCHANGE when that happens.
if (IsWin10OrLater()) {
NotifyThemeChanged();
}
// WM_SYSCOLORCHANGE is not dispatched for accent color changes
OnSysColorChanged();
NotifyThemeChanged();
break;
}
if (IsWin10OrLater() && mWindowType == eWindowType_invisible) {
@ -7500,20 +7493,6 @@ bool nsWindow::HasBogusPopupsDropShadowOnMultiMonitor() {
return !!sHasBogusPopupsDropShadowOnMultiMonitor;
}
void nsWindow::OnSysColorChanged() {
if (mWindowType == eWindowType_invisible) {
::EnumThreadWindows(GetCurrentThreadId(), nsWindow::BroadcastMsg,
WM_SYSCOLORCHANGE);
} else {
// Note: This is sent for child windows as well as top-level windows.
// The Win32 toolkit normally only sends these events to top-level windows.
// But we cycle through all of the childwindows and send it to them as well
// so all presentations get notified properly.
// See nsWindow::GlobalMsgWindowProc.
NotifySysColorChanged();
}
}
void nsWindow::OnDPIChanged(int32_t x, int32_t y, int32_t width,
int32_t height) {
// Don't try to handle WM_DPICHANGED for popup windows (see bug 1239353);