forked from mirrors/gecko-dev
		
	
		
			
				
	
	
		
			213 lines
		
	
	
	
		
			6.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			213 lines
		
	
	
	
		
			6.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 | |
| /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 | |
| /* This Source Code Form is subject to the terms of the Mozilla Public
 | |
|  * License, v. 2.0. If a copy of the MPL was not distributed with this
 | |
|  * 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 {
 | |
| using dom::SystemParameterKVPair;
 | |
| 
 | |
| static_assert(uint8_t(SystemParameterId::Count) < 32,
 | |
|               "Too many SystemParameterId for "
 | |
|               "WinContentSystemParameters::Detail::validCachedValueBitfield");
 | |
| 
 | |
| struct WinContentSystemParameters::Detail {
 | |
|   OffTheBooksMutex mutex{"WinContentSystemParameters::Detail::mutex"};
 | |
|   // A bitfield indicating which cached ids are valid
 | |
|   uint32_t validCachedValueBitfield{0};
 | |
|   bool cachedIsPerMonitorDPIAware{false};
 | |
|   float cachedSystemDPI{0.0f};
 | |
|   bool cachedFlatMenusEnabled{false};
 | |
| 
 | |
|   // Almost-always true in Windows 7, always true starting in Windows 8
 | |
|   bool cachedIsAppThemed{true};
 | |
| };
 | |
| 
 | |
| // static
 | |
| WinContentSystemParameters* WinContentSystemParameters::GetSingleton() {
 | |
|   static WinContentSystemParameters sInstance{};
 | |
|   return &sInstance;
 | |
| }
 | |
| 
 | |
| WinContentSystemParameters::WinContentSystemParameters()
 | |
|     : mDetail(std::make_unique<Detail>()) {}
 | |
| 
 | |
| WinContentSystemParameters::~WinContentSystemParameters() {}
 | |
| 
 | |
| bool WinContentSystemParameters::IsPerMonitorDPIAware() {
 | |
|   MOZ_ASSERT(XRE_IsContentProcess());
 | |
| 
 | |
|   OffTheBooksMutexAutoLock lock(mDetail->mutex);
 | |
|   MOZ_RELEASE_ASSERT(
 | |
|       IsCachedValueValid(SystemParameterId::IsPerMonitorDPIAware));
 | |
|   return mDetail->cachedIsPerMonitorDPIAware;
 | |
| }
 | |
| 
 | |
| float WinContentSystemParameters::SystemDPI() {
 | |
|   MOZ_ASSERT(XRE_IsContentProcess());
 | |
| 
 | |
|   OffTheBooksMutexAutoLock lock(mDetail->mutex);
 | |
|   MOZ_RELEASE_ASSERT(IsCachedValueValid(SystemParameterId::SystemDPI));
 | |
|   return mDetail->cachedSystemDPI;
 | |
| }
 | |
| 
 | |
| bool WinContentSystemParameters::AreFlatMenusEnabled() {
 | |
|   MOZ_ASSERT(XRE_IsContentProcess());
 | |
| 
 | |
|   OffTheBooksMutexAutoLock lock(mDetail->mutex);
 | |
|   MOZ_RELEASE_ASSERT(IsCachedValueValid(SystemParameterId::FlatMenusEnabled));
 | |
|   return mDetail->cachedFlatMenusEnabled;
 | |
| }
 | |
| 
 | |
| bool WinContentSystemParameters::IsAppThemed() {
 | |
|   MOZ_ASSERT(XRE_IsContentProcess());
 | |
| 
 | |
|   OffTheBooksMutexAutoLock lock(mDetail->mutex);
 | |
|   MOZ_RELEASE_ASSERT(IsCachedValueValid(SystemParameterId::IsAppThemed));
 | |
|   return mDetail->cachedIsAppThemed;
 | |
| }
 | |
| 
 | |
| void WinContentSystemParameters::SetContentValueInternal(
 | |
|     const SystemParameterKVPair& aKVPair) {
 | |
|   MOZ_ASSERT(XRE_IsContentProcess());
 | |
|   MOZ_ASSERT(NS_IsMainThread());
 | |
| 
 | |
|   MOZ_RELEASE_ASSERT(aKVPair.id() < uint8_t(SystemParameterId::Count));
 | |
| 
 | |
|   SetCachedValueValid(SystemParameterId(aKVPair.id()), true);
 | |
| 
 | |
|   mDetail->mutex.AssertCurrentThreadOwns();
 | |
| 
 | |
|   switch (SystemParameterId(aKVPair.id())) {
 | |
|     case SystemParameterId::IsPerMonitorDPIAware:
 | |
|       mDetail->cachedIsPerMonitorDPIAware = aKVPair.value();
 | |
|       return;
 | |
| 
 | |
|     case SystemParameterId::SystemDPI:
 | |
|       mDetail->cachedSystemDPI = aKVPair.value();
 | |
|       return;
 | |
| 
 | |
|     case SystemParameterId::FlatMenusEnabled:
 | |
|       mDetail->cachedFlatMenusEnabled = aKVPair.value();
 | |
|       return;
 | |
| 
 | |
|     case SystemParameterId::IsAppThemed:
 | |
|       mDetail->cachedIsAppThemed = aKVPair.value();
 | |
|       return;
 | |
| 
 | |
|     case SystemParameterId::Count:
 | |
|       MOZ_CRASH("Invalid SystemParameterId");
 | |
|   }
 | |
|   MOZ_CRASH("Unhandled SystemParameterId");
 | |
| }
 | |
| 
 | |
| void WinContentSystemParameters::SetContentValues(
 | |
|     const nsTArray<dom::SystemParameterKVPair>& values) {
 | |
|   MOZ_ASSERT(XRE_IsContentProcess());
 | |
|   MOZ_ASSERT(NS_IsMainThread());
 | |
| 
 | |
|   OffTheBooksMutexAutoLock lock(mDetail->mutex);
 | |
|   for (auto& kvPair : values) {
 | |
|     SetContentValueInternal(kvPair);
 | |
|   }
 | |
| }
 | |
| 
 | |
| bool WinContentSystemParameters::GetParentValueInternal(
 | |
|     SystemParameterId aId, SystemParameterKVPair* aKVPair) {
 | |
|   MOZ_ASSERT(XRE_IsParentProcess());
 | |
|   MOZ_ASSERT(aKVPair);
 | |
| 
 | |
|   aKVPair->id() = uint8_t(aId);
 | |
| 
 | |
|   switch (aId) {
 | |
|     case SystemParameterId::IsPerMonitorDPIAware:
 | |
|       aKVPair->value() = WinUtils::IsPerMonitorDPIAware();
 | |
|       return true;
 | |
| 
 | |
|     case SystemParameterId::SystemDPI:
 | |
|       aKVPair->value() = WinUtils::SystemDPI();
 | |
|       return true;
 | |
| 
 | |
|     case SystemParameterId::FlatMenusEnabled:
 | |
|       aKVPair->value() = nsUXThemeData::AreFlatMenusEnabled();
 | |
|       return true;
 | |
| 
 | |
|     case SystemParameterId::IsAppThemed:
 | |
|       aKVPair->value() = nsUXThemeData::IsAppThemed();
 | |
|       return true;
 | |
| 
 | |
|     case SystemParameterId::Count:
 | |
|       MOZ_CRASH("Invalid SystemParameterId");
 | |
|   }
 | |
|   MOZ_CRASH("Unhandled SystemParameterId");
 | |
| }
 | |
| 
 | |
| nsTArray<dom::SystemParameterKVPair>
 | |
| WinContentSystemParameters::GetParentValues() {
 | |
|   MOZ_ASSERT(XRE_IsParentProcess());
 | |
| 
 | |
|   nsTArray<dom::SystemParameterKVPair> results;
 | |
|   for (uint8_t i = 0; i < uint8_t(SystemParameterId::Count); ++i) {
 | |
|     dom::SystemParameterKVPair kvPair{};
 | |
|     GetParentValueInternal(SystemParameterId(i), &kvPair);
 | |
|     results.AppendElement(std::move(kvPair));
 | |
|   }
 | |
|   return results;
 | |
| }
 | |
| 
 | |
| void WinContentSystemParameters::OnThemeChanged() {
 | |
|   MOZ_ASSERT(XRE_IsParentProcess());
 | |
| 
 | |
|   nsTArray<dom::SystemParameterKVPair> updates;
 | |
| 
 | |
|   {
 | |
|     dom::SystemParameterKVPair kvPair{};
 | |
|     GetParentValueInternal(SystemParameterId::FlatMenusEnabled, &kvPair);
 | |
|     updates.AppendElement(std::move(kvPair));
 | |
|   }
 | |
| 
 | |
|   {
 | |
|     dom::SystemParameterKVPair kvPair{};
 | |
|     GetParentValueInternal(SystemParameterId::IsAppThemed, &kvPair);
 | |
|     updates.AppendElement(std::move(kvPair));
 | |
|   }
 | |
| 
 | |
|   nsTArray<dom::ContentParent*> 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));
 | |
|   mDetail->mutex.AssertCurrentThreadOwns();
 | |
|   uint32_t mask = uint32_t(1) << uint8_t(aId);
 | |
|   return (mDetail->validCachedValueBitfield & mask) != 0;
 | |
| }
 | |
| 
 | |
| void WinContentSystemParameters::SetCachedValueValid(SystemParameterId aId,
 | |
|                                                      bool aIsValid) {
 | |
|   MOZ_ASSERT(XRE_IsContentProcess());
 | |
|   MOZ_ASSERT(NS_IsMainThread());
 | |
|   MOZ_ASSERT(uint8_t(aId) < uint8_t(SystemParameterId::Count));
 | |
|   mDetail->mutex.AssertCurrentThreadOwns();
 | |
|   uint32_t mask = uint32_t(1) << uint8_t(aId);
 | |
| 
 | |
|   if (aIsValid) {
 | |
|     mDetail->validCachedValueBitfield |= mask;
 | |
|   } else {
 | |
|     mDetail->validCachedValueBitfield &= ~mask;
 | |
|   }
 | |
| }
 | |
| 
 | |
| }  // namespace widget
 | |
| }  // namespace mozilla
 | 
