File: native_theme_win.h

package info (click to toggle)
chromium 138.0.7204.183-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 6,071,908 kB
  • sloc: cpp: 34,937,088; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,953; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,806; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (241 lines) | stat: -rw-r--r-- 9,422 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef UI_NATIVE_THEME_NATIVE_THEME_WIN_H_
#define UI_NATIVE_THEME_NATIVE_THEME_WIN_H_

// A wrapper class for working with custom XP/Vista themes provided in
// uxtheme.dll.  This is a singleton class that can be grabbed using
// NativeThemeWin::instance().
// For more information on visual style parts and states, see:
// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/commctls/userex/topics/partsandstates.asp
#include <windows.h>

#include <optional>

#include "base/component_export.h"
#include "base/no_destructor.h"
#include "base/win/registry.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/sys_color_change_listener.h"
#include "ui/native_theme/native_theme.h"

class SkCanvas;

namespace ui {

// Windows implementation of native theme class.
//
// At the moment, this class in in transition from an older API that consists
// of several PaintXXX methods to an API, inherited from the NativeTheme base
// class, that consists of a single Paint() method with a argument to indicate
// what kind of part to paint.
class COMPONENT_EXPORT(NATIVE_THEME) NativeThemeWin
    : public NativeTheme,
      public gfx::SysColorChangeListener {
 public:
  enum ThemeName {
    BUTTON,
    LIST,
    MENU,
    MENULIST,
    SCROLLBAR,
    STATUS,
    TAB,
    TEXTFIELD,
    TRACKBAR,
    WINDOW,
    PROGRESS,
    SPIN,
    LAST
  };

  NativeThemeWin(const NativeThemeWin&) = delete;
  NativeThemeWin& operator=(const NativeThemeWin&) = delete;

  // Closes cached theme handles so we can unload the DLL or update our UI
  // for a theme change.
  static void CloseHandles();

  // NativeTheme implementation:
  gfx::Size GetPartSize(Part part,
                        State state,
                        const ExtraParams& extra) const override;
  void Paint(cc::PaintCanvas* canvas,
             const ui::ColorProvider* color_provider,
             Part part,
             State state,
             const gfx::Rect& rect,
             const ExtraParams& extra,
             ColorScheme color_scheme,
             bool in_forced_colors,
             const std::optional<SkColor>& accent_color) const override;
  bool SupportsNinePatch(Part part) const override;
  gfx::Size GetNinePatchCanvasSize(Part part) const override;
  gfx::Rect GetNinePatchAperture(Part part) const override;
  bool ShouldUseDarkColors() const override;

  // On Windows, we look at the high contrast setting to calculate the color
  // scheme. If high contrast is enabled, the preferred color scheme calculation
  // will ignore the state of dark mode. Instead, preferred color scheme will be
  // light or dark depending on the OS high contrast theme. If high contrast is
  // off, the preferred color scheme calculation will be based of the state of
  // dark mode.
  PreferredColorScheme CalculatePreferredColorScheme() const override;

  PreferredContrast CalculatePreferredContrast() const override;
  ColorScheme GetDefaultSystemColorScheme() const override;

 protected:
  friend class NativeTheme;
  friend class base::NoDestructor<NativeThemeWin>;

  // NativeTheme:
  void ConfigureWebInstance() override;
  std::optional<base::TimeDelta> GetPlatformCaretBlinkInterval() const override;

  NativeThemeWin(bool configure_web_instance, bool should_only_use_dark_colors);
  ~NativeThemeWin() override;

 private:
  bool IsUsingHighContrastThemeInternal() const;
  void CloseHandlesInternal();

  // gfx::SysColorChangeListener:
  void OnSysColorChange() override;

  // Update the locally cached set of system colors.
  void UpdateSystemColors();

  // Painting functions that paint to PaintCanvas.
  void PaintMenuSeparator(cc::PaintCanvas* canvas,
                          const ColorProvider* color_provider,
                          const MenuSeparatorExtraParams& params) const;
  void PaintMenuGutter(cc::PaintCanvas* canvas,
                       const ColorProvider* color_provider,
                       const gfx::Rect& rect) const;
  void PaintMenuBackground(cc::PaintCanvas* canvas,
                           const ColorProvider* color_provider,
                           const gfx::Rect& rect) const;

  // Paint directly to canvas' HDC.
  void PaintDirect(SkCanvas* destination_canvas,
                   HDC hdc,
                   Part part,
                   State state,
                   const gfx::Rect& rect,
                   const ExtraParams& extra) const;

  // Create a temporary HDC, paint to that, clean up the alpha values in the
  // temporary HDC, and then blit the result to canvas.  This is to work around
  // the fact that Windows XP and some classic themes give bogus alpha values.
  void PaintIndirect(cc::PaintCanvas* destination_canvas,
                     Part part,
                     State state,
                     const gfx::Rect& rect,
                     const ExtraParams& extra) const;

  // Various helpers to paint specific parts.
  void PaintButtonClassic(HDC hdc,
                          Part part,
                          State state,
                          RECT* rect,
                          const ButtonExtraParams& extra) const;
  void PaintLeftMenuArrowThemed(HDC hdc,
                                HANDLE handle,
                                int part_id,
                                int state_id,
                                const gfx::Rect& rect) const;
  void PaintScrollbarArrowClassic(HDC hdc,
                                  Part part,
                                  State state,
                                  RECT* rect) const;
  void PaintScrollbarTrackClassic(SkCanvas* canvas,
                                  HDC hdc,
                                  RECT* rect,
                                  const ScrollbarTrackExtraParams& extra) const;
  void PaintHorizontalTrackbarThumbClassic(
      SkCanvas* canvas,
      HDC hdc,
      const RECT& rect,
      const TrackbarExtraParams& extra) const;
  void PaintProgressBarOverlayThemed(HDC hdc,
                                     HANDLE handle,
                                     RECT* bar_rect,
                                     RECT* value_rect,
                                     const ProgressBarExtraParams& extra) const;
  void PaintTextFieldThemed(HDC hdc,
                            HANDLE handle,
                            HBRUSH bg_brush,
                            int part_id,
                            int state_id,
                            RECT* rect,
                            const TextFieldExtraParams& extra) const;
  void PaintTextFieldClassic(HDC hdc,
                             HBRUSH bg_brush,
                             RECT* rect,
                             const TextFieldExtraParams& extra) const;

  // Paints a theme part, with support for scene scaling in high-DPI mode.
  // |theme| is the theme handle. |hdc| is the handle for the device context.
  // |part_id| is the identifier for the part (e.g. thumb gripper). |state_id|
  // is the identifier for the rendering state of the part (e.g. hover). |rect|
  // is the bounds for rendering, expressed in logical coordinates.
  void PaintScaledTheme(HANDLE theme,
                        HDC hdc,
                        int part_id,
                        int state_id,
                        const gfx::Rect& rect) const;

  // Get the windows theme name/part/state.  These three helper functions are
  // used only by GetPartSize(), as each of the corresponding PaintXXX()
  // methods do further validation of the part and state that is required for
  // getting the size.
  static ThemeName GetThemeName(Part part);
  static int GetWindowsPart(Part part, State state, const ExtraParams& extra);
  static int GetWindowsState(Part part, State state, const ExtraParams& extra);

  HRESULT PaintFrameControl(HDC hdc,
                            const gfx::Rect& rect,
                            UINT type,
                            UINT state,
                            bool is_selected,
                            State control_state) const;

  // Returns a handle to the theme data.
  HANDLE GetThemeHandle(ThemeName theme_name) const;

  void RegisterThemeRegkeyObserver();
  void RegisterColorFilteringRegkeyObserver();
  void UpdateDarkModeStatus();
  void UpdatePrefersReducedTransparency();
  void UpdateInvertedColors();

  // True if Windows supports dark mode. This does NOT indicate whether the
  // system is in dark mode, only that it is supported by this version of
  // Windows.
  const bool supports_windows_dark_mode_;

  // Dark Mode/Transparency registry key.
  base::win::RegKey hkcu_themes_regkey_;

  // Inverted colors registry key
  base::win::RegKey hkcu_color_filtering_regkey_;

  // A cache of open theme handles.
  mutable HANDLE theme_handles_[LAST];

  // The system color change listener and the updated cache of system colors.
  gfx::ScopedSysColorChangeListener color_change_listener_;

  // Used to notify the web native theme of changes to dark mode, high
  // contrast, preferred color scheme, and preferred contrast.
  std::unique_ptr<NativeTheme::ColorSchemeNativeThemeObserver>
      color_scheme_observer_;
};

}  // namespace ui

#endif  // UI_NATIVE_THEME_NATIVE_THEME_WIN_H_