256 lines
7.6 KiB
C++
256 lines
7.6 KiB
C++
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* vim:expandtab:shiftwidth=2:tabstop=2:
|
|
*/
|
|
/* 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 __nsLookAndFeel
|
|
#define __nsLookAndFeel
|
|
|
|
#include "X11UndefineNone.h"
|
|
#include "nsXPLookAndFeel.h"
|
|
#include "nsCOMPtr.h"
|
|
#include "gfxFont.h"
|
|
|
|
enum WidgetNodeType : int;
|
|
struct _GtkStyle;
|
|
typedef struct _GDBusProxy GDBusProxy;
|
|
typedef struct _GtkCssProvider GtkCssProvider;
|
|
typedef struct _GFile GFile;
|
|
typedef struct _GFileMonitor GFileMonitor;
|
|
typedef struct _GVariant GVariant;
|
|
|
|
namespace mozilla {
|
|
enum class StyleGtkThemeFamily : uint8_t;
|
|
|
|
namespace widget {
|
|
|
|
enum class NativeChangeKind : uint8_t {
|
|
None = 0,
|
|
GtkTheme = 1 << 0,
|
|
OtherSettings = 1 << 1,
|
|
All = GtkTheme | OtherSettings,
|
|
};
|
|
|
|
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(NativeChangeKind)
|
|
|
|
} // namespace widget
|
|
} // namespace mozilla
|
|
|
|
class nsLookAndFeel final : public nsXPLookAndFeel {
|
|
using NativeChangeKind = mozilla::widget::NativeChangeKind;
|
|
|
|
public:
|
|
nsLookAndFeel();
|
|
virtual ~nsLookAndFeel();
|
|
|
|
void RecordChange(NativeChangeKind aKind) { mPendingChanges |= aKind; }
|
|
void NativeInit() final;
|
|
nsresult NativeGetInt(IntID aID, int32_t& aResult) override;
|
|
nsresult NativeGetFloat(FloatID aID, float& aResult) override;
|
|
nsresult NativeGetColor(ColorID, ColorScheme, nscolor& aResult) override;
|
|
bool NativeGetFont(FontID aID, nsString& aFontName,
|
|
gfxFontStyle& aFontStyle) override;
|
|
|
|
char16_t GetPasswordCharacterImpl() override;
|
|
bool GetEchoPasswordImpl() override;
|
|
|
|
void RefreshImpl() override {
|
|
// When calling Refresh(), we don't need to reload all our GTK theme info,
|
|
// but we might need to change our effective theme.
|
|
RecordChange(NativeChangeKind::OtherSettings);
|
|
}
|
|
|
|
bool GetDefaultDrawInTitlebar() override;
|
|
|
|
nsXPLookAndFeel::TitlebarAction GetTitlebarAction(
|
|
TitlebarEvent aEvent) override;
|
|
|
|
void GetThemeInfo(nsACString&) override;
|
|
|
|
nsresult GetKeyboardLayoutImpl(nsACString& aLayout) override;
|
|
|
|
static const nscolor kBlack = NS_RGB(0, 0, 0);
|
|
static const nscolor kWhite = NS_RGB(255, 255, 255);
|
|
// Returns whether any setting changed.
|
|
bool RecomputeDBusSettings();
|
|
// Returns whether the setting really changed.
|
|
bool RecomputeDBusAppearanceSetting(const nsACString& aKey, GVariant* aValue);
|
|
|
|
struct ColorPair {
|
|
nscolor mBg = kWhite;
|
|
nscolor mFg = kBlack;
|
|
|
|
bool operator==(const ColorPair& aOther) const {
|
|
return mBg == aOther.mBg && mFg == aOther.mFg;
|
|
}
|
|
bool operator!=(const ColorPair& aOther) const {
|
|
return !(*this == aOther);
|
|
}
|
|
};
|
|
|
|
using ThemeFamily = mozilla::StyleGtkThemeFamily;
|
|
|
|
protected:
|
|
static bool WidgetUsesImage(WidgetNodeType aNodeType);
|
|
void RecordLookAndFeelSpecificTelemetry() override;
|
|
static bool ShouldHonorThemeScrollbarColors();
|
|
mozilla::Maybe<ColorScheme> ComputeColorSchemeSetting();
|
|
|
|
void WatchDBus();
|
|
void UnwatchDBus();
|
|
|
|
// We use up to two themes (one light, one dark), which might have different
|
|
// sets of fonts and colors.
|
|
struct PerThemeData {
|
|
nsCString mName;
|
|
bool mIsDark = false;
|
|
bool mHighContrast = false;
|
|
bool mPreferDarkTheme = false;
|
|
bool mIsDefaultThemeFallback = false;
|
|
|
|
ThemeFamily mFamily{0};
|
|
|
|
// Cached fonts
|
|
nsString mDefaultFontName;
|
|
nsString mButtonFontName;
|
|
nsString mFieldFontName;
|
|
nsString mMenuFontName;
|
|
gfxFontStyle mDefaultFontStyle;
|
|
gfxFontStyle mButtonFontStyle;
|
|
gfxFontStyle mFieldFontStyle;
|
|
gfxFontStyle mMenuFontStyle;
|
|
|
|
// Cached colors
|
|
nscolor mGrayText = kBlack;
|
|
ColorPair mInfo;
|
|
ColorPair mMenu;
|
|
ColorPair mMenuHover;
|
|
ColorPair mHeaderBar;
|
|
ColorPair mHeaderBarInactive;
|
|
ColorPair mButton;
|
|
ColorPair mButtonHover;
|
|
ColorPair mButtonActive;
|
|
nscolor mButtonBorder = kBlack;
|
|
nscolor mFrameBorder = kBlack;
|
|
nscolor mNativeHyperLinkText = kBlack;
|
|
nscolor mNativeVisitedHyperLinkText = kBlack;
|
|
ColorPair mField;
|
|
ColorPair mWindow;
|
|
ColorPair mDialog;
|
|
ColorPair mSidebar;
|
|
nscolor mSidebarBorder = kBlack;
|
|
|
|
nscolor mMozWindowActiveBorder = kBlack;
|
|
nscolor mMozWindowInactiveBorder = kBlack;
|
|
|
|
ColorPair mCellHighlight;
|
|
ColorPair mSelectedText;
|
|
ColorPair mAccent;
|
|
ColorPair mSelectedItem;
|
|
|
|
ColorPair mMozColHeader;
|
|
ColorPair mMozColHeaderHover;
|
|
ColorPair mMozColHeaderActive;
|
|
|
|
ColorPair mTitlebar;
|
|
ColorPair mTitlebarInactive;
|
|
|
|
nscolor mThemedScrollbar = kWhite;
|
|
nscolor mThemedScrollbarInactive = kWhite;
|
|
nscolor mThemedScrollbarThumb = kBlack;
|
|
nscolor mThemedScrollbarThumbHover = kBlack;
|
|
nscolor mThemedScrollbarThumbActive = kBlack;
|
|
nscolor mThemedScrollbarThumbInactive = kBlack;
|
|
|
|
float mCaretRatio = 0.0f;
|
|
int32_t mTitlebarRadius = 0;
|
|
int32_t mTooltipRadius = 0;
|
|
int32_t mTitlebarButtonSpacing = 0;
|
|
char16_t mInvisibleCharacter = 0;
|
|
bool mMenuSupportsDrag = false;
|
|
|
|
void Init();
|
|
nsresult GetColor(ColorID, nscolor&) const;
|
|
bool GetFont(FontID, nsString& aFontName, gfxFontStyle&,
|
|
float aTextScaleFactor) const;
|
|
void InitCellHighlightColors();
|
|
};
|
|
|
|
PerThemeData mSystemTheme;
|
|
|
|
// If the system theme is light, a dark theme. Otherwise, a light theme. The
|
|
// alternative theme to the current one is preferred, but otherwise we fall
|
|
// back to Adwaita / Adwaita Dark, respectively.
|
|
PerThemeData mAltTheme;
|
|
|
|
const PerThemeData& LightTheme() const {
|
|
return mSystemTheme.mIsDark ? mAltTheme : mSystemTheme;
|
|
}
|
|
|
|
const PerThemeData& DarkTheme() const {
|
|
return mSystemTheme.mIsDark ? mSystemTheme : mAltTheme;
|
|
}
|
|
|
|
const PerThemeData& EffectiveTheme() const {
|
|
return mSystemThemeOverridden ? mAltTheme : mSystemTheme;
|
|
}
|
|
|
|
uint32_t mDBusID = 0;
|
|
RefPtr<GFile> mKdeColors;
|
|
RefPtr<GFileMonitor> mKdeColorsMonitor;
|
|
|
|
mozilla::Maybe<ColorScheme> mColorSchemePreference;
|
|
RefPtr<GDBusProxy> mDBusSettingsProxy;
|
|
// DBus settings from:
|
|
// https://github.com/flatpak/xdg-desktop-portal/blob/main/data/org.freedesktop.portal.Settings.xml
|
|
struct DBusSettings {
|
|
mozilla::Maybe<ColorScheme> mColorScheme;
|
|
bool mPrefersContrast = false;
|
|
// Transparent means no accent-color. Note that the real accent color cannot
|
|
// have transparency.
|
|
ColorPair mAccentColor{NS_TRANSPARENT, NS_TRANSPARENT};
|
|
|
|
bool HasAccentColor() const { return NS_GET_A(mAccentColor.mBg); }
|
|
} mDBusSettings;
|
|
int32_t mCaretBlinkTime = 0;
|
|
int32_t mCaretBlinkCount = -1;
|
|
bool mCSDMaximizeButton = false;
|
|
bool mCSDMinimizeButton = false;
|
|
bool mCSDCloseButton = false;
|
|
bool mCSDReversedPlacement = false;
|
|
bool mPrefersReducedMotion = false;
|
|
bool mSystemThemeOverridden = false;
|
|
NativeChangeKind mPendingChanges = NativeChangeKind::All;
|
|
int32_t mCSDMaximizeButtonPosition = 0;
|
|
int32_t mCSDMinimizeButtonPosition = 0;
|
|
int32_t mCSDCloseButtonPosition = 0;
|
|
TitlebarAction mDoubleClickAction = TitlebarAction::None;
|
|
TitlebarAction mMiddleClickAction = TitlebarAction::None;
|
|
float mTextScaleFactor = 1.0f;
|
|
|
|
RefPtr<GtkCssProvider> mRoundedCornerProvider;
|
|
void UpdateRoundedBottomCornerStyles();
|
|
|
|
void ClearRoundedCornerProvider();
|
|
|
|
void EnsureInit() {
|
|
if (mPendingChanges == NativeChangeKind::None) {
|
|
return;
|
|
}
|
|
Initialize();
|
|
}
|
|
|
|
void Initialize();
|
|
|
|
void RestoreSystemTheme();
|
|
void InitializeGlobalSettings();
|
|
// Returns whether we found an alternative theme.
|
|
bool ConfigureAltTheme();
|
|
void ConfigureAndInitializeAltTheme();
|
|
void ConfigureFinalEffectiveTheme();
|
|
void MaybeApplyColorOverrides();
|
|
};
|
|
|
|
#endif
|