1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef UI_GTK_GTK_UI_H_
6 #define UI_GTK_GTK_UI_H_
7 
8 #include <map>
9 #include <memory>
10 #include <vector>
11 
12 #include "base/compiler_specific.h"
13 #include "base/component_export.h"
14 #include "base/macros.h"
15 #include "base/observer_list.h"
16 #include "build/buildflag.h"
17 #include "ui/base/glib/glib_signal.h"
18 #include "ui/gfx/color_utils.h"
19 #include "ui/gtk/gtk_ui_delegate.h"
20 #include "ui/views/linux_ui/linux_ui.h"
21 #include "ui/views/window/frame_buttons.h"
22 
23 typedef struct _GParamSpec GParamSpec;
24 typedef struct _GtkParamSpec GtkParamSpec;
25 typedef struct _GtkSettings GtkSettings;
26 typedef struct _GtkStyle GtkStyle;
27 typedef struct _GtkWidget GtkWidget;
28 
29 namespace gtk {
30 using ColorMap = std::map<int, SkColor>;
31 
32 class GtkKeyBindingsHandler;
33 class DeviceScaleFactorObserver;
34 class NativeThemeGtk;
35 class SettingsProvider;
36 
37 // Interface to GTK desktop features.
38 class GtkUi : public views::LinuxUI {
39  public:
40   explicit GtkUi(ui::GtkUiDelegate* delegate);
41   ~GtkUi() override;
42 
43   // Static delegate getter, used by different objects (created by GtkUi), e.g:
44   // Dialogs, IME Context, when platform-specific functionality is required.
45   static ui::GtkUiDelegate* GetDelegate();
46 
47   // Setters used by SettingsProvider:
48   void SetWindowButtonOrdering(
49       const std::vector<views::FrameButton>& leading_buttons,
50       const std::vector<views::FrameButton>& trailing_buttons);
51   void SetWindowFrameAction(WindowFrameActionSource source,
52                             WindowFrameAction action);
53 
54   // ui::LinuxInputMethodContextFactory:
55   std::unique_ptr<ui::LinuxInputMethodContext> CreateInputMethodContext(
56       ui::LinuxInputMethodContextDelegate* delegate,
57       bool is_simple) const override;
58 
59   // gfx::LinuxFontDelegate:
60   gfx::FontRenderParams GetDefaultFontRenderParams() const override;
61   void GetDefaultFontDescription(
62       std::string* family_out,
63       int* size_pixels_out,
64       int* style_out,
65       gfx::Font::Weight* weight_out,
66       gfx::FontRenderParams* params_out) const override;
67 
68   // ui::ShellDialogLinux:
69   ui::SelectFileDialog* CreateSelectFileDialog(
70       ui::SelectFileDialog::Listener* listener,
71       std::unique_ptr<ui::SelectFilePolicy> policy) const override;
72 
73   // views::LinuxUI:
74   void Initialize() override;
75   bool GetTint(int id, color_utils::HSL* tint) const override;
76   bool GetColor(int id, SkColor* color, bool use_custom_frame) const override;
77   bool GetDisplayProperty(int id, int* result) const override;
78   SkColor GetFocusRingColor() const override;
79   SkColor GetActiveSelectionBgColor() const override;
80   SkColor GetActiveSelectionFgColor() const override;
81   SkColor GetInactiveSelectionBgColor() const override;
82   SkColor GetInactiveSelectionFgColor() const override;
83   base::TimeDelta GetCursorBlinkInterval() const override;
84   ui::NativeTheme* GetNativeTheme(aura::Window* window) const override;
85   void SetUseSystemThemeCallback(UseSystemThemeCallback callback) override;
86   bool GetDefaultUsesSystemTheme() const override;
87   gfx::Image GetIconForContentType(const std::string& content_type,
88                                    int size) const override;
89   std::unique_ptr<views::Border> CreateNativeBorder(
90       views::LabelButton* owning_button,
91       std::unique_ptr<views::LabelButtonBorder> border) override;
92   void AddWindowButtonOrderObserver(
93       views::WindowButtonOrderObserver* observer) override;
94   void RemoveWindowButtonOrderObserver(
95       views::WindowButtonOrderObserver* observer) override;
96   WindowFrameAction GetWindowFrameAction(
97       WindowFrameActionSource source) override;
98   void NotifyWindowManagerStartupComplete() override;
99   void UpdateDeviceScaleFactor() override;
100   float GetDeviceScaleFactor() const override;
101   void AddDeviceScaleFactorObserver(
102       views::DeviceScaleFactorObserver* observer) override;
103   void RemoveDeviceScaleFactorObserver(
104       views::DeviceScaleFactorObserver* observer) override;
105   bool PreferDarkTheme() const override;
106   bool AnimationsEnabled() const override;
107   std::unique_ptr<views::NavButtonProvider> CreateNavButtonProvider() override;
108   base::flat_map<std::string, std::string> GetKeyboardLayoutMap() override;
109   std::string GetCursorThemeName() override;
110   int GetCursorThemeSize() override;
111 
112   // ui::TextEditKeybindingDelegate:
113   bool MatchEvent(const ui::Event& event,
114                   std::vector<ui::TextEditCommandAuraLinux>* commands) override;
115 
116  private:
117   using TintMap = std::map<int, color_utils::HSL>;
118 
119   CHROMEG_CALLBACK_1(GtkUi, void, OnThemeChanged, GtkSettings*, GtkParamSpec*);
120 
121   CHROMEG_CALLBACK_1(GtkUi,
122                      void,
123                      OnCursorThemeNameChanged,
124                      GtkSettings*,
125                      GtkParamSpec*);
126 
127   CHROMEG_CALLBACK_1(GtkUi,
128                      void,
129                      OnCursorThemeSizeChanged,
130                      GtkSettings*,
131                      GtkParamSpec*);
132 
133   CHROMEG_CALLBACK_1(GtkUi,
134                      void,
135                      OnDeviceScaleFactorMaybeChanged,
136                      void*,
137                      GParamSpec*);
138 
139   // Loads all GTK-provided settings.
140   void LoadGtkValues();
141 
142   // Extracts colors and tints from the GTK theme, both for the
143   // ThemeService interface and the colors we send to Blink.
144   void UpdateColors();
145 
146   // Updates |default_font_*|.
147   void UpdateDefaultFont();
148 
149   float GetRawDeviceScaleFactor();
150 
151   // Not owned by GtkUi.
152   ui::GtkUiDelegate* const delegate_;
153 
154   NativeThemeGtk* native_theme_;
155 
156   // A regular GtkWindow.
157   GtkWidget* fake_window_;
158 
159   // Colors calculated by LoadGtkValues() that are given to the
160   // caller while |use_gtk_| is true.
161   ColorMap colors_;
162 
163   // Frame colors (and colors that depend on frame colors) when using
164   // Chrome-rendered borders and titlebar.
165   ColorMap custom_frame_colors_;
166 
167   // Frame colors (and colors that depend on frame colors) when using
168   // system-rendered borders and titlebar.
169   ColorMap native_frame_colors_;
170 
171   // Colors that we pass to Blink. These are generated each time the theme
172   // changes.
173   SkColor focus_ring_color_;
174   SkColor active_selection_bg_color_;
175   SkColor active_selection_fg_color_;
176   SkColor inactive_selection_bg_color_;
177   SkColor inactive_selection_fg_color_;
178 
179   // Details about the default UI font.
180   std::string default_font_family_;
181   int default_font_size_pixels_ = 0;
182   // Bitfield of gfx::Font::Style values.
183   int default_font_style_ = gfx::Font::NORMAL;
184   gfx::Font::Weight default_font_weight_ = gfx::Font::Weight::NORMAL;
185   gfx::FontRenderParams default_font_render_params_;
186 
187   std::unique_ptr<SettingsProvider> settings_provider_;
188 
189   // Frame button layout state.  If |nav_buttons_set_| is false, then
190   // |leading_buttons_| and |trailing_buttons_| are meaningless.
191   bool nav_buttons_set_ = false;
192   std::vector<views::FrameButton> leading_buttons_;
193   std::vector<views::FrameButton> trailing_buttons_;
194 
195   std::unique_ptr<GtkKeyBindingsHandler> key_bindings_handler_;
196 
197   // Objects to notify when the window frame button order changes.
198   base::ObserverList<views::WindowButtonOrderObserver>::Unchecked
199       window_button_order_observer_list_;
200 
201   // Objects to notify when the device scale factor changes.
202   base::ObserverList<views::DeviceScaleFactorObserver>::Unchecked
203       device_scale_factor_observer_list_;
204 
205   // The action to take when middle, double, or right clicking the titlebar.
206   base::flat_map<WindowFrameActionSource, WindowFrameAction>
207       window_frame_actions_;
208 
209   // Used to determine whether the system theme should be used for a window.  If
210   // no override is provided or the callback returns true, GtkUi will default
211   // to a NativeThemeGtk instance.
212   UseSystemThemeCallback use_system_theme_callback_;
213 
214   float device_scale_factor_ = 1.0f;
215 
216   DISALLOW_COPY_AND_ASSIGN(GtkUi);
217 };
218 
219 }  // namespace gtk
220 
221 // Access point to the GTK desktop system.
222 COMPONENT_EXPORT(GTK)
223 views::LinuxUI* BuildGtkUi(ui::GtkUiDelegate* delegate);
224 
225 #endif  // UI_GTK_GTK_UI_H_
226