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