зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1470983 - Remote all LookAndFeel values for the Gtk backend. r=spohl,jld
This adds a new LookAndFeel implementation, RemoteLookAndFeel, which can be used in content processes and is supplied with all of its values by the parent process. Co-authored-by: Cameron McCormack <cam@mcc.id.au> Differential Revision: https://phabricator.services.mozilla.com/D97977
This commit is contained in:
Родитель
cb3356b35e
Коммит
907aa1cd3c
|
@ -111,6 +111,7 @@
|
|||
#include "mozilla/net/NeckoChild.h"
|
||||
#include "mozilla/plugins/PluginInstanceParent.h"
|
||||
#include "mozilla/plugins/PluginModuleParent.h"
|
||||
#include "mozilla/widget/RemoteLookAndFeel.h"
|
||||
#include "mozilla/widget/ScreenManager.h"
|
||||
#include "mozilla/widget/WidgetMessageUtils.h"
|
||||
#include "nsBaseDragService.h"
|
||||
|
@ -602,7 +603,7 @@ NS_INTERFACE_MAP_END
|
|||
|
||||
mozilla::ipc::IPCResult ContentChild::RecvSetXPCOMProcessAttributes(
|
||||
XPCOMInitData&& aXPCOMInit, const StructuredCloneData& aInitialData,
|
||||
LookAndFeelCache&& aLookAndFeelCache,
|
||||
LookAndFeelData&& aLookAndFeelData,
|
||||
nsTArray<SystemFontListEntry>&& aFontList,
|
||||
const Maybe<SharedMemoryHandle>& aSharedUASheetHandle,
|
||||
const uintptr_t& aSharedUASheetAddress,
|
||||
|
@ -611,7 +612,7 @@ mozilla::ipc::IPCResult ContentChild::RecvSetXPCOMProcessAttributes(
|
|||
return IPC_OK();
|
||||
}
|
||||
|
||||
mLookAndFeelCache = std::move(aLookAndFeelCache);
|
||||
mLookAndFeelData = std::move(aLookAndFeelData);
|
||||
mFontList = std::move(aFontList);
|
||||
mSharedFontListBlocks = std::move(aSharedFontListBlocks);
|
||||
#ifdef XP_WIN
|
||||
|
@ -2287,8 +2288,17 @@ mozilla::ipc::IPCResult ContentChild::RecvNotifyVisited(
|
|||
}
|
||||
|
||||
mozilla::ipc::IPCResult ContentChild::RecvThemeChanged(
|
||||
LookAndFeelCache&& aLookAndFeelCache, widget::ThemeChangeKind aKind) {
|
||||
LookAndFeel::SetCache(aLookAndFeelCache);
|
||||
LookAndFeelData&& aLookAndFeelData, widget::ThemeChangeKind aKind) {
|
||||
switch (aLookAndFeelData.type()) {
|
||||
case LookAndFeelData::TLookAndFeelCache:
|
||||
LookAndFeel::SetCache(aLookAndFeelData.get_LookAndFeelCache());
|
||||
break;
|
||||
case LookAndFeelData::TFullLookAndFeel:
|
||||
LookAndFeel::SetData(std::move(aLookAndFeelData.get_FullLookAndFeel()));
|
||||
break;
|
||||
default:
|
||||
MOZ_ASSERT(false, "unreachable");
|
||||
}
|
||||
LookAndFeel::NotifyChangedAllWindows(aKind);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
|
|
@ -308,7 +308,8 @@ class ContentChild final : public PContentChild,
|
|||
const bool& haveBidiKeyboards);
|
||||
|
||||
mozilla::ipc::IPCResult RecvNotifyVisited(nsTArray<VisitedQueryResult>&&);
|
||||
mozilla::ipc::IPCResult RecvThemeChanged(LookAndFeelCache&& aLookAndFeelCache,
|
||||
|
||||
mozilla::ipc::IPCResult RecvThemeChanged(LookAndFeelData&& aLookAndFeelData,
|
||||
widget::ThemeChangeKind);
|
||||
|
||||
mozilla::ipc::IPCResult RecvUpdateSystemParameters(
|
||||
|
@ -546,7 +547,7 @@ class ContentChild final : public PContentChild,
|
|||
|
||||
mozilla::ipc::IPCResult RecvSetXPCOMProcessAttributes(
|
||||
XPCOMInitData&& aXPCOMInit, const StructuredCloneData& aInitialData,
|
||||
LookAndFeelCache&& aLookAndFeelCache,
|
||||
LookAndFeelData&& aLookAndFeelData,
|
||||
nsTArray<SystemFontListEntry>&& aFontList,
|
||||
const Maybe<base::SharedMemoryHandle>& aSharedUASheetHandle,
|
||||
const uintptr_t& aSharedUASheetAddress,
|
||||
|
@ -611,7 +612,7 @@ class ContentChild final : public PContentChild,
|
|||
bool DeallocPSessionStorageObserverChild(
|
||||
PSessionStorageObserverChild* aActor);
|
||||
|
||||
LookAndFeelCache& BorrowLookAndFeelCache() { return mLookAndFeelCache; }
|
||||
LookAndFeelData& BorrowLookAndFeelData() { return mLookAndFeelData; }
|
||||
|
||||
/**
|
||||
* Helper function for protocols that use the GPU process when available.
|
||||
|
@ -856,8 +857,8 @@ class ContentChild final : public PContentChild,
|
|||
// parent process and used to initialize gfx in the child. Currently used
|
||||
// only on MacOSX and Linux.
|
||||
nsTArray<mozilla::dom::SystemFontListEntry> mFontList;
|
||||
// Temporary storage for nsXPLookAndFeel cache info.
|
||||
LookAndFeelCache mLookAndFeelCache;
|
||||
// Temporary storage for look and feel data.
|
||||
LookAndFeelData mLookAndFeelData;
|
||||
// Temporary storage for list of shared-fontlist memory blocks.
|
||||
nsTArray<base::SharedMemoryHandle> mSharedFontListBlocks;
|
||||
|
||||
|
|
|
@ -72,6 +72,7 @@
|
|||
#include "mozilla/Sprintf.h"
|
||||
#include "mozilla/StaticPrefs_dom.h"
|
||||
#include "mozilla/StaticPrefs_media.h"
|
||||
#include "mozilla/StaticPrefs_widget.h"
|
||||
#include "mozilla/StyleSheet.h"
|
||||
#include "mozilla/StyleSheetInlines.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
|
@ -158,6 +159,7 @@
|
|||
#include "mozilla/net/PCookieServiceParent.h"
|
||||
#include "mozilla/plugins/PluginBridge.h"
|
||||
#include "mozilla/RemoteLazyInputStreamParent.h"
|
||||
#include "mozilla/widget/RemoteLookAndFeel.h"
|
||||
#include "mozilla/widget/ScreenManager.h"
|
||||
#include "nsAnonymousTemporaryFile.h"
|
||||
#include "nsAppRunner.h"
|
||||
|
@ -1484,6 +1486,21 @@ void ContentParent::BroadcastFontListChanged() {
|
|||
}
|
||||
}
|
||||
|
||||
static LookAndFeelData GetLookAndFeelData() {
|
||||
if (StaticPrefs::widget_remote_look_and_feel_AtStartup()) {
|
||||
return RemoteLookAndFeel::ExtractData();
|
||||
}
|
||||
return LookAndFeel::GetCache();
|
||||
}
|
||||
|
||||
void ContentParent::BroadcastThemeUpdate(widget::ThemeChangeKind aKind) {
|
||||
LookAndFeelData lnfData = GetLookAndFeelData();
|
||||
|
||||
for (auto* cp : AllProcesses(eLive)) {
|
||||
Unused << cp->SendThemeChanged(lnfData, aKind);
|
||||
}
|
||||
}
|
||||
|
||||
const nsACString& ContentParent::GetRemoteType() const { return mRemoteType; }
|
||||
|
||||
void ContentParent::Init() {
|
||||
|
@ -2730,7 +2747,7 @@ bool ContentParent::InitInternal(ProcessPriority aInitialPriority) {
|
|||
nsTArray<SystemFontListEntry> fontList;
|
||||
gfxPlatform::GetPlatform()->ReadSystemFontList(&fontList);
|
||||
|
||||
LookAndFeelCache lnfCache = LookAndFeel::GetCache();
|
||||
LookAndFeelData lnfData = GetLookAndFeelData();
|
||||
|
||||
// If the shared fontlist is in use, collect its shmem block handles to pass
|
||||
// to the child.
|
||||
|
@ -2791,7 +2808,7 @@ bool ContentParent::InitInternal(ProcessPriority aInitialPriority) {
|
|||
}
|
||||
|
||||
Unused << SendSetXPCOMProcessAttributes(
|
||||
xpcomInit, initialData, lnfCache, fontList, sharedUASheetHandle,
|
||||
xpcomInit, initialData, lnfData, fontList, sharedUASheetHandle,
|
||||
sharedUASheetAddress, sharedFontListBlocks);
|
||||
|
||||
ipc::WritableSharedMap* sharedData =
|
||||
|
|
|
@ -255,6 +255,8 @@ class ContentParent final
|
|||
|
||||
static void BroadcastFontListChanged();
|
||||
|
||||
static void BroadcastThemeUpdate(widget::ThemeChangeKind);
|
||||
|
||||
const nsACString& GetRemoteType() const override;
|
||||
|
||||
virtual void DoGetRemoteType(nsACString& aRemoteType,
|
||||
|
|
|
@ -580,7 +580,7 @@ child:
|
|||
* Tell the child that the system theme has changed, and that a repaint is
|
||||
* necessary.
|
||||
*/
|
||||
async ThemeChanged(LookAndFeelCache aCache, ThemeChangeKind aKind);
|
||||
async ThemeChanged(LookAndFeelData lookAndFeelData, ThemeChangeKind aKind);
|
||||
|
||||
async UpdateSystemParameters(SystemParameterKVPair[] aUpdates);
|
||||
|
||||
|
@ -688,7 +688,7 @@ child:
|
|||
|
||||
async SetXPCOMProcessAttributes(XPCOMInitData xpcomInit,
|
||||
StructuredCloneData initialData,
|
||||
LookAndFeelCache lookAndFeelCache,
|
||||
LookAndFeelData lookAndFeeldata,
|
||||
/* used on MacOSX/Linux/Android only: */
|
||||
SystemFontListEntry[] systemFontList,
|
||||
SharedMemoryHandle? sharedUASheetHandle,
|
||||
|
|
|
@ -1398,12 +1398,7 @@ void nsPresContext::ThemeChangedInternal() {
|
|||
image::SurfaceCacheUtils::DiscardAll();
|
||||
|
||||
if (XRE_IsParentProcess()) {
|
||||
nsTArray<ContentParent*> cp;
|
||||
ContentParent::GetAll(cp);
|
||||
widget::LookAndFeelCache lnfCache = LookAndFeel::GetCache();
|
||||
for (ContentParent* c : cp) {
|
||||
Unused << c->SendThemeChanged(lnfCache, kind);
|
||||
}
|
||||
ContentParent::BroadcastThemeUpdate(kind);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9579,9 +9579,9 @@
|
|||
#if defined(XP_LINUX) && defined(MOZ_SANDBOX)
|
||||
# Run content processes in headless mode and disallow connections to
|
||||
# the X server. Experimental; breaks WebGL and Flash, and requires
|
||||
# `widget.disable-native-theme-for-content`. Changing it requires a
|
||||
# restart because sandbox policy information dependent on it is cached.
|
||||
# See bug 1640345 for details.
|
||||
# `widget.disable-native-theme-for-content` and `widget.remote-look-and-feel`.
|
||||
# Changing it requires a restart because sandbox policy information dependent
|
||||
# on it is cached. See bug 1640345 for details.
|
||||
- name: security.sandbox.content.headless
|
||||
type: bool
|
||||
value: false
|
||||
|
@ -10417,6 +10417,19 @@
|
|||
mirror: always
|
||||
#endif
|
||||
|
||||
# Enable the RemoteLookAndFeel in content processes, which will cause all
|
||||
# LookAndFeel values to be queried in the parent process and sent to content
|
||||
# processes using IPC. This is required for widgets to paint and behave
|
||||
# correctly when `security.sandbox.content.headless` is enabled.
|
||||
- name: widget.remote-look-and-feel
|
||||
type: bool
|
||||
#ifdef MOZ_WIDGET_GTK
|
||||
value: true
|
||||
#else
|
||||
value: false
|
||||
#endif
|
||||
mirror: once
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Prefs starting with "xul."
|
||||
#---------------------------------------------------------------------------
|
||||
|
|
|
@ -21,6 +21,7 @@ struct gfxFontStyle;
|
|||
namespace mozilla {
|
||||
|
||||
namespace widget {
|
||||
class FullLookAndFeel;
|
||||
class LookAndFeelCache;
|
||||
} // namespace widget
|
||||
|
||||
|
@ -400,6 +401,9 @@ class LookAndFeel {
|
|||
// The width/height ratio of the cursor. If used, the CaretWidth int metric
|
||||
// should be added to the calculated caret width.
|
||||
CaretAspectRatio,
|
||||
|
||||
// Not an ID; used to define the range of valid IDs. Must be last.
|
||||
End,
|
||||
};
|
||||
|
||||
// These constants must be kept in 1:1 correspondence with the
|
||||
|
@ -555,6 +559,7 @@ class LookAndFeel {
|
|||
*/
|
||||
static widget::LookAndFeelCache GetCache();
|
||||
static void SetCache(const widget::LookAndFeelCache& aCache);
|
||||
static void SetData(widget::FullLookAndFeel&& aTables);
|
||||
static void NotifyChangedAllWindows(widget::ThemeChangeKind);
|
||||
};
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ struct LookAndFeelInt {
|
|||
int32_t value;
|
||||
};
|
||||
|
||||
struct LookAndFeelFont {
|
||||
comparable struct LookAndFeelFont {
|
||||
bool haveFont;
|
||||
nsString name;
|
||||
float size;
|
||||
|
@ -35,5 +35,45 @@ struct LookAndFeelCache {
|
|||
LookAndFeelColor[] mColors;
|
||||
};
|
||||
|
||||
/**
|
||||
* Stores the entirety of a LookAndFeel's data.
|
||||
*
|
||||
* The format allows for some compression compared with having fixed
|
||||
* length arrays for each value type and some indication of whether
|
||||
* a value is present. This is because not all values are present on
|
||||
* a given platform, and because there is also substantial repetition
|
||||
* of specific values.
|
||||
*
|
||||
* Each of ints, floats, colors, and fonts is an array that stores the
|
||||
* unique values that occur in the LookAndFeel. intMap, floatMap,
|
||||
* colorMap, and fontMap map from value IDs (LookAndFeel::IntID, etc.)
|
||||
* to indexes into the value arrays. The map arrays are of fixed
|
||||
* length, determined by the maximum ID value. If a value for a
|
||||
* particular ID is not present, the entry in the map is set to -1.
|
||||
*
|
||||
* (Note that fontMap is different from the others since it maps from a
|
||||
* LookAndFeel::FontID value minus 1, as 1 is the minimum value of that
|
||||
* enum.)
|
||||
*/
|
||||
struct FullLookAndFeel {
|
||||
int32_t[] ints;
|
||||
float[] floats;
|
||||
nscolor[] colors;
|
||||
LookAndFeelFont[] fonts;
|
||||
|
||||
uint8_t[] intMap;
|
||||
uint8_t[] floatMap;
|
||||
uint8_t[] colorMap;
|
||||
uint8_t[] fontMap;
|
||||
|
||||
uint16_t passwordChar;
|
||||
bool passwordEcho;
|
||||
};
|
||||
|
||||
union LookAndFeelData {
|
||||
LookAndFeelCache;
|
||||
FullLookAndFeel;
|
||||
};
|
||||
|
||||
} // namespace widget
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -0,0 +1,195 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: sw=2 ts=8 et :
|
||||
*/
|
||||
/* 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 "RemoteLookAndFeel.h"
|
||||
|
||||
#include "gfxFont.h"
|
||||
#include "MainThreadUtils.h"
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/Result.h"
|
||||
#include "mozilla/ResultExtensions.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
|
||||
#include <limits>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
namespace mozilla::widget {
|
||||
|
||||
RemoteLookAndFeel::RemoteLookAndFeel(FullLookAndFeel&& aTables)
|
||||
: mTables(std::move(aTables)) {
|
||||
MOZ_ASSERT(XRE_IsContentProcess(),
|
||||
"Only content processes should be using a RemoteLookAndFeel");
|
||||
}
|
||||
|
||||
RemoteLookAndFeel::~RemoteLookAndFeel() = default;
|
||||
|
||||
void RemoteLookAndFeel::SetDataImpl(FullLookAndFeel&& aTables) {
|
||||
MOZ_ASSERT(XRE_IsContentProcess(),
|
||||
"Only content processes should be using a RemoteLookAndFeel");
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
mTables = std::move(aTables);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
template <typename Item, typename UInt, typename ID>
|
||||
Result<const Item*, nsresult> MapLookup(const nsTArray<Item>& aItems,
|
||||
const nsTArray<UInt>& aMap, ID aID,
|
||||
ID aMinimum = ID(0)) {
|
||||
UInt mapped = aMap[static_cast<size_t>(aID) - static_cast<size_t>(aMinimum)];
|
||||
|
||||
if (mapped == std::numeric_limits<UInt>::max()) {
|
||||
return Err(NS_ERROR_NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
return &aItems[static_cast<size_t>(mapped)];
|
||||
}
|
||||
|
||||
template <typename Item, typename UInt>
|
||||
void AddToMap(nsTArray<Item>* aItems, nsTArray<UInt>* aMap,
|
||||
Maybe<Item>&& aNewItem) {
|
||||
if (aNewItem.isNothing()) {
|
||||
aMap->AppendElement(std::numeric_limits<UInt>::max());
|
||||
return;
|
||||
}
|
||||
|
||||
size_t newIndex = aItems->Length();
|
||||
MOZ_ASSERT(newIndex < std::numeric_limits<UInt>::max());
|
||||
|
||||
// Check if there is an existing value in aItems that we can point to.
|
||||
//
|
||||
// The arrays should be small enough and contain few enough unique
|
||||
// values that sequential search here is reasonable.
|
||||
for (size_t i = 0; i < newIndex; ++i) {
|
||||
if ((*aItems)[i] == aNewItem.ref()) {
|
||||
aMap->AppendElement(static_cast<UInt>(i));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
aItems->AppendElement(aNewItem.extract());
|
||||
aMap->AppendElement(static_cast<UInt>(newIndex));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
nsresult RemoteLookAndFeel::NativeGetColor(ColorID aID, nscolor& aResult) {
|
||||
const nscolor* result;
|
||||
MOZ_TRY_VAR(result, MapLookup(mTables.colors(), mTables.colorMap(), aID));
|
||||
aResult = *result;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult RemoteLookAndFeel::NativeGetInt(IntID aID, int32_t& aResult) {
|
||||
const int32_t* result;
|
||||
MOZ_TRY_VAR(result, MapLookup(mTables.ints(), mTables.intMap(), aID));
|
||||
aResult = *result;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult RemoteLookAndFeel::NativeGetFloat(FloatID aID, float& aResult) {
|
||||
const float* result;
|
||||
MOZ_TRY_VAR(result, MapLookup(mTables.floats(), mTables.floatMap(), aID));
|
||||
aResult = *result;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool RemoteLookAndFeel::NativeGetFont(FontID aID, nsString& aFontName,
|
||||
gfxFontStyle& aFontStyle) {
|
||||
auto result =
|
||||
MapLookup(mTables.fonts(), mTables.fontMap(), aID, FontID::MINIMUM);
|
||||
if (result.isErr()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const LookAndFeelFont& font = *result.unwrap();
|
||||
MOZ_ASSERT(font.haveFont());
|
||||
aFontName = font.name();
|
||||
aFontStyle = gfxFontStyle();
|
||||
aFontStyle.size = font.size();
|
||||
aFontStyle.weight = FontWeight(font.weight());
|
||||
aFontStyle.style =
|
||||
font.italic() ? FontSlantStyle::Italic() : FontSlantStyle::Normal();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
char16_t RemoteLookAndFeel::GetPasswordCharacterImpl() {
|
||||
return static_cast<char16_t>(mTables.passwordChar());
|
||||
}
|
||||
|
||||
bool RemoteLookAndFeel::GetEchoPasswordImpl() { return mTables.passwordEcho(); }
|
||||
|
||||
// static
|
||||
FullLookAndFeel RemoteLookAndFeel::ExtractData() {
|
||||
MOZ_ASSERT(XRE_IsParentProcess(),
|
||||
"Only parent processes should be extracting LookAndFeel data");
|
||||
FullLookAndFeel lf{};
|
||||
|
||||
nsXPLookAndFeel* impl = nsXPLookAndFeel::GetInstance();
|
||||
|
||||
for (auto id : MakeEnumeratedRange(IntID::End)) {
|
||||
int32_t theInt;
|
||||
nsresult rv = impl->NativeGetInt(id, theInt);
|
||||
AddToMap(&lf.ints(), &lf.intMap(),
|
||||
NS_SUCCEEDED(rv) ? Some(theInt) : Nothing{});
|
||||
}
|
||||
|
||||
for (auto id : MakeEnumeratedRange(FloatID::End)) {
|
||||
float theFloat;
|
||||
nsresult rv = impl->NativeGetFloat(id, theFloat);
|
||||
AddToMap(&lf.floats(), &lf.floatMap(),
|
||||
NS_SUCCEEDED(rv) ? Some(theFloat) : Nothing{});
|
||||
}
|
||||
|
||||
for (auto id : MakeEnumeratedRange(ColorID::End)) {
|
||||
nscolor theColor;
|
||||
nsresult rv = impl->NativeGetColor(id, theColor);
|
||||
AddToMap(&lf.colors(), &lf.colorMap(),
|
||||
NS_SUCCEEDED(rv) ? Some(theColor) : Nothing{});
|
||||
}
|
||||
|
||||
for (auto id :
|
||||
MakeInclusiveEnumeratedRange(FontID::MINIMUM, FontID::MAXIMUM)) {
|
||||
LookAndFeelFont font{};
|
||||
gfxFontStyle fontStyle{};
|
||||
|
||||
bool rv = impl->NativeGetFont(id, font.name(), fontStyle);
|
||||
Maybe<LookAndFeelFont> maybeFont;
|
||||
if (rv) {
|
||||
font.haveFont() = true;
|
||||
font.size() = fontStyle.size;
|
||||
font.weight() = fontStyle.weight.ToFloat();
|
||||
font.italic() = fontStyle.style.IsItalic();
|
||||
MOZ_ASSERT(fontStyle.style.IsNormal() || fontStyle.style.IsItalic(),
|
||||
"Cannot handle oblique font style");
|
||||
#ifdef DEBUG
|
||||
{
|
||||
// Assert that all the remaining font style properties have their
|
||||
// default values.
|
||||
gfxFontStyle candidate = fontStyle;
|
||||
gfxFontStyle defaults{};
|
||||
candidate.size = defaults.size;
|
||||
candidate.weight = defaults.weight;
|
||||
candidate.style = defaults.style;
|
||||
MOZ_ASSERT(candidate.Equals(defaults),
|
||||
"Some font style properties not supported");
|
||||
}
|
||||
#endif
|
||||
maybeFont = Some(std::move(font));
|
||||
}
|
||||
AddToMap(&lf.fonts(), &lf.fontMap(), std::move(maybeFont));
|
||||
}
|
||||
|
||||
lf.passwordChar() = impl->GetPasswordCharacterImpl();
|
||||
lf.passwordEcho() = impl->GetEchoPasswordImpl();
|
||||
|
||||
return lf;
|
||||
}
|
||||
|
||||
} // namespace mozilla::widget
|
|
@ -0,0 +1,53 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: sw=2 ts=8 et :
|
||||
*/
|
||||
/* 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/. */
|
||||
|
||||
#ifndef mozilla_widget_RemoteLookAndFeel_h__
|
||||
#define mozilla_widget_RemoteLookAndFeel_h__
|
||||
|
||||
#include "mozilla/widget/nsXPLookAndFeel.h"
|
||||
#include "mozilla/widget/LookAndFeelTypes.h"
|
||||
|
||||
namespace mozilla::widget {
|
||||
|
||||
/**
|
||||
* A LookAndFeel implementation whose native values are provided by the
|
||||
* parent process.
|
||||
*/
|
||||
class RemoteLookAndFeel final : public nsXPLookAndFeel {
|
||||
public:
|
||||
explicit RemoteLookAndFeel(FullLookAndFeel&& aTables);
|
||||
|
||||
virtual ~RemoteLookAndFeel();
|
||||
|
||||
void NativeInit() override {}
|
||||
|
||||
nsresult NativeGetInt(IntID aID, int32_t& aResult) override;
|
||||
nsresult NativeGetFloat(FloatID aID, float& aResult) override;
|
||||
nsresult NativeGetColor(ColorID aID, nscolor& aResult) override;
|
||||
bool NativeGetFont(FontID aID, nsString& aFontName,
|
||||
gfxFontStyle& aFontStyle) override;
|
||||
|
||||
char16_t GetPasswordCharacterImpl() override;
|
||||
bool GetEchoPasswordImpl() override;
|
||||
|
||||
// Sets the LookAndFeel data to be used by this content process' singleton
|
||||
// RemoteLookAndFeel object.
|
||||
void SetDataImpl(FullLookAndFeel&& aTables) override;
|
||||
|
||||
// Extracts the data from the platform's default LookAndFeel implementation.
|
||||
//
|
||||
// This is called in the parent process to obtain the data to send down to
|
||||
// content processes when they are created (and when the OS theme changes).
|
||||
static FullLookAndFeel ExtractData();
|
||||
|
||||
private:
|
||||
FullLookAndFeel mTables;
|
||||
};
|
||||
|
||||
} // namespace mozilla::widget
|
||||
|
||||
#endif // mozilla_widget_RemoteLookAndFeel_h__
|
|
@ -20,7 +20,11 @@ using mozilla::dom::ContentChild;
|
|||
|
||||
static const char16_t UNICODE_BULLET = 0x2022;
|
||||
|
||||
nsLookAndFeel::nsLookAndFeel() : nsXPLookAndFeel() {}
|
||||
nsLookAndFeel::nsLookAndFeel(const LookAndFeelCache* aCache) {
|
||||
if (aCache) {
|
||||
DoSetCache(*aCache);
|
||||
}
|
||||
}
|
||||
|
||||
nsLookAndFeel::~nsLookAndFeel() {}
|
||||
|
||||
|
@ -505,6 +509,10 @@ widget::LookAndFeelCache nsLookAndFeel::GetCacheImpl() {
|
|||
}
|
||||
|
||||
void nsLookAndFeel::SetCacheImpl(const LookAndFeelCache& aCache) {
|
||||
DoSetCache(aCache);
|
||||
}
|
||||
|
||||
void nsLookAndFeel::DoSetCache(const LookAndFeelCache& aCache) {
|
||||
for (const auto& entry : aCache.mInts()) {
|
||||
switch (entry.id()) {
|
||||
case IntID::PrefersReducedMotion:
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
class nsLookAndFeel final : public nsXPLookAndFeel {
|
||||
public:
|
||||
nsLookAndFeel();
|
||||
explicit nsLookAndFeel(const LookAndFeelCache* aCache);
|
||||
virtual ~nsLookAndFeel();
|
||||
|
||||
void NativeInit() final;
|
||||
|
@ -27,6 +27,8 @@ class nsLookAndFeel final : public nsXPLookAndFeel {
|
|||
void SetCacheImpl(const LookAndFeelCache& aCache) override;
|
||||
|
||||
protected:
|
||||
void DoSetCache(const LookAndFeelCache& aCache);
|
||||
|
||||
bool mInitializedSystemColors = false;
|
||||
mozilla::AndroidSystemColors mSystemColors;
|
||||
bool mInitializedShowPassword = false;
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
class nsLookAndFeel final : public nsXPLookAndFeel {
|
||||
public:
|
||||
nsLookAndFeel();
|
||||
explicit nsLookAndFeel(const LookAndFeelCache* aCache);
|
||||
virtual ~nsLookAndFeel();
|
||||
|
||||
void NativeInit() final;
|
||||
|
@ -31,6 +31,7 @@ class nsLookAndFeel final : public nsXPLookAndFeel {
|
|||
void SetCacheImpl(const LookAndFeelCache& aCache) override;
|
||||
|
||||
protected:
|
||||
void DoSetCache(const LookAndFeelCache& aCache);
|
||||
static bool AllowOverlayScrollbarsOverlap();
|
||||
|
||||
static bool SystemWantsDarkTheme();
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
@property(readonly) BOOL accessibilityDisplayShouldReduceMotion;
|
||||
@end
|
||||
|
||||
nsLookAndFeel::nsLookAndFeel()
|
||||
nsLookAndFeel::nsLookAndFeel(const LookAndFeelCache* aCache)
|
||||
: nsXPLookAndFeel(),
|
||||
mUseOverlayScrollbars(-1),
|
||||
mUseOverlayScrollbarsCached(false),
|
||||
|
@ -69,7 +69,11 @@ nsLookAndFeel::nsLookAndFeel()
|
|||
mColorEvenTreeRow(0),
|
||||
mColorOddTreeRow(0),
|
||||
mColorActiveSourceListSelection(0),
|
||||
mInitialized(false) {}
|
||||
mInitialized(false) {
|
||||
if (aCache) {
|
||||
DoSetCache(*aCache);
|
||||
}
|
||||
}
|
||||
|
||||
nsLookAndFeel::~nsLookAndFeel() {}
|
||||
|
||||
|
@ -671,7 +675,9 @@ mozilla::widget::LookAndFeelCache nsLookAndFeel::GetCacheImpl() {
|
|||
return cache;
|
||||
}
|
||||
|
||||
void nsLookAndFeel::SetCacheImpl(const LookAndFeelCache& aCache) {
|
||||
void nsLookAndFeel::SetCacheImpl(const LookAndFeelCache& aCache) { DoSetCache(aCache); }
|
||||
|
||||
void nsLookAndFeel::DoSetCache(const LookAndFeelCache& aCache) {
|
||||
for (auto entry : aCache.mInts()) {
|
||||
switch (entry.id()) {
|
||||
case IntID::UseOverlayScrollbars:
|
||||
|
|
|
@ -59,7 +59,11 @@ extern mozilla::LazyLogModule gWidgetLog;
|
|||
((nscolor)NS_RGBA((int)((c).red * 255), (int)((c).green * 255), \
|
||||
(int)((c).blue * 255), (int)((c).alpha * 255)))
|
||||
|
||||
nsLookAndFeel::nsLookAndFeel() = default;
|
||||
nsLookAndFeel::nsLookAndFeel(const LookAndFeelCache* aCache) {
|
||||
if (aCache) {
|
||||
DoSetCache(*aCache);
|
||||
}
|
||||
}
|
||||
|
||||
nsLookAndFeel::~nsLookAndFeel() = default;
|
||||
|
||||
|
@ -295,6 +299,10 @@ widget::LookAndFeelCache nsLookAndFeel::GetCacheImpl() {
|
|||
}
|
||||
|
||||
void nsLookAndFeel::SetCacheImpl(const LookAndFeelCache& aCache) {
|
||||
DoSetCache(aCache);
|
||||
}
|
||||
|
||||
void nsLookAndFeel::DoSetCache(const LookAndFeelCache& aCache) {
|
||||
for (const auto& entry : aCache.mInts()) {
|
||||
switch (entry.id()) {
|
||||
case IntID::SystemUsesDarkTheme:
|
||||
|
|
|
@ -18,7 +18,7 @@ struct _GtkStyle;
|
|||
|
||||
class nsLookAndFeel final : public nsXPLookAndFeel {
|
||||
public:
|
||||
nsLookAndFeel();
|
||||
explicit nsLookAndFeel(const LookAndFeelCache* aCache);
|
||||
virtual ~nsLookAndFeel();
|
||||
|
||||
void NativeInit() final;
|
||||
|
@ -41,6 +41,7 @@ class nsLookAndFeel final : public nsXPLookAndFeel {
|
|||
static const nscolor kWhite = NS_RGB(255, 255, 255);
|
||||
|
||||
protected:
|
||||
void DoSetCache(const LookAndFeelCache& aCache);
|
||||
bool WidgetUsesImage(WidgetNodeType aNodeType);
|
||||
void RecordLookAndFeelSpecificTelemetry() override;
|
||||
bool ShouldHonorThemeScrollbarColors();
|
||||
|
|
|
@ -4744,6 +4744,21 @@ nsresult nsWindow::Create(nsIWidget* aParent, nsNativeWidget aNativeParent,
|
|||
G_CALLBACK(settings_changed_cb), this);
|
||||
g_signal_connect_after(default_settings, "notify::gtk-xft-dpi",
|
||||
G_CALLBACK(settings_xft_dpi_changed_cb), this);
|
||||
// For remote LookAndFeel, to refresh the content processes' copies:
|
||||
g_signal_connect_after(default_settings, "notify::gtk-cursor-blink-time",
|
||||
G_CALLBACK(settings_changed_cb), this);
|
||||
g_signal_connect_after(default_settings, "notify::gtk-cursor-blink",
|
||||
G_CALLBACK(settings_changed_cb), this);
|
||||
g_signal_connect_after(default_settings,
|
||||
"notify::gtk-entry-select-on-focus",
|
||||
G_CALLBACK(settings_changed_cb), this);
|
||||
g_signal_connect_after(default_settings,
|
||||
"notify::gtk-primary-button-warps-slider",
|
||||
G_CALLBACK(settings_changed_cb), this);
|
||||
g_signal_connect_after(default_settings, "notify::gtk-menu-popup-delay",
|
||||
G_CALLBACK(settings_changed_cb), this);
|
||||
g_signal_connect_after(default_settings, "notify::gtk-dnd-drag-threshold",
|
||||
G_CALLBACK(settings_changed_cb), this);
|
||||
}
|
||||
|
||||
if (mContainer) {
|
||||
|
|
|
@ -15,12 +15,27 @@ namespace widget {
|
|||
|
||||
#if defined(MOZ_WIDGET_GTK)
|
||||
|
||||
// Our nsLookAndFeel for GTK relies on APIs that aren't available in headless
|
||||
// mode, so we use an implementation with hardcoded values.
|
||||
// Our nsLookAndFeel for Gtk relies on APIs that aren't available in headless
|
||||
// mode, so for processes that are unable to connect to a display server, we use
|
||||
// an implementation with hardcoded values.
|
||||
//
|
||||
// HeadlessLookAndFeel is used:
|
||||
//
|
||||
// * in the parent process, when full headless mode (MOZ_HEADLESS=1) is
|
||||
// enabled
|
||||
// * in content processes, when full headless mode or headless content
|
||||
// mode (security.sandbox.content.headless) is enabled, unless
|
||||
// widget.remote-look-and-feel is also enabled, in which case
|
||||
// RemoteLookAndFeel is used instead.
|
||||
//
|
||||
// The result of this is that when headless content mode is enabled, content
|
||||
// processes use values derived from the parent's nsLookAndFeel (i.e., values
|
||||
// derived from Gtk APIs) while still refraining from making any display server
|
||||
// connections.
|
||||
|
||||
class HeadlessLookAndFeel : public nsXPLookAndFeel {
|
||||
public:
|
||||
HeadlessLookAndFeel();
|
||||
explicit HeadlessLookAndFeel(const LookAndFeelCache* aCache);
|
||||
virtual ~HeadlessLookAndFeel();
|
||||
|
||||
void NativeInit() final{};
|
||||
|
|
|
@ -15,7 +15,7 @@ namespace widget {
|
|||
|
||||
static const char16_t UNICODE_BULLET = 0x2022;
|
||||
|
||||
HeadlessLookAndFeel::HeadlessLookAndFeel() = default;
|
||||
HeadlessLookAndFeel::HeadlessLookAndFeel(const LookAndFeelCache* aCache) {}
|
||||
|
||||
HeadlessLookAndFeel::~HeadlessLookAndFeel() = default;
|
||||
|
||||
|
|
|
@ -177,7 +177,9 @@ EXPORTS.mozilla.widget += [
|
|||
"InProcessCompositorWidget.h",
|
||||
"MediaKeysEventSourceFactory.h",
|
||||
"nsAutoRollup.h",
|
||||
"nsXPLookAndFeel.h",
|
||||
"PuppetBidiKeyboard.h",
|
||||
"RemoteLookAndFeel.h",
|
||||
"Screen.h",
|
||||
"ScreenManager.h",
|
||||
"ThemeChangeKind.h",
|
||||
|
@ -215,6 +217,7 @@ UNIFIED_SOURCES += [
|
|||
"nsXPLookAndFeel.cpp",
|
||||
"PuppetBidiKeyboard.cpp",
|
||||
"PuppetWidget.cpp",
|
||||
"RemoteLookAndFeel.cpp",
|
||||
"Screen.cpp",
|
||||
"ScrollbarDrawingMac.cpp",
|
||||
"SharedWidgetUtils.cpp",
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "nsXPLookAndFeel.h"
|
||||
#include "nsLookAndFeel.h"
|
||||
#include "HeadlessLookAndFeel.h"
|
||||
#include "RemoteLookAndFeel.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsCRT.h"
|
||||
#include "nsFont.h"
|
||||
|
@ -254,11 +255,44 @@ nsXPLookAndFeel* nsXPLookAndFeel::GetInstance() {
|
|||
|
||||
NS_ENSURE_TRUE(!sShutdown, nullptr);
|
||||
|
||||
if (gfxPlatform::IsHeadless()) {
|
||||
sInstance = new widget::HeadlessLookAndFeel();
|
||||
} else {
|
||||
sInstance = new nsLookAndFeel();
|
||||
// If we're in a content process, then the parent process will have supplied
|
||||
// us with an initial FullLookAndFeel object (for when the RemoteLookAndFeel
|
||||
// is to be used) or an initial LookAndFeelCache object (for regular
|
||||
// LookAndFeel implementations). We grab this data from the ContentChild,
|
||||
// where it's been temporarily stashed, and initialize our new LookAndFeel
|
||||
// object with it.
|
||||
|
||||
LookAndFeelCache* lnfCache = nullptr;
|
||||
FullLookAndFeel* fullLnf = nullptr;
|
||||
widget::LookAndFeelData* lnfData = nullptr;
|
||||
|
||||
if (auto* cc = mozilla::dom::ContentChild::GetSingleton()) {
|
||||
lnfData = &cc->BorrowLookAndFeelData();
|
||||
switch (lnfData->type()) {
|
||||
case widget::LookAndFeelData::TLookAndFeelCache:
|
||||
lnfCache = &lnfData->get_LookAndFeelCache();
|
||||
break;
|
||||
case widget::LookAndFeelData::TFullLookAndFeel:
|
||||
fullLnf = &lnfData->get_FullLookAndFeel();
|
||||
break;
|
||||
default:
|
||||
MOZ_ASSERT_UNREACHABLE("unexpected LookAndFeelData type");
|
||||
}
|
||||
}
|
||||
|
||||
if (fullLnf) {
|
||||
sInstance = new widget::RemoteLookAndFeel(std::move(*fullLnf));
|
||||
} else if (gfxPlatform::IsHeadless()) {
|
||||
sInstance = new widget::HeadlessLookAndFeel(lnfCache);
|
||||
} else {
|
||||
sInstance = new nsLookAndFeel(lnfCache);
|
||||
}
|
||||
|
||||
// This is only ever used once during initialization, and can be cleared now.
|
||||
if (lnfData) {
|
||||
*lnfData = widget::LookAndFeelData{};
|
||||
}
|
||||
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
|
@ -461,15 +495,6 @@ void nsXPLookAndFeel::Init() {
|
|||
for (i = 0; i < ArrayLength(sColorPrefs); ++i) {
|
||||
InitColorFromPref(i);
|
||||
}
|
||||
|
||||
if (XRE_IsContentProcess()) {
|
||||
mozilla::dom::ContentChild* cc = mozilla::dom::ContentChild::GetSingleton();
|
||||
|
||||
LookAndFeel::SetCache(cc->BorrowLookAndFeelCache());
|
||||
// This is only ever used once during initialization, and can be cleared
|
||||
// now.
|
||||
cc->BorrowLookAndFeelCache() = LookAndFeelCache{};
|
||||
}
|
||||
}
|
||||
|
||||
nsXPLookAndFeel::~nsXPLookAndFeel() {
|
||||
|
@ -1088,4 +1113,9 @@ void LookAndFeel::SetCache(const widget::LookAndFeelCache& aCache) {
|
|||
nsLookAndFeel::GetInstance()->SetCacheImpl(aCache);
|
||||
}
|
||||
|
||||
// static
|
||||
void LookAndFeel::SetData(widget::FullLookAndFeel&& aTables) {
|
||||
nsLookAndFeel::GetInstance()->SetDataImpl(std::move(aTables));
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -79,6 +79,7 @@ class nsXPLookAndFeel : public mozilla::LookAndFeel {
|
|||
|
||||
virtual uint32_t GetPasswordMaskDelayImpl() { return 600; }
|
||||
|
||||
using FullLookAndFeel = mozilla::widget::FullLookAndFeel;
|
||||
using LookAndFeelCache = mozilla::widget::LookAndFeelCache;
|
||||
using LookAndFeelInt = mozilla::widget::LookAndFeelInt;
|
||||
using LookAndFeelFont = mozilla::widget::LookAndFeelFont;
|
||||
|
@ -86,6 +87,7 @@ class nsXPLookAndFeel : public mozilla::LookAndFeel {
|
|||
|
||||
virtual LookAndFeelCache GetCacheImpl();
|
||||
virtual void SetCacheImpl(const LookAndFeelCache& aCache) {}
|
||||
virtual void SetDataImpl(FullLookAndFeel&& aTables) {}
|
||||
|
||||
virtual void NativeInit() = 0;
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
class nsLookAndFeel final : public nsXPLookAndFeel {
|
||||
public:
|
||||
nsLookAndFeel();
|
||||
explicit nsLookAndFeel(const LookAndFeelCache* aCache);
|
||||
virtual ~nsLookAndFeel();
|
||||
|
||||
void NativeInit() final;
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
#include "gfxFont.h"
|
||||
#include "gfxFontConstants.h"
|
||||
|
||||
nsLookAndFeel::nsLookAndFeel() : nsXPLookAndFeel(), mInitialized(false) {}
|
||||
nsLookAndFeel::nsLookAndFeel(LookAndFeelCache* aCache) : nsXPLookAndFeel(), mInitialized(false) {}
|
||||
|
||||
nsLookAndFeel::~nsLookAndFeel() {}
|
||||
|
||||
|
|
|
@ -89,7 +89,7 @@ static nsresult SystemWantsDarkTheme(int32_t& darkThemeEnabled) {
|
|||
return rv;
|
||||
}
|
||||
|
||||
nsLookAndFeel::nsLookAndFeel()
|
||||
nsLookAndFeel::nsLookAndFeel(const LookAndFeelCache* aCache)
|
||||
: nsXPLookAndFeel(),
|
||||
mUseAccessibilityTheme(0),
|
||||
mUseDefaultTheme(0),
|
||||
|
@ -103,6 +103,9 @@ nsLookAndFeel::nsLookAndFeel()
|
|||
mInitialized(false) {
|
||||
mozilla::Telemetry::Accumulate(mozilla::Telemetry::TOUCH_ENABLED_DEVICE,
|
||||
WinUtils::IsTouchDeviceSupportPresent());
|
||||
if (aCache) {
|
||||
DoSetCache(*aCache);
|
||||
}
|
||||
}
|
||||
|
||||
nsLookAndFeel::~nsLookAndFeel() {}
|
||||
|
@ -839,6 +842,10 @@ LookAndFeelCache nsLookAndFeel::GetCacheImpl() {
|
|||
}
|
||||
|
||||
void nsLookAndFeel::SetCacheImpl(const LookAndFeelCache& aCache) {
|
||||
DoSetCache(aCache);
|
||||
}
|
||||
|
||||
void nsLookAndFeel::DoSetCache(const LookAndFeelCache& aCache) {
|
||||
MOZ_ASSERT(XRE_IsContentProcess());
|
||||
MOZ_RELEASE_ASSERT(aCache.mFonts().Length() == mFontCache.length());
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@ class nsLookAndFeel final : public nsXPLookAndFeel {
|
|||
static OperatingSystemVersion GetOperatingSystemVersion();
|
||||
|
||||
public:
|
||||
nsLookAndFeel();
|
||||
explicit nsLookAndFeel(const LookAndFeelCache* aCache);
|
||||
virtual ~nsLookAndFeel();
|
||||
|
||||
void NativeInit() final;
|
||||
|
@ -62,6 +62,8 @@ class nsLookAndFeel final : public nsXPLookAndFeel {
|
|||
void SetCacheImpl(const LookAndFeelCache& aCache) override;
|
||||
|
||||
private:
|
||||
void DoSetCache(const LookAndFeelCache& aCache);
|
||||
|
||||
/**
|
||||
* Fetches the Windows accent color from the Windows settings if
|
||||
* the accent color is set to apply to the title bar, otherwise
|
||||
|
|
Загрузка…
Ссылка в новой задаче