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 CHROME_BROWSER_UI_LIBGTK2UI_GTK2_UI_H_ 6 #define CHROME_BROWSER_UI_LIBGTK2UI_GTK2_UI_H_ 7 8 #include <map> 9 #include <vector> 10 11 #include "base/basictypes.h" 12 #include "base/compiler_specific.h" 13 #include "base/memory/scoped_ptr.h" 14 #include "base/observer_list.h" 15 #include "chrome/browser/ui/libgtk2ui/gtk2_signal.h" 16 #include "chrome/browser/ui/libgtk2ui/gtk2_signal_registrar.h" 17 #include "chrome/browser/ui/libgtk2ui/libgtk2ui_export.h" 18 #include "chrome/browser/ui/libgtk2ui/owned_widget_gtk2.h" 19 #include "ui/events/linux/text_edit_key_bindings_delegate_auralinux.h" 20 #include "ui/gfx/color_utils.h" 21 #include "ui/views/linux_ui/linux_ui.h" 22 #include "ui/views/window/frame_buttons.h" 23 24 typedef struct _GdkColor GdkColor; 25 typedef struct _GtkBorder GtkBorder; 26 typedef struct _GtkStyle GtkStyle; 27 typedef struct _GtkWidget GtkWidget; 28 29 class SkBitmap; 30 31 namespace gfx { 32 class Image; 33 class ScopedPangoFontDescription; 34 } 35 36 namespace libgtk2ui { 37 class Gtk2Border; 38 class Gtk2KeyBindingsHandler; 39 class Gtk2SignalRegistrar; 40 class GConfListener; 41 42 // Interface to GTK2 desktop features. 43 // 44 class Gtk2UI : public views::LinuxUI { 45 public: 46 Gtk2UI(); 47 virtual ~Gtk2UI(); 48 49 typedef base::Callback<ui::NativeTheme*(aura::Window* window)> 50 NativeThemeGetter; 51 52 // Setters used by GConfListener: 53 void SetWindowButtonOrdering( 54 const std::vector<views::FrameButton>& leading_buttons, 55 const std::vector<views::FrameButton>& trailing_buttons); 56 void SetNonClientMiddleClickAction(NonClientMiddleClickAction action); 57 58 // Draws the GTK button border for state |gtk_state| onto a bitmap. 59 SkBitmap DrawGtkButtonBorder(int gtk_state, 60 bool focused, 61 bool call_to_action, 62 int width, 63 int height) const; 64 65 // ui::LinuxInputMethodContextFactory: 66 virtual scoped_ptr<ui::LinuxInputMethodContext> CreateInputMethodContext( 67 ui::LinuxInputMethodContextDelegate* delegate) const OVERRIDE; 68 69 // gfx::LinuxFontDelegate: 70 virtual gfx::FontRenderParams GetDefaultFontRenderParams() const OVERRIDE; 71 virtual scoped_ptr<gfx::ScopedPangoFontDescription> 72 GetDefaultPangoFontDescription() const OVERRIDE; 73 virtual double GetFontDPI() const OVERRIDE; 74 75 // ui::LinuxShellDialog: 76 virtual ui::SelectFileDialog* CreateSelectFileDialog( 77 ui::SelectFileDialog::Listener* listener, 78 ui::SelectFilePolicy* policy) const OVERRIDE; 79 80 // ui::LinuxUI: 81 virtual void Initialize() OVERRIDE; 82 virtual gfx::Image GetThemeImageNamed(int id) const OVERRIDE; 83 virtual bool GetColor(int id, SkColor* color) const OVERRIDE; 84 virtual bool HasCustomImage(int id) const OVERRIDE; 85 virtual SkColor GetFocusRingColor() const OVERRIDE; 86 virtual SkColor GetThumbActiveColor() const OVERRIDE; 87 virtual SkColor GetThumbInactiveColor() const OVERRIDE; 88 virtual SkColor GetTrackColor() const OVERRIDE; 89 virtual SkColor GetActiveSelectionBgColor() const OVERRIDE; 90 virtual SkColor GetActiveSelectionFgColor() const OVERRIDE; 91 virtual SkColor GetInactiveSelectionBgColor() const OVERRIDE; 92 virtual SkColor GetInactiveSelectionFgColor() const OVERRIDE; 93 virtual double GetCursorBlinkInterval() const OVERRIDE; 94 virtual ui::NativeTheme* GetNativeTheme(aura::Window* window) const OVERRIDE; 95 virtual void SetNativeThemeOverride(const NativeThemeGetter& callback) 96 OVERRIDE; 97 virtual bool GetDefaultUsesSystemTheme() const OVERRIDE; 98 virtual void SetDownloadCount(int count) const OVERRIDE; 99 virtual void SetProgressFraction(float percentage) const OVERRIDE; 100 virtual bool IsStatusIconSupported() const OVERRIDE; 101 virtual scoped_ptr<views::StatusIconLinux> CreateLinuxStatusIcon( 102 const gfx::ImageSkia& image, 103 const base::string16& tool_tip) const OVERRIDE; 104 virtual gfx::Image GetIconForContentType( 105 const std::string& content_type, int size) const OVERRIDE; 106 virtual scoped_ptr<views::Border> CreateNativeBorder( 107 views::LabelButton* owning_button, 108 scoped_ptr<views::LabelButtonBorder> border) OVERRIDE; 109 virtual void AddWindowButtonOrderObserver( 110 views::WindowButtonOrderObserver* observer) OVERRIDE; 111 virtual void RemoveWindowButtonOrderObserver( 112 views::WindowButtonOrderObserver* observer) OVERRIDE; 113 virtual bool UnityIsRunning() OVERRIDE; 114 virtual NonClientMiddleClickAction GetNonClientMiddleClickAction() OVERRIDE; 115 virtual void NotifyWindowManagerStartupComplete() OVERRIDE; 116 117 // ui::TextEditKeybindingDelegate: 118 virtual bool MatchEvent( 119 const ui::Event& event, 120 std::vector<ui::TextEditCommandAuraLinux>* commands) OVERRIDE; 121 122 private: 123 typedef std::map<int, SkColor> ColorMap; 124 typedef std::map<int, color_utils::HSL> TintMap; 125 typedef std::map<int, gfx::Image> ImageCache; 126 127 // This method returns the colors webkit will use for the scrollbars. When no 128 // colors are specified by the GTK+ theme, this function averages of the 129 // thumb part and of the track colors. 130 void GetScrollbarColors(GdkColor* thumb_active_color, 131 GdkColor* thumb_inactive_color, 132 GdkColor* track_color); 133 134 // Extracts colors and tints from the GTK theme, both for the 135 // ThemeService interface and the colors we send to webkit. 136 void LoadGtkValues(); 137 138 // Reads in explicit theme frame colors from the ChromeGtkFrame style class 139 // or generates them per our fallback algorithm. 140 GdkColor BuildFrameColors(GtkStyle* frame_style); 141 142 // Sets the underlying theme colors/tints from a GTK color. 143 void SetThemeColorFromGtk(int id, const GdkColor* color); 144 void SetThemeTintFromGtk(int id, const GdkColor* color); 145 146 // Creates and returns a frame color, either using |gtk_base| verbatim if 147 // non-NULL, or tinting |base| with |tint|. Also sets |color_id| and 148 // |tint_id| to the returned color. 149 GdkColor BuildAndSetFrameColor(const GdkColor* base, 150 const GdkColor* gtk_base, 151 const color_utils::HSL& tint, 152 int color_id, 153 int tint_id); 154 155 // Lazily generates each bitmap used in the gtk theme. 156 SkBitmap GenerateGtkThemeBitmap(int id) const; 157 158 // Creates a GTK+ version of IDR_THEME_FRAME. Instead of tinting, this 159 // creates a theme configurable gradient ending with |color_id| at the 160 // bottom, and |gradient_name| at the top if that color is specified in the 161 // theme. 162 SkBitmap GenerateFrameImage(int color_id, 163 const char* gradient_name) const; 164 165 // Takes the base frame image |base_id| and tints it with |tint_id|. 166 SkBitmap GenerateTabImage(int base_id) const; 167 168 // Tints an icon based on tint. 169 SkBitmap GenerateTintedIcon(int base_id, 170 const color_utils::HSL& tint) const; 171 172 // Renders a GTK icon as a SkBitmap, with prelight/active border if 173 // appropriate. 174 SkBitmap GenerateGTKIcon(int base_id) const; 175 176 // Renders a GTK button border the size of the image |sizing_idr| in 177 // |gtk_state|. 178 SkBitmap GenerateToolbarBezel(int gtk_state, int sizing_idr) const; 179 180 // Returns the tint for buttons that contrasts with the normal window 181 // background color. 182 void GetNormalButtonTintHSL(color_utils::HSL* tint) const; 183 184 // Returns a tint that's the color of the current normal text in an entry. 185 void GetNormalEntryForegroundHSL(color_utils::HSL* tint) const; 186 187 // Returns a tint that's the color of the current highlighted text in an 188 // entry. 189 void GetSelectedEntryForegroundHSL(color_utils::HSL* tint) const; 190 191 // Gets a color for the background of the call to action button. 192 SkColor CallToActionBgColor(int gtk_state) const; 193 194 // Frees all calculated images and color data. 195 void ClearAllThemeData(); 196 197 // Handles signal from GTK that our theme has been changed. 198 CHROMEGTK_CALLBACK_1(Gtk2UI, void, OnStyleSet, GtkStyle*); 199 200 GtkWidget* fake_window_; 201 GtkWidget* fake_frame_; 202 OwnedWidgetGtk fake_label_; 203 OwnedWidgetGtk fake_entry_; 204 205 // Tracks all the signals we have connected to on various widgets. 206 scoped_ptr<Gtk2SignalRegistrar> signals_; 207 208 // Tints and colors calculated by LoadGtkValues() that are given to the 209 // caller while |use_gtk_| is true. 210 ColorMap colors_; 211 TintMap tints_; 212 213 // Colors used to tint certain icons. 214 color_utils::HSL button_tint_; 215 color_utils::HSL entry_tint_; 216 color_utils::HSL selected_entry_tint_; 217 218 // Colors that we pass to WebKit. These are generated each time the theme 219 // changes. 220 SkColor focus_ring_color_; 221 SkColor thumb_active_color_; 222 SkColor thumb_inactive_color_; 223 SkColor track_color_; 224 SkColor active_selection_bg_color_; 225 SkColor active_selection_fg_color_; 226 SkColor inactive_selection_bg_color_; 227 SkColor inactive_selection_fg_color_; 228 229 // Pango description for the default UI font. 230 scoped_ptr<gfx::ScopedPangoFontDescription> default_font_description_; 231 232 #if defined(USE_GCONF) 233 // Currently, the only source of window button configuration. This will 234 // change if we ever have to support XFCE's configuration system or KDE's. 235 scoped_ptr<GConfListener> gconf_listener_; 236 #endif // defined(USE_GCONF) 237 238 // If either of these vectors are non-empty, they represent the current 239 // window button configuration. 240 std::vector<views::FrameButton> leading_buttons_; 241 std::vector<views::FrameButton> trailing_buttons_; 242 243 scoped_ptr<Gtk2KeyBindingsHandler> key_bindings_handler_; 244 245 // Objects to notify when the window frame button order changes. 246 ObserverList<views::WindowButtonOrderObserver> observer_list_; 247 248 // Whether we should lower the window on a middle click to the non client 249 // area. 250 NonClientMiddleClickAction middle_click_action_; 251 252 // Image cache of lazily created images. 253 mutable ImageCache gtk_images_; 254 255 // Used to override the native theme for a window. If no override is provided 256 // or the callback returns NULL, Gtk2UI will default to a NativeThemeGtk2 257 // instance. 258 NativeThemeGetter native_theme_overrider_; 259 260 DISALLOW_COPY_AND_ASSIGN(Gtk2UI); 261 }; 262 263 } // namespace libgtk2ui 264 265 // Access point to the GTK2 desktop system. This should be the only symbol that 266 // is exported in the library; everything else should be used through the 267 // interface, because eventually this .so will be loaded through dlopen at 268 // runtime so our main binary can conditionally load GTK2 or GTK3 or EFL or 269 // QT or whatever. 270 LIBGTK2UI_EXPORT views::LinuxUI* BuildGtk2UI(); 271 272 #endif // CHROME_BROWSER_UI_LIBGTK2UI_GTK2_UI_H_ 273