From c5f74d8b964056c93076bc62c7a7c10dc1984f98 Mon Sep 17 00:00:00 2001 From: Chris Martin Date: Wed, 24 Jun 2020 15:29:58 +0000 Subject: [PATCH] Bug 1400317 - Win32k Lockdown: Remote SPI_GETFLATMENU r=jmathies SPI_GETFLATMENU uses the newly-added WinContentSystemParameters and adds the ability to update theme-related variables when they change. Differential Revision: https://phabricator.services.mozilla.com/D80071 --- dom/ipc/ContentChild.cpp | 10 +++ dom/ipc/ContentChild.h | 3 + dom/ipc/PContent.ipdl | 2 + widget/windows/WinContentSystemParameters.cpp | 63 ++++++++++++------- widget/windows/WinContentSystemParameters.h | 10 ++- widget/windows/nsUXThemeData.cpp | 5 ++ widget/windows/nsWindow.cpp | 4 ++ 7 files changed, 72 insertions(+), 25 deletions(-) diff --git a/dom/ipc/ContentChild.cpp b/dom/ipc/ContentChild.cpp index d69718cff3e4..ae85a9db8084 100644 --- a/dom/ipc/ContentChild.cpp +++ b/dom/ipc/ContentChild.cpp @@ -2307,6 +2307,16 @@ mozilla::ipc::IPCResult ContentChild::RecvThemeChanged( return IPC_OK(); } +mozilla::ipc::IPCResult ContentChild::RecvUpdateSystemParameters( + nsTArray&& aUpdates) { +#ifdef XP_WIN + widget::WinContentSystemParameters::GetSingleton()->SetContentValues( + aUpdates); +#endif + + return IPC_OK(); +} + mozilla::ipc::IPCResult ContentChild::RecvLoadProcessScript( const nsString& aURL) { auto* global = ContentProcessMessageManager::Get(); diff --git a/dom/ipc/ContentChild.h b/dom/ipc/ContentChild.h index 2605dcf7eda3..7d7d4f6e93eb 100644 --- a/dom/ipc/ContentChild.h +++ b/dom/ipc/ContentChild.h @@ -304,6 +304,9 @@ class ContentChild final : public PContentChild, mozilla::ipc::IPCResult RecvNotifyVisited(nsTArray&&); mozilla::ipc::IPCResult RecvThemeChanged(nsTArray&&); + mozilla::ipc::IPCResult RecvUpdateSystemParameters( + nsTArray&& aUpdates); + // auto remove when alertfinished is received. nsresult AddRemoteAlertObserver(const nsString& aData, nsIObserver* aObserver); diff --git a/dom/ipc/PContent.ipdl b/dom/ipc/PContent.ipdl index cf042b86b31b..03faab6ede12 100644 --- a/dom/ipc/PContent.ipdl +++ b/dom/ipc/PContent.ipdl @@ -556,6 +556,8 @@ child: */ async ThemeChanged(LookAndFeelInt[] lookAndFeelIntCache); + async UpdateSystemParameters(SystemParameterKVPair[] aUpdates); + async PreferenceUpdate(Pref pref); async VarUpdate(GfxVarUpdate var); diff --git a/widget/windows/WinContentSystemParameters.cpp b/widget/windows/WinContentSystemParameters.cpp index ebf15241e885..cb1f18c11f63 100644 --- a/widget/windows/WinContentSystemParameters.cpp +++ b/widget/windows/WinContentSystemParameters.cpp @@ -5,8 +5,10 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "WinContentSystemParameters.h" #include "WinUtils.h" +#include "nsUXThemeData.h" #include "mozilla/Mutex.h" #include "mozilla/dom/ContentChild.h" +#include "mozilla/dom/ContentParent.h" namespace mozilla { namespace widget { @@ -22,6 +24,7 @@ struct WinContentSystemParameters::Detail { uint32_t validCachedValueBitfield{0}; bool cachedIsPerMonitorDPIAware{false}; float cachedSystemDPI{0.0f}; + bool cachedFlatMenusEnabled{false}; }; // static @@ -52,6 +55,14 @@ float WinContentSystemParameters::SystemDPI() { return mDetail->cachedSystemDPI; } +bool WinContentSystemParameters::AreFlatMenusEnabled() { + MOZ_ASSERT(XRE_IsContentProcess()); + + OffTheBooksMutexAutoLock lock(mDetail->mutex); + MOZ_RELEASE_ASSERT(IsCachedValueValid(SystemParameterId::FlatMenusEnabled)); + return mDetail->cachedFlatMenusEnabled; +} + void WinContentSystemParameters::SetContentValueInternal( const SystemParameterKVPair& aKVPair) { MOZ_ASSERT(XRE_IsContentProcess()); @@ -72,21 +83,16 @@ void WinContentSystemParameters::SetContentValueInternal( mDetail->cachedSystemDPI = aKVPair.value(); return; + case SystemParameterId::FlatMenusEnabled: + mDetail->cachedFlatMenusEnabled = aKVPair.value(); + return; + case SystemParameterId::Count: MOZ_CRASH("Invalid SystemParameterId"); } MOZ_CRASH("Unhandled SystemParameterId"); } -void WinContentSystemParameters::SetContentValue( - const SystemParameterKVPair& aKVPair) { - MOZ_ASSERT(XRE_IsContentProcess()); - MOZ_ASSERT(NS_IsMainThread()); - - OffTheBooksMutexAutoLock lock(mDetail->mutex); - SetContentValueInternal(aKVPair); -} - void WinContentSystemParameters::SetContentValues( const nsTArray& values) { MOZ_ASSERT(XRE_IsContentProcess()); @@ -99,14 +105,13 @@ void WinContentSystemParameters::SetContentValues( } bool WinContentSystemParameters::GetParentValueInternal( - uint8_t aId, SystemParameterKVPair* aKVPair) { + SystemParameterId aId, SystemParameterKVPair* aKVPair) { MOZ_ASSERT(XRE_IsParentProcess()); - MOZ_ASSERT(aId < uint8_t(SystemParameterId::Count)); MOZ_ASSERT(aKVPair); - aKVPair->id() = aId; + aKVPair->id() = uint8_t(aId); - switch (SystemParameterId(aId)) { + switch (aId) { case SystemParameterId::IsPerMonitorDPIAware: aKVPair->value() = WinUtils::IsPerMonitorDPIAware(); return true; @@ -115,20 +120,16 @@ bool WinContentSystemParameters::GetParentValueInternal( aKVPair->value() = WinUtils::SystemDPI(); return true; + case SystemParameterId::FlatMenusEnabled: + aKVPair->value() = nsUXThemeData::AreFlatMenusEnabled(); + return true; + case SystemParameterId::Count: MOZ_CRASH("Invalid SystemParameterId"); } MOZ_CRASH("Unhandled SystemParameterId"); } -bool WinContentSystemParameters::GetParentValue( - uint8_t aId, dom::SystemParameterKVPair* aKVPair) { - MOZ_ASSERT(XRE_IsParentProcess()); - MOZ_RELEASE_ASSERT(aId < uint8_t(SystemParameterId::Count)); - MOZ_RELEASE_ASSERT(aKVPair); - return GetParentValueInternal(aId, aKVPair); -} - nsTArray WinContentSystemParameters::GetParentValues() { MOZ_ASSERT(XRE_IsParentProcess()); @@ -136,12 +137,30 @@ WinContentSystemParameters::GetParentValues() { nsTArray results; for (uint8_t i = 0; i < uint8_t(SystemParameterId::Count); ++i) { dom::SystemParameterKVPair kvPair{}; - GetParentValueInternal(i, &kvPair); + GetParentValueInternal(SystemParameterId(i), &kvPair); results.AppendElement(std::move(kvPair)); } return results; } +void WinContentSystemParameters::OnThemeChanged() { + MOZ_ASSERT(XRE_IsParentProcess()); + + nsTArray updates; + + { + dom::SystemParameterKVPair kvPair{}; + GetParentValueInternal(SystemParameterId::FlatMenusEnabled, &kvPair); + updates.AppendElement(std::move(kvPair)); + } + + nsTArray contentProcesses{}; + dom::ContentParent::GetAll(contentProcesses); + for (auto contentProcess : contentProcesses) { + Unused << contentProcess->SendUpdateSystemParameters(updates); + } +} + bool WinContentSystemParameters::IsCachedValueValid(SystemParameterId aId) { MOZ_ASSERT(XRE_IsContentProcess()); MOZ_ASSERT(uint8_t(aId) < uint8_t(SystemParameterId::Count)); diff --git a/widget/windows/WinContentSystemParameters.h b/widget/windows/WinContentSystemParameters.h index 0e2c1baa237c..3166bb7f7ecb 100644 --- a/widget/windows/WinContentSystemParameters.h +++ b/widget/windows/WinContentSystemParameters.h @@ -21,6 +21,7 @@ namespace widget { enum class SystemParameterId : uint8_t { IsPerMonitorDPIAware = 0, SystemDPI, + FlatMenusEnabled, Count, }; @@ -32,12 +33,14 @@ class WinContentSystemParameters { float SystemDPI(); - void SetContentValue(const dom::SystemParameterKVPair& aKVPair); + bool AreFlatMenusEnabled(); + void SetContentValues(const nsTArray& values); - bool GetParentValue(uint8_t aId, dom::SystemParameterKVPair* aKVPair); nsTArray GetParentValues(); + void OnThemeChanged(); + WinContentSystemParameters(const WinContentSystemParameters&) = delete; WinContentSystemParameters(WinContentSystemParameters&&) = delete; WinContentSystemParameters& operator=(const WinContentSystemParameters&) = @@ -50,7 +53,8 @@ class WinContentSystemParameters { void SetContentValueInternal(const dom::SystemParameterKVPair& aKVPair); - bool GetParentValueInternal(uint8_t aId, dom::SystemParameterKVPair* aKVPair); + bool GetParentValueInternal(SystemParameterId aId, + dom::SystemParameterKVPair* aKVPair); bool IsCachedValueValid(SystemParameterId aId); void SetCachedValueValid(SystemParameterId aId, bool aIsValid); diff --git a/widget/windows/nsUXThemeData.cpp b/widget/windows/nsUXThemeData.cpp index 993494bd7dbe..b36d31501f6c 100644 --- a/widget/windows/nsUXThemeData.cpp +++ b/widget/windows/nsUXThemeData.cpp @@ -12,6 +12,7 @@ #include "nsDebug.h" #include "nsToolkit.h" #include "nsUXThemeConstants.h" +#include "WinContentSystemParameters.h" using namespace mozilla; using namespace mozilla::widget; @@ -391,6 +392,10 @@ void nsUXThemeData::UpdateNativeThemeInfo() { // static bool nsUXThemeData::AreFlatMenusEnabled() { + if (XRE_IsContentProcess()) { + return WinContentSystemParameters::GetSingleton()->AreFlatMenusEnabled(); + } + BOOL useFlat = FALSE; return !!::SystemParametersInfo(SPI_GETFLATMENU, 0, &useFlat, 0) ? useFlat : false; diff --git a/widget/windows/nsWindow.cpp b/widget/windows/nsWindow.cpp index 612a99418057..4760f00d99e4 100644 --- a/widget/windows/nsWindow.cpp +++ b/widget/windows/nsWindow.cpp @@ -126,6 +126,7 @@ #include "SystemTimeConverter.h" #include "WinTaskbar.h" #include "WidgetUtils.h" +#include "WinContentSystemParameters.h" #include "nsIWidgetListener.h" #include "mozilla/dom/MouseEventBinding.h" #include "mozilla/dom/Touch.h" @@ -5206,6 +5207,9 @@ bool nsWindow::ProcessMessage(UINT msg, WPARAM& wParam, LPARAM& lParam, break; case WM_THEMECHANGED: { + // Before anything else, push updates to child processes + WinContentSystemParameters::GetSingleton()->OnThemeChanged(); + // Update non-client margin offsets UpdateNonClientMargins(); nsUXThemeData::UpdateNativeThemeInfo();