1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim:expandtab:shiftwidth=2:tabstop=2:
3  */
4 /* This Source Code Form is subject to the terms of the Mozilla Public
5  * License, v. 2.0. If a copy of the MPL was not distributed with this
6  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 
8 #ifndef __nsLookAndFeel
9 #define __nsLookAndFeel
10 
11 #include "X11UndefineNone.h"
12 #include "nsXPLookAndFeel.h"
13 #include "nsCOMPtr.h"
14 #include "gfxFont.h"
15 
16 enum WidgetNodeType : int;
17 struct _GtkStyle;
18 
19 class nsLookAndFeel final : public nsXPLookAndFeel {
20  public:
21   nsLookAndFeel();
22   virtual ~nsLookAndFeel();
23 
24   void NativeInit() final;
25   void RefreshImpl() override;
26   nsresult NativeGetInt(IntID aID, int32_t& aResult) override;
27   nsresult NativeGetFloat(FloatID aID, float& aResult) override;
28   nsresult NativeGetColor(ColorID, ColorScheme, nscolor& aResult) override;
29   bool NativeGetFont(FontID aID, nsString& aFontName,
30                      gfxFontStyle& aFontStyle) override;
31 
32   char16_t GetPasswordCharacterImpl() override;
33   bool GetEchoPasswordImpl() override;
34 
35   template <typename Callback>
36   void WithAltThemeConfigured(const Callback&);
37 
38   void InitializeAltTheme();
39 
40   void GetGtkContentTheme(LookAndFeelTheme&) override;
41 
42   static void ConfigureTheme(const LookAndFeelTheme& aTheme);
43 
IsCSDAvailable()44   bool IsCSDAvailable() const { return mCSDAvailable; }
45 
46   static const nscolor kBlack = NS_RGB(0, 0, 0);
47   static const nscolor kWhite = NS_RGB(255, 255, 255);
48 
49  protected:
50   static bool WidgetUsesImage(WidgetNodeType aNodeType);
51   void RecordLookAndFeelSpecificTelemetry() override;
52   static bool ShouldHonorThemeScrollbarColors();
53 
54   // We use up to two themes (one light, one dark), which might have different
55   // sets of fonts and colors.
56   struct PerThemeData {
57     nsCString mName;
58 
59     bool mIsDark = false;
60     bool mHighContrast = false;
61     bool mPreferDarkTheme = false;
62 
63     // NOTE(emilio): This is unused, but if we need to we can use it to override
64     // system colors with standins like we do for the non-native theme.
65     bool mCompatibleWithHTMLLightColors = false;
66 
67     // Cached fonts
68     nsString mDefaultFontName;
69     nsString mButtonFontName;
70     nsString mFieldFontName;
71     nsString mMenuFontName;
72     gfxFontStyle mDefaultFontStyle;
73     gfxFontStyle mButtonFontStyle;
74     gfxFontStyle mFieldFontStyle;
75     gfxFontStyle mMenuFontStyle;
76 
77     // Cached colors
78     nscolor mInfoBackground = kWhite;
79     nscolor mInfoText = kBlack;
80     nscolor mMenuBackground = kWhite;
81     nscolor mMenuBarText = kBlack;
82     nscolor mMenuBarHoverText = kBlack;
83     nscolor mMenuText = kBlack;
84     nscolor mMenuTextInactive = kWhite;
85     nscolor mMenuHover = kWhite;
86     nscolor mMenuHoverText = kBlack;
87     nscolor mButtonDefault = kWhite;
88     nscolor mButtonText = kBlack;
89     nscolor mButtonHoverText = kBlack;
90     nscolor mButtonHoverFace = kWhite;
91     nscolor mButtonActiveText = kBlack;
92     nscolor mFrameOuterLightBorder = kBlack;
93     nscolor mFrameInnerDarkBorder = kBlack;
94     nscolor mOddCellBackground = kWhite;
95     nscolor mNativeHyperLinkText = kBlack;
96     nscolor mComboBoxText = kBlack;
97     nscolor mComboBoxBackground = kWhite;
98     nscolor mFieldText = kBlack;
99     nscolor mFieldBackground = kWhite;
100     nscolor mMozWindowText = kBlack;
101     nscolor mMozWindowBackground = kWhite;
102     nscolor mMozWindowActiveBorder = kBlack;
103     nscolor mMozWindowInactiveBorder = kBlack;
104     nscolor mMozWindowInactiveCaption = kWhite;
105     nscolor mMozCellHighlightBackground = kWhite;
106     nscolor mMozCellHighlightText = kBlack;
107     nscolor mTextSelectedText = kBlack;
108     nscolor mTextSelectedBackground = kWhite;
109     nscolor mAccentColor = kWhite;
110     nscolor mAccentColorForeground = kWhite;
111     nscolor mMozScrollbar = kWhite;
112     nscolor mMozColHeaderText = kBlack;
113     nscolor mMozColHeaderHoverText = kBlack;
114     nscolor mTitlebarText = kBlack;
115     nscolor mTitlebarInactiveText = kBlack;
116     nscolor mThemedScrollbar = kWhite;
117     nscolor mThemedScrollbarInactive = kWhite;
118     nscolor mThemedScrollbarThumb = kBlack;
119     nscolor mThemedScrollbarThumbHover = kBlack;
120     nscolor mThemedScrollbarThumbActive = kBlack;
121     nscolor mThemedScrollbarThumbInactive = kBlack;
122 
123     float mCaretRatio = 0.0f;
124     char16_t mInvisibleCharacter = 0;
125     bool mMenuSupportsDrag = false;
126 
127     void Init();
128     nsresult GetColor(ColorID, nscolor&) const;
129     bool GetFont(FontID, nsString& aFontName, gfxFontStyle&) const;
130     void InitCellHighlightColors();
131   };
132 
133   PerThemeData mSystemTheme;
134 
135   // If the system theme is light, a dark theme. Otherwise, a light theme. The
136   // alternative theme to the current one is preferred, but otherwise we fall
137   // back to Adwaita / Adwaita Dark, respectively.
138   PerThemeData mAltTheme;
139 
LightTheme()140   const PerThemeData& LightTheme() const {
141     return mSystemTheme.mIsDark ? mAltTheme : mSystemTheme;
142   }
143 
DarkTheme()144   const PerThemeData& DarkTheme() const {
145     return mSystemTheme.mIsDark ? mSystemTheme : mAltTheme;
146   }
147 
148   int32_t mCaretBlinkTime = 0;
149   bool mCSDAvailable = false;
150   bool mCSDHideTitlebarByDefault = false;
151   bool mCSDMaximizeButton = false;
152   bool mCSDMinimizeButton = false;
153   bool mCSDCloseButton = false;
154   bool mCSDReversedPlacement = false;
155   bool mPrefersReducedMotion = false;
156   bool mInitialized = false;
157   bool mSystemThemeOverridden = false;
158   int32_t mCSDMaximizeButtonPosition = 0;
159   int32_t mCSDMinimizeButtonPosition = 0;
160   int32_t mCSDCloseButtonPosition = 0;
161 
162   void EnsureInit();
163 
164   static void FirefoxThemeChanged(const char*, void* aInstance);
165   void RestoreSystemTheme();
166   bool MatchFirefoxThemeIfNeeded();
167 };
168 
169 #endif
170