Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/ui/libgtk2ui/gtk2_ui.h" | 5 #include "chrome/browser/ui/libgtk2ui/gtk2_ui.h" |
| 6 | 6 |
| 7 #include <math.h> | 7 #include <math.h> |
| 8 #include <set> | 8 #include <set> |
| 9 | 9 |
| 10 #include <pango/pango.h> | 10 #include <pango/pango.h> |
| 11 | 11 |
| 12 #include "base/command_line.h" | 12 #include "base/command_line.h" |
| 13 #include "base/debug/leak_annotations.h" | 13 #include "base/debug/leak_annotations.h" |
| 14 #include "base/environment.h" | 14 #include "base/environment.h" |
| 15 #include "base/i18n/rtl.h" | 15 #include "base/i18n/rtl.h" |
| 16 #include "base/logging.h" | 16 #include "base/logging.h" |
| 17 #include "base/nix/mime_util_xdg.h" | 17 #include "base/nix/mime_util_xdg.h" |
| 18 #include "base/nix/xdg_util.h" | 18 #include "base/nix/xdg_util.h" |
| 19 #include "base/stl_util.h" | 19 #include "base/stl_util.h" |
| 20 #include "base/strings/string_split.h" | 20 #include "base/strings/string_split.h" |
| 21 #include "base/strings/stringprintf.h" | 21 #include "base/strings/stringprintf.h" |
| 22 #include "chrome/browser/themes/theme_properties.h" | 22 #include "chrome/browser/themes/theme_properties.h" |
| 23 #include "chrome/browser/ui/libgtk2ui/app_indicator_icon.h" | 23 #include "chrome/browser/ui/libgtk2ui/app_indicator_icon.h" |
| 24 #include "chrome/browser/ui/libgtk2ui/chrome_gtk_frame.h" | |
| 25 #include "chrome/browser/ui/libgtk2ui/gtk2_border.h" | 24 #include "chrome/browser/ui/libgtk2ui/gtk2_border.h" |
| 26 #include "chrome/browser/ui/libgtk2ui/gtk2_event_loop.h" | 25 #include "chrome/browser/ui/libgtk2ui/gtk2_event_loop.h" |
| 27 #include "chrome/browser/ui/libgtk2ui/gtk2_key_bindings_handler.h" | 26 #include "chrome/browser/ui/libgtk2ui/gtk2_key_bindings_handler.h" |
| 28 #include "chrome/browser/ui/libgtk2ui/gtk2_signal_registrar.h" | 27 #include "chrome/browser/ui/libgtk2ui/gtk2_signal_registrar.h" |
| 29 #include "chrome/browser/ui/libgtk2ui/gtk2_status_icon.h" | 28 #include "chrome/browser/ui/libgtk2ui/gtk2_status_icon.h" |
| 30 #include "chrome/browser/ui/libgtk2ui/gtk2_util.h" | 29 #include "chrome/browser/ui/libgtk2ui/gtk2_util.h" |
| 31 #include "chrome/browser/ui/libgtk2ui/native_theme_gtk2.h" | 30 #include "chrome/browser/ui/libgtk2ui/native_theme_gtk2.h" |
| 32 #include "chrome/browser/ui/libgtk2ui/print_dialog_gtk2.h" | 31 #include "chrome/browser/ui/libgtk2ui/print_dialog_gtk2.h" |
| 33 #include "chrome/browser/ui/libgtk2ui/printing_gtk2_util.h" | 32 #include "chrome/browser/ui/libgtk2ui/printing_gtk2_util.h" |
| 34 #include "chrome/browser/ui/libgtk2ui/select_file_dialog_impl.h" | 33 #include "chrome/browser/ui/libgtk2ui/select_file_dialog_impl.h" |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 45 #include "ui/base/resource/resource_bundle.h" | 44 #include "ui/base/resource/resource_bundle.h" |
| 46 #include "ui/gfx/canvas.h" | 45 #include "ui/gfx/canvas.h" |
| 47 #include "ui/gfx/display.h" | 46 #include "ui/gfx/display.h" |
| 48 #include "ui/gfx/geometry/rect.h" | 47 #include "ui/gfx/geometry/rect.h" |
| 49 #include "ui/gfx/geometry/size.h" | 48 #include "ui/gfx/geometry/size.h" |
| 50 #include "ui/gfx/image/image.h" | 49 #include "ui/gfx/image/image.h" |
| 51 #include "ui/gfx/skbitmap_operations.h" | 50 #include "ui/gfx/skbitmap_operations.h" |
| 52 #include "ui/gfx/skia_util.h" | 51 #include "ui/gfx/skia_util.h" |
| 53 #include "ui/native_theme/native_theme.h" | 52 #include "ui/native_theme/native_theme.h" |
| 54 #include "ui/resources/grit/ui_resources.h" | 53 #include "ui/resources/grit/ui_resources.h" |
| 54 #include "ui/views/controls/button/blue_button.h" | |
| 55 #include "ui/views/controls/button/label_button.h" | 55 #include "ui/views/controls/button/label_button.h" |
| 56 #include "ui/views/controls/button/label_button_border.h" | 56 #include "ui/views/controls/button/label_button_border.h" |
| 57 #include "ui/views/linux_ui/window_button_order_observer.h" | 57 #include "ui/views/linux_ui/window_button_order_observer.h" |
| 58 #include "ui/views/resources/grit/views_resources.h" | 58 #include "ui/views/resources/grit/views_resources.h" |
| 59 | 59 |
| 60 #if defined(USE_GCONF) | 60 #if defined(USE_GCONF) |
| 61 #include "chrome/browser/ui/libgtk2ui/gconf_listener.h" | 61 #include "chrome/browser/ui/libgtk2ui/gconf_listener.h" |
| 62 #endif | 62 #endif |
| 63 | 63 |
| 64 // A minimized port of GtkThemeService into something that can provide colors | 64 // A minimized port of GtkThemeService into something that can provide colors |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 100 // Number of app indicators used (used as part of app-indicator id). | 100 // Number of app indicators used (used as part of app-indicator id). |
| 101 int indicators_count; | 101 int indicators_count; |
| 102 | 102 |
| 103 // The unknown content type. | 103 // The unknown content type. |
| 104 const char* kUnknownContentType = "application/octet-stream"; | 104 const char* kUnknownContentType = "application/octet-stream"; |
| 105 | 105 |
| 106 // The size of the rendered toolbar image. | 106 // The size of the rendered toolbar image. |
| 107 const int kToolbarImageWidth = 64; | 107 const int kToolbarImageWidth = 64; |
| 108 const int kToolbarImageHeight = 128; | 108 const int kToolbarImageHeight = 128; |
| 109 | 109 |
| 110 // How much to tint the GTK+ color lighter at the top of the window. | |
| 111 const color_utils::HSL kGtkFrameShift = { -1, -1, 0.58 }; | |
| 112 | |
| 113 // How much to tint the GTK+ color when an explicit frame color hasn't been | |
| 114 // specified. | |
| 115 const color_utils::HSL kDefaultFrameShift = { -1, -1, 0.4 }; | |
| 116 | |
| 117 // Values used as the new luminance and saturation values in the inactive tab | 110 // Values used as the new luminance and saturation values in the inactive tab |
| 118 // text color. | 111 // text color. |
| 119 const double kDarkInactiveLuminance = 0.85; | 112 const double kDarkInactiveLuminance = 0.85; |
| 120 const double kLightInactiveLuminance = 0.15; | 113 const double kLightInactiveLuminance = 0.15; |
| 121 const double kHeavyInactiveSaturation = 0.7; | 114 const double kHeavyInactiveSaturation = 0.7; |
| 122 const double kLightInactiveSaturation = 0.3; | 115 const double kLightInactiveSaturation = 0.3; |
| 123 | 116 |
| 124 // Default color for links on the NTP when the GTK+ theme doesn't define a | |
| 125 // link color. Constant taken from gtklinkbutton.c. | |
| 126 const GdkColor kDefaultLinkColor = { 0, 0, 0, 0xeeee }; | |
| 127 | |
| 128 const int kSkiaToGDKMultiplier = 257; | |
| 129 | |
| 130 // TODO(erg): ThemeService has a whole interface just for reading default | 117 // TODO(erg): ThemeService has a whole interface just for reading default |
| 131 // constants. Figure out what to do with that more long term; for now, just | 118 // constants. Figure out what to do with that more long term; for now, just |
| 132 // copy the constants themselves here. | 119 // copy the constants themselves here. |
| 133 // | 120 // |
| 134 // Default tints. | 121 // Default tints. |
| 135 const color_utils::HSL kDefaultTintButtons = { -1, -1, -1 }; | 122 const color_utils::HSL kDefaultTintButtons = { -1, -1, -1 }; |
| 136 const color_utils::HSL kDefaultTintFrame = { -1, -1, -1 }; | 123 const color_utils::HSL kDefaultTintFrame = { -1, -1, -1 }; |
| 137 const color_utils::HSL kDefaultTintFrameInactive = { -1, -1, 0.75f }; | 124 const color_utils::HSL kDefaultTintFrameInactive = { -1, -1, 0.75f }; |
| 138 const color_utils::HSL kDefaultTintFrameIncognito = { -1, 0.2f, 0.35f }; | 125 const color_utils::HSL kDefaultTintFrameIncognito = { -1, 0.2f, 0.35f }; |
| 139 const color_utils::HSL kDefaultTintFrameIncognitoInactive = { -1, 0.3f, 0.6f }; | 126 const color_utils::HSL kDefaultTintFrameIncognitoInactive = { -1, 0.3f, 0.6f }; |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 174 IDR_OMNIBOX_STAR, | 161 IDR_OMNIBOX_STAR, |
| 175 IDR_OMNIBOX_STAR_DARK, | 162 IDR_OMNIBOX_STAR_DARK, |
| 176 IDR_OMNIBOX_TTS, | 163 IDR_OMNIBOX_TTS, |
| 177 IDR_OMNIBOX_TTS_DARK, | 164 IDR_OMNIBOX_TTS_DARK, |
| 178 }; | 165 }; |
| 179 | 166 |
| 180 // This table converts button ids into a pair of gtk-stock id and state. | 167 // This table converts button ids into a pair of gtk-stock id and state. |
| 181 struct IDRGtkMapping { | 168 struct IDRGtkMapping { |
| 182 int idr; | 169 int idr; |
| 183 const char* stock_id; | 170 const char* stock_id; |
| 184 GtkStateType gtk_state; | 171 bool enabled; |
| 185 } const kGtkIcons[] = { | 172 } const kGtkIcons[] = { |
| 186 { IDR_BACK, GTK_STOCK_GO_BACK, GTK_STATE_NORMAL }, | 173 { IDR_BACK, "go-previous", true }, |
| 187 { IDR_BACK_D, GTK_STOCK_GO_BACK, GTK_STATE_INSENSITIVE }, | 174 { IDR_BACK_D, "go-previous", false }, |
| 188 | 175 |
| 189 { IDR_FORWARD, GTK_STOCK_GO_FORWARD, GTK_STATE_NORMAL }, | 176 { IDR_FORWARD, "go-next", true }, |
| 190 { IDR_FORWARD_D, GTK_STOCK_GO_FORWARD, GTK_STATE_INSENSITIVE }, | 177 { IDR_FORWARD_D, "go-next", false }, |
| 191 | 178 |
| 192 { IDR_HOME, GTK_STOCK_HOME, GTK_STATE_NORMAL }, | 179 { IDR_HOME, "go-home", true }, |
| 193 | 180 |
| 194 { IDR_RELOAD, GTK_STOCK_REFRESH, GTK_STATE_NORMAL }, | 181 { IDR_RELOAD, "view-refresh", true }, |
| 195 { IDR_RELOAD_D, GTK_STOCK_REFRESH, GTK_STATE_INSENSITIVE }, | 182 { IDR_RELOAD_D, "view-refresh", false }, |
| 196 | 183 |
| 197 { IDR_STOP, GTK_STOCK_STOP, GTK_STATE_NORMAL }, | 184 { IDR_STOP, "process-stop", true }, |
| 198 { IDR_STOP_D, GTK_STOCK_STOP, GTK_STATE_INSENSITIVE }, | 185 { IDR_STOP_D, "process-stop", false }, |
| 199 }; | 186 }; |
| 200 | 187 |
| 201 // The image resources that will be tinted by the 'button' tint value. | 188 // The image resources that will be tinted by the 'button' tint value. |
| 202 const int kOtherToolbarButtonIDs[] = { | 189 const int kOtherToolbarButtonIDs[] = { |
| 203 IDR_TOOLBAR_BEZEL_HOVER, | 190 IDR_TOOLBAR_BEZEL_HOVER, |
| 204 IDR_TOOLBAR_BEZEL_PRESSED, | 191 IDR_TOOLBAR_BEZEL_PRESSED, |
| 205 IDR_BROWSER_ACTIONS_OVERFLOW, | 192 IDR_BROWSER_ACTIONS_OVERFLOW, |
| 206 | 193 |
| 207 // TODO(erg): The dropdown arrow should be tinted because we're injecting | 194 // TODO(erg): The dropdown arrow should be tinted because we're injecting |
| 208 // various background GTK colors, but the code that accesses them needs to be | 195 // various background GTK colors, but the code that accesses them needs to be |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 222 for (unsigned int i = 0; i < arraysize(kGtkIcons); ++i) | 209 for (unsigned int i = 0; i < arraysize(kGtkIcons); ++i) |
| 223 images.insert(kGtkIcons[i].idr); | 210 images.insert(kGtkIcons[i].idr); |
| 224 | 211 |
| 225 images.insert(kOtherToolbarButtonIDs, | 212 images.insert(kOtherToolbarButtonIDs, |
| 226 kOtherToolbarButtonIDs + arraysize(kOtherToolbarButtonIDs)); | 213 kOtherToolbarButtonIDs + arraysize(kOtherToolbarButtonIDs)); |
| 227 } | 214 } |
| 228 | 215 |
| 229 return images.count(id) > 0; | 216 return images.count(id) > 0; |
| 230 } | 217 } |
| 231 | 218 |
| 219 // Get ChromeGtkFrame theme colors. No-op in GTK3. | |
| 220 void GetChromeStyleColor(const char* style_property, SkColor* ret_color) { | |
| 221 #if GTK_MAJOR_VERSION == 2 | |
| 222 GdkColor* style_color = NULL; | |
| 223 | |
| 224 gtk_widget_style_get(NativeThemeGtk2::instance()->GetWindow(), | |
| 225 style_property, &style_color, | |
| 226 NULL); | |
| 227 | |
| 228 if (style_color) { | |
| 229 *ret_color = GdkColorToSkColor(*style_color); | |
| 230 gdk_color_free(style_color); | |
| 231 } | |
| 232 #endif | |
| 233 } | |
| 234 | |
| 232 // Picks a button tint from a set of background colors. While | 235 // Picks a button tint from a set of background colors. While |
| 233 // |accent_gdk_color| will usually be the same color through a theme, this | 236 // |accent_color| will usually be the same color through a theme, this |
| 234 // function will get called with the normal GtkLabel |text_color|/GtkWindow | 237 // function will get called with the normal GtkLabel |text_color|/GtkWindow |
| 235 // |background_color| pair and the GtkEntry |text_color|/|background_color| | 238 // |background_color| pair and the GtkEntry |text_color|/|background_color| |
| 236 // pair. While 3/4 of the time the resulting tint will be the same, themes that | 239 // pair. While 3/4 of the time the resulting tint will be the same, themes that |
| 237 // have a dark window background (with light text) and a light text entry (with | 240 // have a dark window background (with light text) and a light text entry (with |
| 238 // dark text) will get better icons with this separated out. | 241 // dark text) will get better icons with this separated out. |
| 239 void PickButtonTintFromColors(const GdkColor& accent_gdk_color, | 242 void PickButtonTintFromColors(SkColor accent_color, |
| 240 const GdkColor& text_color, | 243 SkColor text_color, |
| 241 const GdkColor& background_color, | 244 SkColor background_color, |
| 242 color_utils::HSL* tint) { | 245 color_utils::HSL* tint) { |
| 243 SkColor accent_color = GdkColorToSkColor(accent_gdk_color); | 246 color_utils::HSL accent_tint, text_tint, background_tint; |
| 244 color_utils::HSL accent_tint; | |
| 245 color_utils::SkColorToHSL(accent_color, &accent_tint); | 247 color_utils::SkColorToHSL(accent_color, &accent_tint); |
| 246 | 248 color_utils::SkColorToHSL(text_color, &text_tint); |
| 247 color_utils::HSL text_tint; | 249 color_utils::SkColorToHSL(background_color, &background_tint); |
| 248 color_utils::SkColorToHSL(GdkColorToSkColor(text_color), | |
| 249 &text_tint); | |
| 250 | |
| 251 color_utils::HSL background_tint; | |
| 252 color_utils::SkColorToHSL(GdkColorToSkColor(background_color), | |
| 253 &background_tint); | |
| 254 | 250 |
| 255 // If the accent color is gray, then our normal HSL tomfoolery will bring out | 251 // If the accent color is gray, then our normal HSL tomfoolery will bring out |
| 256 // whatever color is oddly dominant (for example, in rgb space [125, 128, | 252 // whatever color is oddly dominant (for example, in rgb space [125, 128, |
| 257 // 125] will tint green instead of gray). Slight differences (+/-10 (4%) to | 253 // 125] will tint green instead of gray). Slight differences (+/-10 (4%) to |
| 258 // all color components) should be interpreted as this color being gray and | 254 // all color components) should be interpreted as this color being gray and |
| 259 // we should switch into a special grayscale mode. | 255 // we should switch into a special grayscale mode. |
| 260 int rb_diff = abs(static_cast<int>(SkColorGetR(accent_color)) - | 256 int rb_diff = abs(static_cast<int>(SkColorGetR(accent_color)) - |
| 261 static_cast<int>(SkColorGetB(accent_color))); | 257 static_cast<int>(SkColorGetB(accent_color))); |
| 262 int rg_diff = abs(static_cast<int>(SkColorGetR(accent_color)) - | 258 int rg_diff = abs(static_cast<int>(SkColorGetR(accent_color)) - |
| 263 static_cast<int>(SkColorGetG(accent_color))); | 259 static_cast<int>(SkColorGetG(accent_color))); |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 290 // white. | 286 // white. |
| 291 if (text_tint.l < 0.5) | 287 if (text_tint.l < 0.5) |
| 292 tint->l = -1; | 288 tint->l = -1; |
| 293 else if (text_tint.l <= 0.9) | 289 else if (text_tint.l <= 0.9) |
| 294 tint->l = text_tint.l; | 290 tint->l = text_tint.l; |
| 295 else | 291 else |
| 296 tint->l = 0.9; | 292 tint->l = 0.9; |
| 297 } | 293 } |
| 298 } | 294 } |
| 299 | 295 |
| 300 // Applies an HSL shift to a GdkColor (instead of an SkColor) | |
| 301 void GdkColorHSLShift(const color_utils::HSL& shift, GdkColor* frame_color) { | |
| 302 SkColor shifted = color_utils::HSLShift( | |
| 303 GdkColorToSkColor(*frame_color), shift); | |
| 304 | |
| 305 frame_color->pixel = 0; | |
| 306 frame_color->red = SkColorGetR(shifted) * kSkiaToGDKMultiplier; | |
| 307 frame_color->green = SkColorGetG(shifted) * kSkiaToGDKMultiplier; | |
| 308 frame_color->blue = SkColorGetB(shifted) * kSkiaToGDKMultiplier; | |
| 309 } | |
| 310 | |
| 311 // Copied Default blah sections from ThemeService. | 296 // Copied Default blah sections from ThemeService. |
| 312 color_utils::HSL GetDefaultTint(int id) { | 297 color_utils::HSL GetDefaultTint(int id) { |
| 313 switch (id) { | 298 switch (id) { |
| 314 case ThemeProperties::TINT_FRAME: | 299 case ThemeProperties::TINT_FRAME: |
| 315 return kDefaultTintFrame; | 300 return kDefaultTintFrame; |
| 316 case ThemeProperties::TINT_FRAME_INACTIVE: | 301 case ThemeProperties::TINT_FRAME_INACTIVE: |
| 317 return kDefaultTintFrameInactive; | 302 return kDefaultTintFrameInactive; |
| 318 case ThemeProperties::TINT_FRAME_INCOGNITO: | 303 case ThemeProperties::TINT_FRAME_INCOGNITO: |
| 319 return kDefaultTintFrameIncognito; | 304 return kDefaultTintFrameIncognito; |
| 320 case ThemeProperties::TINT_FRAME_INCOGNITO_INACTIVE: | 305 case ThemeProperties::TINT_FRAME_INCOGNITO_INACTIVE: |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 421 } // namespace | 406 } // namespace |
| 422 | 407 |
| 423 Gtk2UI::Gtk2UI() | 408 Gtk2UI::Gtk2UI() |
| 424 : default_font_size_pixels_(0), | 409 : default_font_size_pixels_(0), |
| 425 default_font_style_(gfx::Font::NORMAL), | 410 default_font_style_(gfx::Font::NORMAL), |
| 426 middle_click_action_(GetDefaultMiddleClickAction()), | 411 middle_click_action_(GetDefaultMiddleClickAction()), |
| 427 device_scale_factor_(1.0) { | 412 device_scale_factor_(1.0) { |
| 428 GtkInitFromCommandLine(*base::CommandLine::ForCurrentProcess()); | 413 GtkInitFromCommandLine(*base::CommandLine::ForCurrentProcess()); |
| 429 } | 414 } |
| 430 | 415 |
| 416 | |
| 417 | |
| 418 void OnThemeChanged(GObject* obj, GParamSpec* param, Gtk2UI* gtkui) { | |
| 419 gtkui->ResetStyle(); | |
| 420 } | |
| 421 | |
| 431 void Gtk2UI::Initialize() { | 422 void Gtk2UI::Initialize() { |
| 432 signals_.reset(new Gtk2SignalRegistrar); | 423 GtkSettings* settings = gtk_settings_get_default(); |
| 424 g_signal_connect_after(settings, | |
| 425 "notify::gtk-theme-name", | |
| 426 G_CALLBACK(OnThemeChanged), | |
| 427 this); | |
| 428 g_signal_connect_after(settings, | |
| 429 "notify::gtk-icon-theme-name", | |
| 430 G_CALLBACK(OnThemeChanged), | |
| 431 this); | |
| 433 | 432 |
| 434 // Create our fake widgets. | |
| 435 fake_window_ = gtk_window_new(GTK_WINDOW_TOPLEVEL); | |
| 436 fake_frame_ = chrome_gtk_frame_new(); | |
| 437 fake_label_.Own(gtk_label_new("")); | |
| 438 fake_entry_.Own(gtk_entry_new()); | |
| 439 | |
| 440 // Only realized widgets receive style-set notifications, which we need to | |
| 441 // broadcast new theme images and colors. Only realized widgets have style | |
| 442 // properties, too, which we query for some colors. | |
| 443 gtk_widget_realize(fake_frame_); | |
| 444 gtk_widget_realize(fake_window_); | |
| 445 | |
| 446 signals_->Connect(fake_frame_, "style-set", | |
| 447 G_CALLBACK(&OnStyleSetThunk), this); | |
| 448 | 433 |
| 449 LoadGtkValues(); | 434 LoadGtkValues(); |
| 450 | 435 |
| 451 printing::PrintingContextLinux::SetCreatePrintDialogFunction( | 436 printing::PrintingContextLinux::SetCreatePrintDialogFunction( |
| 452 &PrintDialogGtk2::CreatePrintDialog); | 437 &PrintDialogGtk2::CreatePrintDialog); |
| 453 printing::PrintingContextLinux::SetPdfPaperSizeFunction( | 438 printing::PrintingContextLinux::SetPdfPaperSizeFunction( |
| 454 &GetPdfPaperSizeDeviceUnitsGtk); | 439 &GetPdfPaperSizeDeviceUnitsGtk); |
| 455 | 440 |
| 456 #if defined(USE_GCONF) | 441 #if defined(USE_GCONF) |
| 457 // We must build this after GTK gets initialized. | 442 // We must build this after GTK gets initialized. |
| 458 gconf_listener_.reset(new GConfListener(this)); | 443 gconf_listener_.reset(new GConfListener(this)); |
| 459 #endif // defined(USE_GCONF) | 444 #endif // defined(USE_GCONF) |
| 460 | 445 |
| 461 indicators_count = 0; | 446 indicators_count = 0; |
| 462 | 447 |
| 463 // Instantiate the singleton instance of Gtk2EventLoop. | 448 // Instantiate the singleton instance of Gtk2EventLoop. |
| 464 Gtk2EventLoop::GetInstance(); | 449 Gtk2EventLoop::GetInstance(); |
| 465 } | 450 } |
| 466 | 451 |
| 467 Gtk2UI::~Gtk2UI() { | 452 Gtk2UI::~Gtk2UI() { |
| 468 gtk_widget_destroy(fake_window_); | |
| 469 gtk_widget_destroy(fake_frame_); | |
| 470 fake_label_.Destroy(); | |
| 471 fake_entry_.Destroy(); | |
| 472 | |
| 473 ClearAllThemeData(); | 453 ClearAllThemeData(); |
| 474 } | 454 } |
| 475 | 455 |
| 476 gfx::Image Gtk2UI::GetThemeImageNamed(int id) const { | 456 gfx::Image Gtk2UI::GetThemeImageNamed(int id) const { |
| 477 // Try to get our cached version: | 457 // Try to get our cached version: |
| 478 ImageCache::const_iterator it = gtk_images_.find(id); | 458 ImageCache::const_iterator it = gtk_images_.find(id); |
| 479 if (it != gtk_images_.end()) | 459 if (it != gtk_images_.end()) |
| 480 return it->second; | 460 return it->second; |
| 481 | 461 |
| 482 if (IsOverridableImage(id)) { | 462 if (IsOverridableImage(id)) { |
| (...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 734 | 714 |
| 735 bool Gtk2UI::MatchEvent(const ui::Event& event, | 715 bool Gtk2UI::MatchEvent(const ui::Event& event, |
| 736 std::vector<ui::TextEditCommandAuraLinux>* commands) { | 716 std::vector<ui::TextEditCommandAuraLinux>* commands) { |
| 737 // Ensure that we have a keyboard handler. | 717 // Ensure that we have a keyboard handler. |
| 738 if (!key_bindings_handler_) | 718 if (!key_bindings_handler_) |
| 739 key_bindings_handler_.reset(new Gtk2KeyBindingsHandler); | 719 key_bindings_handler_.reset(new Gtk2KeyBindingsHandler); |
| 740 | 720 |
| 741 return key_bindings_handler_->MatchEvent(event, commands); | 721 return key_bindings_handler_->MatchEvent(event, commands); |
| 742 } | 722 } |
| 743 | 723 |
| 744 void Gtk2UI::GetScrollbarColors(GdkColor* thumb_active_color, | 724 void Gtk2UI::SetScrollbarColors() { |
| 745 GdkColor* thumb_inactive_color, | 725 thumb_active_color_ = SkColorSetRGB(244, 244, 244); |
| 746 GdkColor* track_color) { | 726 thumb_inactive_color_ = SkColorSetRGB(234, 234, 234); |
| 747 GdkColor* theme_thumb_active = NULL; | 727 track_color_ = SkColorSetRGB(211, 211, 211); |
| 748 GdkColor* theme_thumb_inactive = NULL; | |
| 749 GdkColor* theme_trough_color = NULL; | |
| 750 gtk_widget_style_get(GTK_WIDGET(fake_frame_), | |
| 751 "scrollbar-slider-prelight-color", &theme_thumb_active, | |
| 752 "scrollbar-slider-normal-color", &theme_thumb_inactive, | |
| 753 "scrollbar-trough-color", &theme_trough_color, | |
| 754 NULL); | |
| 755 | 728 |
| 756 // Ask the theme if the theme specifies all the scrollbar colors and short | 729 GetChromeStyleColor("scrollbar-slider-prelight-color", &thumb_active_color_); |
| 757 // circuit the expensive painting/compositing if we have all of them. | 730 GetChromeStyleColor("scrollbar-slider-normal-color", &thumb_inactive_color_); |
| 758 if (theme_thumb_active && theme_thumb_inactive && theme_trough_color) { | 731 GetChromeStyleColor("scrollbar-trough-color", &track_color_); |
| 759 *thumb_active_color = *theme_thumb_active; | |
| 760 *thumb_inactive_color = *theme_thumb_inactive; | |
| 761 *track_color = *theme_trough_color; | |
| 762 | |
| 763 gdk_color_free(theme_thumb_active); | |
| 764 gdk_color_free(theme_thumb_inactive); | |
| 765 gdk_color_free(theme_trough_color); | |
| 766 return; | |
| 767 } | |
| 768 | |
| 769 // Create window containing scrollbar elements | |
| 770 GtkWidget* window = gtk_window_new(GTK_WINDOW_POPUP); | |
| 771 GtkWidget* fixed = gtk_fixed_new(); | |
| 772 GtkWidget* scrollbar = gtk_hscrollbar_new(NULL); | |
| 773 gtk_container_add(GTK_CONTAINER(window), fixed); | |
| 774 gtk_container_add(GTK_CONTAINER(fixed), scrollbar); | |
| 775 gtk_widget_realize(window); | |
| 776 gtk_widget_realize(scrollbar); | |
| 777 | |
| 778 // Draw scrollbar thumb part and track into offscreen image | |
| 779 const int kWidth = 100; | |
| 780 const int kHeight = 20; | |
| 781 GtkStyle* style = gtk_rc_get_style(scrollbar); | |
| 782 GdkWindow* gdk_window = gtk_widget_get_window(window); | |
| 783 GdkPixmap* pm = gdk_pixmap_new(gdk_window, kWidth, kHeight, -1); | |
| 784 GdkRectangle rect = { 0, 0, kWidth, kHeight }; | |
| 785 unsigned char data[3 * kWidth * kHeight]; | |
| 786 for (int i = 0; i < 3; ++i) { | |
| 787 if (i < 2) { | |
| 788 // Thumb part | |
| 789 gtk_paint_slider(style, pm, | |
| 790 i == 0 ? GTK_STATE_PRELIGHT : GTK_STATE_NORMAL, | |
| 791 GTK_SHADOW_OUT, &rect, scrollbar, "slider", 0, 0, | |
| 792 kWidth, kHeight, GTK_ORIENTATION_HORIZONTAL); | |
| 793 } else { | |
| 794 // Track | |
| 795 gtk_paint_box(style, pm, GTK_STATE_ACTIVE, GTK_SHADOW_IN, &rect, | |
| 796 scrollbar, "trough-upper", 0, 0, kWidth, kHeight); | |
| 797 } | |
| 798 GdkPixbuf* pb = gdk_pixbuf_new_from_data(data, GDK_COLORSPACE_RGB, | |
| 799 FALSE, 8, kWidth, kHeight, | |
| 800 3 * kWidth, 0, 0); | |
| 801 gdk_pixbuf_get_from_drawable(pb, pm, NULL, 0, 0, 0, 0, kWidth, kHeight); | |
| 802 | |
| 803 // Sample pixels | |
| 804 int components[3] = { 0 }; | |
| 805 for (int y = 2; y < kHeight - 2; ++y) { | |
| 806 for (int c = 0; c < 3; ++c) { | |
| 807 // Sample a vertical slice of pixels at about one-thirds from the | |
| 808 // left edge. This allows us to avoid any fixed graphics that might be | |
| 809 // located at the edges or in the center of the scrollbar. | |
| 810 // Each pixel is made up of a red, green, and blue component; taking up | |
| 811 // a total of three bytes. | |
| 812 components[c] += data[3 * (kWidth / 3 + y * kWidth) + c]; | |
| 813 } | |
| 814 } | |
| 815 GdkColor* color = i == 0 ? thumb_active_color : | |
| 816 i == 1 ? thumb_inactive_color : | |
| 817 track_color; | |
| 818 color->pixel = 0; | |
| 819 // We sampled pixels across the full height of the image, ignoring a two | |
| 820 // pixel border. In some themes, the border has a completely different | |
| 821 // color which we do not want to factor into our average color computation. | |
| 822 // | |
| 823 // We now need to scale the colors from the 0..255 range, to the wider | |
| 824 // 0..65535 range, and we need to actually compute the average color; so, | |
| 825 // we divide by the total number of pixels in the sample. | |
| 826 color->red = components[0] * 65535 / (255 * (kHeight - 4)); | |
| 827 color->green = components[1] * 65535 / (255 * (kHeight - 4)); | |
| 828 color->blue = components[2] * 65535 / (255 * (kHeight - 4)); | |
| 829 | |
| 830 g_object_unref(pb); | |
| 831 } | |
| 832 g_object_unref(pm); | |
| 833 | |
| 834 gtk_widget_destroy(window); | |
| 835 | |
| 836 // Override any of the default colors with ones that were specified by the | |
| 837 // theme. | |
| 838 if (theme_thumb_active) { | |
| 839 *thumb_active_color = *theme_thumb_active; | |
| 840 gdk_color_free(theme_thumb_active); | |
| 841 } | |
| 842 | |
| 843 if (theme_thumb_inactive) { | |
| 844 *thumb_inactive_color = *theme_thumb_inactive; | |
| 845 gdk_color_free(theme_thumb_inactive); | |
| 846 } | |
| 847 | |
| 848 if (theme_trough_color) { | |
| 849 *track_color = *theme_trough_color; | |
| 850 gdk_color_free(theme_trough_color); | |
| 851 } | |
| 852 } | 732 } |
| 853 | 733 |
| 854 void Gtk2UI::LoadGtkValues() { | 734 void Gtk2UI::LoadGtkValues() { |
| 855 // TODO(erg): GtkThemeService had a comment here about having to muck with | 735 // TODO(erg): GtkThemeService had a comment here about having to muck with |
| 856 // the raw Prefs object to remove prefs::kCurrentThemeImages or else we'd | 736 // the raw Prefs object to remove prefs::kCurrentThemeImages or else we'd |
| 857 // regress startup time. Figure out how to do that when we can't access the | 737 // regress startup time. Figure out how to do that when we can't access the |
| 858 // prefs system from here. | 738 // prefs system from here. |
| 859 | 739 |
| 860 GtkStyle* frame_style = gtk_rc_get_style(fake_frame_); | 740 NativeThemeGtk2* theme = NativeThemeGtk2::instance(); |
| 861 | 741 |
| 862 GtkStyle* window_style = gtk_rc_get_style(fake_window_); | 742 SkColor toolbar_color = |
| 863 SetThemeColorFromGtk(ThemeProperties::COLOR_CONTROL_BACKGROUND, | 743 theme->GetSystemColor(ui::NativeTheme::kColorId_WindowBackground); |
| 864 &window_style->bg[GTK_STATE_NORMAL]); | 744 SkColor button_color = |
| 745 theme->GetSystemColor(ui::NativeTheme::kColorId_ButtonHighlightColor); | |
| 746 SkColor label_color = | |
| 747 theme->GetSystemColor(ui::NativeTheme::kColorId_LabelEnabledColor); | |
| 865 | 748 |
| 866 GdkColor toolbar_color = window_style->bg[GTK_STATE_NORMAL]; | 749 colors_[ThemeProperties::COLOR_CONTROL_BACKGROUND] = toolbar_color; |
| 867 SetThemeColorFromGtk(ThemeProperties::COLOR_TOOLBAR, &toolbar_color); | 750 colors_[ThemeProperties::COLOR_TOOLBAR] = toolbar_color; |
| 868 | 751 |
| 869 GdkColor button_color = window_style->bg[GTK_STATE_SELECTED]; | 752 SetThemeTint(ThemeProperties::TINT_BUTTONS, button_color); |
| 870 SetThemeTintFromGtk(ThemeProperties::TINT_BUTTONS, &button_color); | |
| 871 | 753 |
| 872 GtkStyle* label_style = gtk_rc_get_style(fake_label_.get()); | 754 colors_[ThemeProperties::COLOR_TAB_TEXT] = label_color; |
| 873 GdkColor label_color = label_style->fg[GTK_STATE_NORMAL]; | 755 colors_[ThemeProperties::COLOR_BOOKMARK_TEXT] = label_color; |
| 874 SetThemeColorFromGtk(ThemeProperties::COLOR_TAB_TEXT, &label_color); | 756 colors_[ThemeProperties::COLOR_STATUS_BAR_TEXT] = label_color; |
| 875 SetThemeColorFromGtk(ThemeProperties::COLOR_BOOKMARK_TEXT, &label_color); | |
| 876 SetThemeColorFromGtk(ThemeProperties::COLOR_STATUS_BAR_TEXT, &label_color); | |
| 877 | 757 |
| 878 UpdateDefaultFont(label_style->font_desc); | 758 UpdateDefaultFont(); |
| 879 | 759 |
| 880 // Build the various icon tints. | 760 // Build the various icon tints. |
| 881 GetNormalButtonTintHSL(&button_tint_); | 761 GetNormalButtonTintHSL(&button_tint_); |
| 882 GetNormalEntryForegroundHSL(&entry_tint_); | 762 GetNormalEntryForegroundHSL(&entry_tint_); |
| 883 GetSelectedEntryForegroundHSL(&selected_entry_tint_); | 763 GetSelectedEntryForegroundHSL(&selected_entry_tint_); |
| 884 GdkColor frame_color = BuildFrameColors(frame_style); | 764 SkColor frame_color = BuildFrameColors(); |
| 885 | 765 |
| 886 // The inactive frame color never occurs naturally in the theme, as it is a | 766 // The inactive frame color never occurs naturally in the theme, as it is a |
| 887 // tinted version of |frame_color|. We generate another color based on the | 767 // tinted version of |frame_color|. We generate another color based on the |
| 888 // background tab color, with the lightness and saturation moved in the | 768 // background tab color, with the lightness and saturation moved in the |
| 889 // opposite direction. (We don't touch the hue, since there should be subtle | 769 // opposite direction. (We don't touch the hue, since there should be subtle |
| 890 // hints of the color in the text.) | 770 // hints of the color in the text.) |
| 891 color_utils::HSL inactive_tab_text_hsl = | 771 color_utils::HSL inactive_tab_text_hsl = |
| 892 tints_[ThemeProperties::TINT_BACKGROUND_TAB]; | 772 tints_[ThemeProperties::TINT_BACKGROUND_TAB]; |
| 893 if (inactive_tab_text_hsl.l < 0.5) | 773 if (inactive_tab_text_hsl.l < 0.5) |
| 894 inactive_tab_text_hsl.l = kDarkInactiveLuminance; | 774 inactive_tab_text_hsl.l = kDarkInactiveLuminance; |
| 895 else | 775 else |
| 896 inactive_tab_text_hsl.l = kLightInactiveLuminance; | 776 inactive_tab_text_hsl.l = kLightInactiveLuminance; |
| 897 | 777 |
| 898 if (inactive_tab_text_hsl.s < 0.5) | 778 if (inactive_tab_text_hsl.s < 0.5) |
| 899 inactive_tab_text_hsl.s = kHeavyInactiveSaturation; | 779 inactive_tab_text_hsl.s = kHeavyInactiveSaturation; |
| 900 else | 780 else |
| 901 inactive_tab_text_hsl.s = kLightInactiveSaturation; | 781 inactive_tab_text_hsl.s = kLightInactiveSaturation; |
| 902 | 782 |
| 903 colors_[ThemeProperties::COLOR_BACKGROUND_TAB_TEXT] = | 783 colors_[ThemeProperties::COLOR_BACKGROUND_TAB_TEXT] = |
| 904 color_utils::HSLToSkColor(inactive_tab_text_hsl, 255); | 784 color_utils::HSLToSkColor(inactive_tab_text_hsl, 255); |
| 905 | 785 |
| 906 // We pick the text and background colors for the NTP out of the colors for a | 786 // We pick the text and background colors for the NTP out of the colors for a |
| 907 // GtkEntry. We do this because GtkEntries background color is never the same | 787 // GtkEntry. We do this because GtkEntries background color is never the same |
| 908 // as |toolbar_color|, is usually a white, and when it isn't a white, | 788 // as |toolbar_color|, is usually a white, and when it isn't a white, |
| 909 // provides sufficient contrast to |toolbar_color|. Try this out with | 789 // provides sufficient contrast to |toolbar_color|. Try this out with |
| 910 // Darklooks, HighContrastInverse or ThinIce. | 790 // Darklooks, HighContrastInverse or ThinIce. |
| 911 GtkStyle* entry_style = gtk_rc_get_style(fake_entry_.get()); | 791 |
| 912 GdkColor ntp_background = entry_style->base[GTK_STATE_NORMAL]; | 792 SkColor ntp_background = |
| 913 GdkColor ntp_foreground = entry_style->text[GTK_STATE_NORMAL]; | 793 theme->GetSystemColor(ui::NativeTheme::kColorId_TextfieldDefaultBackground ); |
| 914 SetThemeColorFromGtk(ThemeProperties::COLOR_NTP_BACKGROUND, | 794 SkColor ntp_foreground = |
| 915 &ntp_background); | 795 theme->GetSystemColor(ui::NativeTheme::kColorId_TextfieldDefaultColor); |
| 916 SetThemeColorFromGtk(ThemeProperties::COLOR_NTP_TEXT, | 796 |
| 917 &ntp_foreground); | 797 colors_[ThemeProperties::COLOR_NTP_BACKGROUND] = ntp_background; |
| 798 colors_[ThemeProperties::COLOR_NTP_TEXT] = ntp_foreground; | |
| 918 | 799 |
| 919 // The NTP header is the color that surrounds the current active thumbnail on | 800 // The NTP header is the color that surrounds the current active thumbnail on |
| 920 // the NTP, and acts as the border of the "Recent Links" box. It would be | 801 // the NTP, and acts as the border of the "Recent Links" box. It would be |
| 921 // awesome if they were separated so we could use GetBorderColor() for the | 802 // awesome if they were separated so we could use GetBorderColor() for the |
| 922 // border around the "Recent Links" section, but matching the frame color is | 803 // border around the "Recent Links" section, but matching the frame color is |
| 923 // more important. | 804 // more important. |
| 924 SetThemeColorFromGtk(ThemeProperties::COLOR_NTP_HEADER, | |
| 925 &frame_color); | |
| 926 SetThemeColorFromGtk(ThemeProperties::COLOR_NTP_SECTION, | |
| 927 &toolbar_color); | |
| 928 SetThemeColorFromGtk(ThemeProperties::COLOR_NTP_SECTION_TEXT, | |
| 929 &label_color); | |
| 930 | 805 |
| 931 // Override the link color if the theme provides it. | 806 colors_[ThemeProperties::COLOR_NTP_HEADER] = frame_color; |
| 932 const GdkColor* link_color = NULL; | 807 colors_[ThemeProperties::COLOR_NTP_SECTION] = toolbar_color; |
| 933 gtk_widget_style_get(GTK_WIDGET(fake_window_), | 808 colors_[ThemeProperties::COLOR_NTP_SECTION_TEXT] = label_color; |
| 934 "link-color", &link_color, NULL); | |
| 935 | 809 |
| 936 bool is_default_link_color = false; | 810 // Default link color, taken from gtklinkbutton.c. |
| 937 if (!link_color) { | 811 SkColor link_color = SkColorSetRGB(0, 0, 0xee); |
| 938 link_color = &kDefaultLinkColor; | 812 GetChromeStyleColor("link-color", &link_color); |
| 939 is_default_link_color = true; | |
| 940 } | |
| 941 | 813 |
| 942 SetThemeColorFromGtk(ThemeProperties::COLOR_NTP_LINK, | 814 colors_[ThemeProperties::COLOR_NTP_LINK] = link_color; |
| 943 link_color); | 815 colors_[ThemeProperties::COLOR_NTP_LINK_UNDERLINE] = link_color; |
| 944 SetThemeColorFromGtk(ThemeProperties::COLOR_NTP_LINK_UNDERLINE, | 816 colors_[ThemeProperties::COLOR_NTP_SECTION_LINK] = link_color; |
| 945 link_color); | 817 colors_[ThemeProperties::COLOR_NTP_SECTION_LINK_UNDERLINE] = link_color; |
| 946 SetThemeColorFromGtk(ThemeProperties::COLOR_NTP_SECTION_LINK, | |
| 947 link_color); | |
| 948 SetThemeColorFromGtk(ThemeProperties::COLOR_NTP_SECTION_LINK_UNDERLINE, | |
| 949 link_color); | |
| 950 | |
| 951 if (!is_default_link_color) | |
| 952 gdk_color_free(const_cast<GdkColor*>(link_color)); | |
| 953 | 818 |
| 954 // Generate the colors that we pass to WebKit. | 819 // Generate the colors that we pass to WebKit. |
| 955 focus_ring_color_ = GdkColorToSkColor(frame_color); | 820 focus_ring_color_ = frame_color; |
| 956 | 821 |
| 957 GdkColor thumb_active_color, thumb_inactive_color, track_color; | 822 SetScrollbarColors(); |
| 958 Gtk2UI::GetScrollbarColors(&thumb_active_color, | |
| 959 &thumb_inactive_color, | |
| 960 &track_color); | |
| 961 thumb_active_color_ = GdkColorToSkColor(thumb_active_color); | |
| 962 thumb_inactive_color_ = GdkColorToSkColor(thumb_inactive_color); | |
| 963 track_color_ = GdkColorToSkColor(track_color); | |
| 964 | 823 |
| 965 // Some GTK themes only define the text selection colors on the GtkEntry | 824 // Some GTK themes only define the text selection colors on the GtkEntry |
| 966 // class, so we need to use that for getting selection colors. | 825 // class, so we need to use that for getting selection colors. |
| 967 active_selection_bg_color_ = | 826 active_selection_bg_color_ = |
| 968 GdkColorToSkColor(entry_style->base[GTK_STATE_SELECTED]); | 827 theme->GetSystemColor(ui::NativeTheme::kColorId_TextfieldSelectionBackgrou ndFocused); |
| 969 active_selection_fg_color_ = | 828 active_selection_fg_color_ = |
| 970 GdkColorToSkColor(entry_style->text[GTK_STATE_SELECTED]); | 829 theme->GetSystemColor(ui::NativeTheme::kColorId_TextfieldSelectionColor); |
| 971 inactive_selection_bg_color_ = | 830 inactive_selection_bg_color_ = |
| 972 GdkColorToSkColor(entry_style->base[GTK_STATE_ACTIVE]); | 831 theme->GetSystemColor(ui::NativeTheme::kColorId_TextfieldReadOnlyBackgroun d); |
| 973 inactive_selection_fg_color_ = | 832 inactive_selection_fg_color_ = |
| 974 GdkColorToSkColor(entry_style->text[GTK_STATE_ACTIVE]); | 833 theme->GetSystemColor(ui::NativeTheme::kColorId_TextfieldReadOnlyColor); |
| 975 | 834 |
| 976 colors_[ThemeProperties::COLOR_THROBBER_SPINNING] = | 835 colors_[ThemeProperties::COLOR_THROBBER_SPINNING] = |
| 977 NativeThemeGtk2::instance()->GetSystemColor( | 836 theme->GetSystemColor(ui::NativeTheme::kColorId_ThrobberSpinningColor); |
| 978 ui::NativeTheme::kColorId_ThrobberSpinningColor); | |
| 979 colors_[ThemeProperties::COLOR_THROBBER_WAITING] = | 837 colors_[ThemeProperties::COLOR_THROBBER_WAITING] = |
| 980 NativeThemeGtk2::instance()->GetSystemColor( | 838 theme->GetSystemColor(ui::NativeTheme::kColorId_ThrobberWaitingColor); |
| 981 ui::NativeTheme::kColorId_ThrobberWaitingColor); | |
| 982 } | 839 } |
| 983 | 840 |
| 984 GdkColor Gtk2UI::BuildFrameColors(GtkStyle* frame_style) { | 841 SkColor Gtk2UI::BuildFrameColors() { |
| 985 GdkColor* theme_frame = NULL; | 842 SkColor frame_color = |
| 986 GdkColor* theme_inactive_frame = NULL; | 843 NativeThemeGtk2::instance()->GetSystemColor( |
| 987 GdkColor* theme_incognito_frame = NULL; | 844 ui::NativeTheme::kColorId_WindowBackground); |
| 988 GdkColor* theme_incognito_inactive_frame = NULL; | 845 SkColor temp_color; |
| 989 gtk_widget_style_get(GTK_WIDGET(fake_frame_), | 846 SetThemeTint(ThemeProperties::TINT_BACKGROUND_TAB, frame_color); |
| 990 "frame-color", &theme_frame, | |
| 991 "inactive-frame-color", &theme_inactive_frame, | |
| 992 "incognito-frame-color", &theme_incognito_frame, | |
| 993 "incognito-inactive-frame-color", | |
| 994 &theme_incognito_inactive_frame, | |
| 995 NULL); | |
| 996 | 847 |
| 997 GdkColor frame_color = BuildAndSetFrameColor( | |
| 998 &frame_style->bg[GTK_STATE_SELECTED], | |
| 999 theme_frame, | |
| 1000 kDefaultFrameShift, | |
| 1001 ThemeProperties::COLOR_FRAME, | |
| 1002 ThemeProperties::TINT_FRAME); | |
| 1003 if (theme_frame) | |
| 1004 gdk_color_free(theme_frame); | |
| 1005 SetThemeTintFromGtk(ThemeProperties::TINT_BACKGROUND_TAB, &frame_color); | |
| 1006 | 848 |
| 1007 BuildAndSetFrameColor( | 849 temp_color = color_utils::HSLShift( |
| 1008 &frame_style->bg[GTK_STATE_INSENSITIVE], | 850 frame_color, |
| 1009 theme_inactive_frame, | 851 GetDefaultTint(ThemeProperties::TINT_FRAME)); |
| 1010 kDefaultFrameShift, | 852 GetChromeStyleColor("frame-color", &temp_color); |
| 1011 ThemeProperties::COLOR_FRAME_INACTIVE, | |
| 1012 ThemeProperties::TINT_FRAME_INACTIVE); | |
| 1013 if (theme_inactive_frame) | |
| 1014 gdk_color_free(theme_inactive_frame); | |
| 1015 | 853 |
| 1016 BuildAndSetFrameColor( | 854 colors_[ThemeProperties::COLOR_FRAME] = temp_color; |
| 1017 &frame_color, | 855 SetThemeTint(ThemeProperties::TINT_FRAME, temp_color); |
| 1018 theme_incognito_frame, | |
| 1019 GetDefaultTint(ThemeProperties::TINT_FRAME_INCOGNITO), | |
| 1020 ThemeProperties::COLOR_FRAME_INCOGNITO, | |
| 1021 ThemeProperties::TINT_FRAME_INCOGNITO); | |
| 1022 if (theme_incognito_frame) | |
| 1023 gdk_color_free(theme_incognito_frame); | |
| 1024 | 856 |
| 1025 BuildAndSetFrameColor( | 857 |
| 1026 &frame_color, | 858 temp_color = color_utils::HSLShift( |
| 1027 theme_incognito_inactive_frame, | 859 frame_color, |
| 1028 GetDefaultTint(ThemeProperties::TINT_FRAME_INCOGNITO_INACTIVE), | 860 GetDefaultTint(ThemeProperties::TINT_FRAME_INACTIVE)); |
| 1029 ThemeProperties::COLOR_FRAME_INCOGNITO_INACTIVE, | 861 GetChromeStyleColor("inactive-frame-color", &temp_color); |
| 1030 ThemeProperties::TINT_FRAME_INCOGNITO_INACTIVE); | 862 |
| 1031 if (theme_incognito_inactive_frame) | 863 colors_[ThemeProperties::COLOR_FRAME_INACTIVE] = temp_color; |
| 1032 gdk_color_free(theme_incognito_inactive_frame); | 864 SetThemeTint(ThemeProperties::TINT_FRAME_INACTIVE, temp_color); |
| 865 | |
| 866 | |
| 867 temp_color = color_utils::HSLShift( | |
| 868 frame_color, | |
| 869 GetDefaultTint(ThemeProperties::TINT_FRAME_INCOGNITO)); | |
| 870 GetChromeStyleColor("incognito-frame-color", &temp_color); | |
| 871 | |
| 872 colors_[ThemeProperties::COLOR_FRAME_INCOGNITO] = temp_color; | |
| 873 SetThemeTint(ThemeProperties::TINT_FRAME_INCOGNITO, temp_color); | |
| 874 | |
| 875 | |
| 876 temp_color = color_utils::HSLShift( | |
| 877 frame_color, | |
| 878 GetDefaultTint(ThemeProperties::TINT_FRAME_INCOGNITO_INACTIVE)); | |
| 879 GetChromeStyleColor("incognito-inactive-frame-color", &temp_color); | |
| 880 | |
| 881 colors_[ThemeProperties::COLOR_FRAME_INCOGNITO_INACTIVE] = temp_color; | |
| 882 SetThemeTint(ThemeProperties::TINT_FRAME_INCOGNITO_INACTIVE, temp_color); | |
| 883 | |
| 1033 | 884 |
| 1034 return frame_color; | 885 return frame_color; |
| 1035 } | 886 } |
| 1036 | 887 |
| 1037 void Gtk2UI::SetThemeColorFromGtk(int id, const GdkColor* color) { | 888 void Gtk2UI::SetThemeTint(int id, SkColor color) { |
| 1038 colors_[id] = GdkColorToSkColor(*color); | |
| 1039 } | |
| 1040 | |
| 1041 void Gtk2UI::SetThemeTintFromGtk(int id, const GdkColor* color) { | |
| 1042 color_utils::HSL default_tint = GetDefaultTint(id); | 889 color_utils::HSL default_tint = GetDefaultTint(id); |
| 1043 color_utils::HSL hsl; | 890 color_utils::HSL hsl; |
| 1044 color_utils::SkColorToHSL(GdkColorToSkColor(*color), &hsl); | 891 color_utils::SkColorToHSL(color, &hsl); |
| 1045 | 892 |
| 1046 if (default_tint.s != -1) | 893 if (default_tint.s != -1) |
| 1047 hsl.s = default_tint.s; | 894 hsl.s = default_tint.s; |
| 1048 | 895 |
| 1049 if (default_tint.l != -1) | 896 if (default_tint.l != -1) |
| 1050 hsl.l = default_tint.l; | 897 hsl.l = default_tint.l; |
| 1051 | 898 |
| 1052 tints_[id] = hsl; | 899 tints_[id] = hsl; |
| 1053 } | 900 } |
| 1054 | 901 |
| 1055 GdkColor Gtk2UI::BuildAndSetFrameColor(const GdkColor* base, | |
| 1056 const GdkColor* gtk_base, | |
| 1057 const color_utils::HSL& tint, | |
| 1058 int color_id, | |
| 1059 int tint_id) { | |
| 1060 GdkColor out_color = *base; | |
| 1061 if (gtk_base) { | |
| 1062 // The theme author specified a color to use, use it without modification. | |
| 1063 out_color = *gtk_base; | |
| 1064 } else { | |
| 1065 // Tint the basic color since this is a heuristic color instead of one | |
| 1066 // specified by the theme author. | |
| 1067 GdkColorHSLShift(tint, &out_color); | |
| 1068 } | |
| 1069 SetThemeColorFromGtk(color_id, &out_color); | |
| 1070 SetThemeTintFromGtk(tint_id, &out_color); | |
| 1071 | |
| 1072 return out_color; | |
| 1073 } | |
| 1074 | |
| 1075 SkBitmap Gtk2UI::GenerateGtkThemeBitmap(int id) const { | 902 SkBitmap Gtk2UI::GenerateGtkThemeBitmap(int id) const { |
| 1076 switch (id) { | 903 switch (id) { |
| 1077 case IDR_THEME_TOOLBAR: { | 904 case IDR_THEME_TOOLBAR: { |
| 1078 GtkStyle* style = gtk_rc_get_style(fake_window_); | |
| 1079 GdkColor* color = &style->bg[GTK_STATE_NORMAL]; | |
| 1080 SkBitmap bitmap; | 905 SkBitmap bitmap; |
| 1081 bitmap.allocN32Pixels(kToolbarImageWidth, kToolbarImageHeight); | 906 bitmap.allocN32Pixels(kToolbarImageWidth, kToolbarImageHeight); |
| 1082 bitmap.eraseARGB(0xff, color->red >> 8, color->green >> 8, | 907 bitmap.eraseColor( |
| 1083 color->blue >> 8); | 908 NativeThemeGtk2::instance()->GetSystemColor( |
| 909 ui::NativeTheme::kColorId_WindowBackground)); | |
| 1084 return bitmap; | 910 return bitmap; |
| 1085 } | 911 } |
| 1086 case IDR_THEME_TAB_BACKGROUND: | 912 case IDR_THEME_TAB_BACKGROUND: |
| 1087 case IDR_THEME_TAB_BACKGROUND_DESKTOP: | 913 case IDR_THEME_TAB_BACKGROUND_DESKTOP: |
| 1088 return GenerateTabImage(IDR_THEME_FRAME); | 914 return GenerateTabImage(IDR_THEME_FRAME); |
| 1089 case IDR_THEME_TAB_BACKGROUND_INCOGNITO: | 915 case IDR_THEME_TAB_BACKGROUND_INCOGNITO: |
| 1090 case IDR_THEME_TAB_BACKGROUND_INCOGNITO_DESKTOP: | 916 case IDR_THEME_TAB_BACKGROUND_INCOGNITO_DESKTOP: |
| 1091 return GenerateTabImage(IDR_THEME_FRAME_INCOGNITO); | 917 return GenerateTabImage(IDR_THEME_FRAME_INCOGNITO); |
| 1092 case IDR_FRAME: | 918 case IDR_FRAME: |
| 1093 case IDR_THEME_FRAME: | 919 case IDR_THEME_FRAME: |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1136 case IDR_FORWARD: | 962 case IDR_FORWARD: |
| 1137 case IDR_FORWARD_D: | 963 case IDR_FORWARD_D: |
| 1138 case IDR_HOME: | 964 case IDR_HOME: |
| 1139 case IDR_RELOAD: | 965 case IDR_RELOAD: |
| 1140 case IDR_RELOAD_D: | 966 case IDR_RELOAD_D: |
| 1141 case IDR_STOP: | 967 case IDR_STOP: |
| 1142 case IDR_STOP_D: { | 968 case IDR_STOP_D: { |
| 1143 return GenerateGTKIcon(id); | 969 return GenerateGTKIcon(id); |
| 1144 } | 970 } |
| 1145 case IDR_TOOLBAR_BEZEL_HOVER: | 971 case IDR_TOOLBAR_BEZEL_HOVER: |
| 1146 return GenerateToolbarBezel(GTK_STATE_PRELIGHT, IDR_TOOLBAR_BEZEL_HOVER); | 972 return GenerateToolbarBezel(ui::NativeTheme::kHovered, IDR_TOOLBAR_BEZEL_H OVER); |
| 1147 case IDR_TOOLBAR_BEZEL_PRESSED: | 973 case IDR_TOOLBAR_BEZEL_PRESSED: |
| 1148 return GenerateToolbarBezel(GTK_STATE_ACTIVE, IDR_TOOLBAR_BEZEL_PRESSED); | 974 return GenerateToolbarBezel(ui::NativeTheme::kPressed, IDR_TOOLBAR_BEZEL_P RESSED); |
| 1149 default: { | 975 default: { |
| 1150 return GenerateTintedIcon(id, button_tint_); | 976 return GenerateTintedIcon(id, button_tint_); |
| 1151 } | 977 } |
| 1152 } | 978 } |
| 1153 | 979 |
| 1154 return SkBitmap(); | 980 return SkBitmap(); |
| 1155 } | 981 } |
| 1156 | 982 |
| 1157 SkBitmap Gtk2UI::GenerateFrameImage( | 983 SkBitmap Gtk2UI::GenerateFrameImage( |
| 1158 int color_id, | 984 int color_id, |
| 1159 const char* gradient_name) const { | 985 const char* gradient_name) const { |
| 1160 // We use two colors: the main color (passed in) and a lightened version of | |
| 1161 // that color (which is supposed to match the light gradient at the top of | |
| 1162 // several GTK+ themes, such as Ambiance, Clearlooks or Bluebird). | |
| 1163 ColorMap::const_iterator it = colors_.find(color_id); | 986 ColorMap::const_iterator it = colors_.find(color_id); |
| 1164 DCHECK(it != colors_.end()); | 987 DCHECK(it != colors_.end()); |
| 1165 SkColor base = it->second; | 988 SkColor base = it->second; |
| 1166 | 989 |
| 990 | |
| 991 #if GTK_MAJOR_VERSION == 2 | |
| 992 // We use two colors: the main color (passed in) and a lightened version of | |
| 993 // that color (which is supposed to match the light gradient at the top of | |
| 994 // several GTK+ themes, such as Ambiance, Clearlooks or Bluebird). | |
| 995 const color_utils::HSL kGtkFrameShift = { -1, -1, 0.8 }; | |
| 1167 gfx::Canvas canvas(gfx::Size(kToolbarImageWidth, kToolbarImageHeight), | 996 gfx::Canvas canvas(gfx::Size(kToolbarImageWidth, kToolbarImageHeight), |
| 1168 1.0f, true); | 997 1.0f, true); |
| 1169 | 998 |
| 999 SkColor gradient_top_color = color_utils::HSLShift(base, kGtkFrameShift); | |
| 1170 int gradient_size; | 1000 int gradient_size; |
| 1171 GdkColor* gradient_top_color = NULL; | 1001 |
| 1172 gtk_widget_style_get(GTK_WIDGET(fake_frame_), | 1002 GetChromeStyleColor(gradient_name, &gradient_top_color); |
| 1003 gtk_widget_style_get(NativeThemeGtk2::instance()->GetWindow(), | |
| 1173 "frame-gradient-size", &gradient_size, | 1004 "frame-gradient-size", &gradient_size, |
| 1174 gradient_name, &gradient_top_color, | |
| 1175 NULL); | 1005 NULL); |
| 1006 | |
| 1176 if (gradient_size) { | 1007 if (gradient_size) { |
| 1177 SkColor lighter = gradient_top_color ? | |
| 1178 GdkColorToSkColor(*gradient_top_color) : | |
| 1179 color_utils::HSLShift(base, kGtkFrameShift); | |
| 1180 skia::RefPtr<SkShader> shader = gfx::CreateGradientShader( | 1008 skia::RefPtr<SkShader> shader = gfx::CreateGradientShader( |
| 1181 0, gradient_size, lighter, base); | 1009 0, gradient_size, gradient_top_color, base); |
| 1182 SkPaint paint; | 1010 SkPaint paint; |
| 1183 paint.setStyle(SkPaint::kFill_Style); | 1011 paint.setStyle(SkPaint::kFill_Style); |
| 1184 paint.setAntiAlias(true); | 1012 paint.setAntiAlias(true); |
| 1185 paint.setShader(shader.get()); | 1013 paint.setShader(shader.get()); |
| 1186 | 1014 |
| 1187 canvas.DrawRect(gfx::Rect(0, 0, kToolbarImageWidth, gradient_size), paint); | 1015 canvas.DrawRect(gfx::Rect(0, 0, kToolbarImageWidth, gradient_size), paint); |
| 1188 } | 1016 } |
| 1189 | 1017 |
| 1190 if (gradient_top_color) | |
| 1191 gdk_color_free(gradient_top_color); | |
| 1192 | |
| 1193 canvas.FillRect(gfx::Rect(0, gradient_size, kToolbarImageWidth, | 1018 canvas.FillRect(gfx::Rect(0, gradient_size, kToolbarImageWidth, |
| 1194 kToolbarImageHeight - gradient_size), base); | 1019 kToolbarImageHeight - gradient_size), base); |
| 1195 return canvas.ExtractImageRep().sk_bitmap(); | 1020 return canvas.ExtractImageRep().sk_bitmap(); |
| 1021 | |
| 1022 #else | |
|
knthzh
2015/08/24 03:58:18
So, I ended up deciding that the best way to rende
Elliot Glaysher
2015/08/24 17:14:38
Probably not. You should still be able to do by re
knthzh
2015/08/24 20:04:18
Wait, huh?
Elliot Glaysher
2015/08/24 20:14:23
I should not be allowed to write anything before m
| |
| 1023 // Render a GtkHeaderBar as our title bar, cropping out any curved edges on | |
| 1024 // the left and right sides. Also remove the bottom border for good measure. | |
| 1025 SkBitmap bitmap; | |
| 1026 bitmap.allocN32Pixels(kToolbarImageWidth, kToolbarImageHeight); | |
| 1027 bitmap.eraseColor(base); | |
| 1028 | |
| 1029 | |
| 1030 static GtkWidget* title = NULL; | |
| 1031 if (!title) { | |
| 1032 title = gtk_header_bar_new(); | |
| 1033 gtk_widget_set_size_request(title, kToolbarImageWidth * 2, 48); | |
| 1034 | |
| 1035 GtkWidget* window = gtk_offscreen_window_new(); | |
| 1036 gtk_container_add(GTK_CONTAINER(window), title); | |
| 1037 | |
| 1038 gtk_widget_show_all(window); | |
| 1039 } | |
| 1040 | |
| 1041 cairo_surface_t* surface = cairo_image_surface_create_for_data( | |
| 1042 static_cast<unsigned char*>(bitmap.getAddr(0, 0)), | |
| 1043 CAIRO_FORMAT_ARGB32, | |
| 1044 kToolbarImageWidth, 40, | |
| 1045 kToolbarImageWidth * 4); | |
| 1046 cairo_t* cr = cairo_create(surface); | |
| 1047 cairo_translate(cr, kToolbarImageWidth / -2, 0); | |
| 1048 gtk_widget_draw(title, cr); | |
| 1049 cairo_destroy(cr); | |
| 1050 cairo_surface_destroy(surface); | |
| 1051 | |
| 1052 | |
| 1053 return bitmap; | |
| 1054 #endif | |
| 1196 } | 1055 } |
| 1197 | 1056 |
| 1198 SkBitmap Gtk2UI::GenerateTabImage(int base_id) const { | 1057 SkBitmap Gtk2UI::GenerateTabImage(int base_id) const { |
| 1199 const SkBitmap* base_image = GetThemeImageNamed(base_id).ToSkBitmap(); | 1058 const SkBitmap* base_image = GetThemeImageNamed(base_id).ToSkBitmap(); |
| 1200 SkBitmap bg_tint = SkBitmapOperations::CreateHSLShiftedBitmap( | 1059 SkBitmap bg_tint = SkBitmapOperations::CreateHSLShiftedBitmap( |
| 1201 *base_image, GetDefaultTint(ThemeProperties::TINT_BACKGROUND_TAB)); | 1060 *base_image, GetDefaultTint(ThemeProperties::TINT_BACKGROUND_TAB)); |
| 1202 return SkBitmapOperations::CreateTiledBitmap( | 1061 return SkBitmapOperations::CreateTiledBitmap( |
| 1203 bg_tint, 0, 0, bg_tint.width(), bg_tint.height()); | 1062 bg_tint, 0, 0, bg_tint.width(), bg_tint.height()); |
| 1204 } | 1063 } |
| 1205 | 1064 |
| 1206 SkBitmap Gtk2UI::GenerateTintedIcon( | 1065 SkBitmap Gtk2UI::GenerateTintedIcon( |
| 1207 int base_id, | 1066 int base_id, |
| 1208 const color_utils::HSL& tint) const { | 1067 const color_utils::HSL& tint) const { |
| 1209 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | 1068 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); |
| 1210 return SkBitmapOperations::CreateHSLShiftedBitmap( | 1069 return SkBitmapOperations::CreateHSLShiftedBitmap( |
| 1211 rb.GetImageNamed(base_id).AsBitmap(), tint); | 1070 rb.GetImageNamed(base_id).AsBitmap(), tint); |
| 1212 } | 1071 } |
| 1213 | 1072 |
| 1214 SkBitmap Gtk2UI::GenerateGTKIcon(int base_id) const { | 1073 SkBitmap Gtk2UI::GenerateGTKIcon(int base_id) const { |
| 1215 const char* stock_id = NULL; | 1074 const char* stock_id = NULL; |
| 1216 GtkStateType gtk_state = GTK_STATE_NORMAL; | 1075 bool enabled = true; |
| 1217 for (unsigned int i = 0; i < arraysize(kGtkIcons); ++i) { | 1076 for (unsigned int i = 0; i < arraysize(kGtkIcons); ++i) { |
| 1218 if (kGtkIcons[i].idr == base_id) { | 1077 if (kGtkIcons[i].idr == base_id) { |
| 1219 stock_id = kGtkIcons[i].stock_id; | 1078 stock_id = kGtkIcons[i].stock_id; |
| 1220 gtk_state = kGtkIcons[i].gtk_state; | 1079 enabled = kGtkIcons[i].enabled; |
| 1221 break; | 1080 break; |
| 1222 } | 1081 } |
| 1223 } | 1082 } |
| 1224 DCHECK(stock_id); | 1083 DCHECK(stock_id); |
| 1225 | 1084 |
| 1226 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | 1085 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); |
| 1227 SkBitmap default_bitmap = rb.GetImageNamed(base_id).AsBitmap(); | 1086 SkBitmap default_bitmap = rb.GetImageNamed(base_id).AsBitmap(); |
| 1228 | 1087 |
| 1229 gtk_widget_ensure_style(fake_frame_); | |
| 1230 GtkStyle* style = gtk_widget_get_style(fake_frame_); | |
| 1231 GtkIconSet* icon_set = gtk_style_lookup_icon_set(style, stock_id); | |
| 1232 if (!icon_set) | |
| 1233 return default_bitmap; | |
| 1234 | |
| 1235 // Ask GTK to render the icon to a buffer, which we will steal from. | 1088 // Ask GTK to render the icon to a buffer, which we will steal from. |
| 1236 GdkPixbuf* gdk_icon = gtk_icon_set_render_icon( | 1089 GtkIconTheme* icon_theme = gtk_icon_theme_get_default(); |
| 1237 icon_set, | 1090 GdkPixbuf* gdk_icon = gtk_icon_theme_load_icon( |
| 1238 style, | 1091 icon_theme, |
| 1239 base::i18n::IsRTL() ? GTK_TEXT_DIR_RTL : GTK_TEXT_DIR_LTR, | 1092 stock_id, |
| 1240 gtk_state, | 1093 16, |
| 1241 GTK_ICON_SIZE_SMALL_TOOLBAR, | 1094 (GtkIconLookupFlags)0, |
| 1242 fake_frame_, | |
| 1243 NULL); | 1095 NULL); |
| 1244 | 1096 |
| 1245 if (!gdk_icon) { | 1097 if (!gdk_icon) { |
| 1246 // This can theoretically happen if an icon theme doesn't provide a | 1098 // This can theoretically happen if an icon theme doesn't provide a |
| 1247 // specific image. This should realistically never happen, but I bet there | 1099 // specific image. This should realistically never happen, but I bet there |
| 1248 // are some theme authors who don't reliably provide all icons. | 1100 // are some theme authors who don't reliably provide all icons. |
| 1249 return default_bitmap; | 1101 return default_bitmap; |
| 1250 } | 1102 } |
| 1251 | 1103 |
| 1252 SkBitmap retval; | 1104 SkBitmap retval; |
| 1253 retval.allocN32Pixels(default_bitmap.width(), default_bitmap.height()); | 1105 retval.allocN32Pixels(default_bitmap.width(), default_bitmap.height()); |
| 1254 retval.eraseColor(0); | 1106 retval.eraseColor(0); |
| 1255 | 1107 |
| 1256 const SkBitmap icon = GdkPixbufToImageSkia(gdk_icon); | 1108 const SkBitmap icon = GdkPixbufToImageSkia(gdk_icon); |
| 1257 g_object_unref(gdk_icon); | 1109 g_object_unref(gdk_icon); |
| 1258 | 1110 |
| 1259 SkCanvas canvas(retval); | 1111 SkCanvas canvas(retval); |
| 1260 | 1112 |
| 1261 if (gtk_state == GTK_STATE_ACTIVE || gtk_state == GTK_STATE_PRELIGHT) { | 1113 SkPaint paint; |
| 1262 SkBitmap border = DrawGtkButtonBorder(gtk_state, | 1114 |
| 1263 false, | 1115 // GTK3 behavior |
| 1264 false, | 1116 if (!enabled) |
| 1265 default_bitmap.width(), | 1117 paint.setAlpha(128); |
| 1266 default_bitmap.height()); | |
| 1267 canvas.drawBitmap(border, 0, 0); | |
| 1268 } | |
| 1269 | 1118 |
| 1270 canvas.drawBitmap(icon, | 1119 canvas.drawBitmap(icon, |
| 1271 (default_bitmap.width() / 2) - (icon.width() / 2), | 1120 (default_bitmap.width() / 2) - (icon.width() / 2), |
| 1272 (default_bitmap.height() / 2) - (icon.height() / 2)); | 1121 (default_bitmap.height() / 2) - (icon.height() / 2), |
| 1122 &paint); | |
| 1273 | 1123 |
| 1274 return retval; | 1124 return retval; |
| 1275 } | 1125 } |
| 1276 | 1126 |
| 1277 SkBitmap Gtk2UI::GenerateToolbarBezel(int gtk_state, int sizing_idr) const { | 1127 SkBitmap Gtk2UI::GenerateToolbarBezel( |
| 1128 ui::NativeTheme::State state, | |
| 1129 int sizing_idr) const { | |
| 1278 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | 1130 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); |
| 1279 SkBitmap default_bitmap = | 1131 SkBitmap default_bitmap = |
| 1280 rb.GetImageNamed(sizing_idr).AsBitmap(); | 1132 rb.GetImageNamed(sizing_idr).AsBitmap(); |
| 1281 | 1133 |
| 1282 SkBitmap retval; | 1134 return DrawGtkButtonBorder( |
| 1283 retval.allocN32Pixels(default_bitmap.width(), default_bitmap.height()); | 1135 NULL, |
| 1284 retval.eraseColor(0); | 1136 state, |
| 1285 | |
| 1286 SkCanvas canvas(retval); | |
| 1287 SkBitmap border = DrawGtkButtonBorder( | |
| 1288 gtk_state, | |
| 1289 false, | |
| 1290 false, | |
| 1291 default_bitmap.width(), | 1137 default_bitmap.width(), |
| 1292 default_bitmap.height()); | 1138 default_bitmap.height()); |
| 1293 canvas.drawBitmap(border, 0, 0); | |
| 1294 | |
| 1295 return retval; | |
| 1296 } | 1139 } |
| 1297 | 1140 |
| 1298 void Gtk2UI::GetNormalButtonTintHSL(color_utils::HSL* tint) const { | 1141 void Gtk2UI::GetNormalButtonTintHSL(color_utils::HSL* tint) const { |
| 1299 GtkStyle* window_style = gtk_rc_get_style(fake_window_); | 1142 NativeThemeGtk2* theme = NativeThemeGtk2::instance(); |
| 1300 const GdkColor accent_gdk_color = window_style->bg[GTK_STATE_SELECTED]; | |
| 1301 const GdkColor base_color = window_style->base[GTK_STATE_NORMAL]; | |
| 1302 | 1143 |
| 1303 GtkStyle* label_style = gtk_rc_get_style(fake_label_.get()); | 1144 SkColor accent_color = |
| 1304 const GdkColor text_color = label_style->fg[GTK_STATE_NORMAL]; | 1145 theme->GetSystemColor(ui::NativeTheme::kColorId_ButtonHighlightColor); |
| 1146 SkColor text_color = | |
| 1147 theme->GetSystemColor(ui::NativeTheme::kColorId_LabelEnabledColor); | |
| 1148 SkColor base_color = | |
| 1149 theme->GetSystemColor(ui::NativeTheme::kColorId_LabelBackgroundColor); | |
| 1305 | 1150 |
| 1306 PickButtonTintFromColors(accent_gdk_color, text_color, base_color, tint); | 1151 PickButtonTintFromColors(accent_color, text_color, base_color, tint); |
| 1307 } | 1152 } |
| 1308 | 1153 |
| 1309 void Gtk2UI::GetNormalEntryForegroundHSL(color_utils::HSL* tint) const { | 1154 void Gtk2UI::GetNormalEntryForegroundHSL(color_utils::HSL* tint) const { |
| 1310 GtkStyle* window_style = gtk_rc_get_style(fake_window_); | 1155 NativeThemeGtk2* theme = NativeThemeGtk2::instance(); |
| 1311 const GdkColor accent_gdk_color = window_style->bg[GTK_STATE_SELECTED]; | |
| 1312 | 1156 |
| 1313 GtkStyle* style = gtk_rc_get_style(fake_entry_.get()); | 1157 SkColor accent_color = |
| 1314 const GdkColor text_color = style->text[GTK_STATE_NORMAL]; | 1158 theme->GetSystemColor(ui::NativeTheme::kColorId_ButtonHighlightColor); |
| 1315 const GdkColor base_color = style->base[GTK_STATE_NORMAL]; | 1159 SkColor text_color = |
| 1160 theme->GetSystemColor(ui::NativeTheme::kColorId_TextfieldDefaultColor); | |
| 1161 SkColor base_color = | |
| 1162 theme->GetSystemColor(ui::NativeTheme::kColorId_TextfieldDefaultBackground ); | |
| 1316 | 1163 |
| 1317 PickButtonTintFromColors(accent_gdk_color, text_color, base_color, tint); | 1164 PickButtonTintFromColors(accent_color, text_color, base_color, tint); |
| 1318 } | 1165 } |
| 1319 | 1166 |
| 1320 void Gtk2UI::GetSelectedEntryForegroundHSL(color_utils::HSL* tint) const { | 1167 void Gtk2UI::GetSelectedEntryForegroundHSL(color_utils::HSL* tint) const { |
| 1321 // The simplest of all the tints. We just use the selected text in the entry | 1168 // The simplest of all the tints. We just use the selected text in the entry |
| 1322 // since the icons tinted this way will only be displayed against | 1169 // since the icons tinted this way will only be displayed against |
| 1323 // base[GTK_STATE_SELECTED]. | 1170 // base[GTK_STATE_SELECTED]. |
| 1324 GtkStyle* style = gtk_rc_get_style(fake_entry_.get()); | 1171 SkColor color = |
| 1325 const GdkColor color = style->text[GTK_STATE_SELECTED]; | 1172 NativeThemeGtk2::instance()->GetSystemColor( |
| 1326 color_utils::SkColorToHSL(GdkColorToSkColor(color), tint); | 1173 ui::NativeTheme::kColorId_TextfieldSelectionColor); |
| 1174 | |
| 1175 color_utils::SkColorToHSL(color, tint); | |
| 1327 } | 1176 } |
| 1328 | 1177 |
| 1329 SkBitmap Gtk2UI::DrawGtkButtonBorder(int gtk_state, | 1178 SkBitmap Gtk2UI::DrawGtkButtonBorder(const char* class_name, |
| 1330 bool focused, | 1179 ui::NativeTheme::State state, |
| 1331 bool call_to_action, | |
| 1332 int width, | 1180 int width, |
| 1333 int height) const { | 1181 int height) const { |
| 1182 SkBitmap border; | |
| 1183 border.allocN32Pixels(width, height); | |
| 1184 border.eraseColor(0); | |
| 1185 | |
| 1334 // Create a temporary GTK button to snapshot | 1186 // Create a temporary GTK button to snapshot |
| 1335 GtkWidget* window = gtk_offscreen_window_new(); | 1187 GtkWidget* window = gtk_offscreen_window_new(); |
| 1336 GtkWidget* button = gtk_button_new(); | 1188 GtkWidget* button = gtk_toggle_button_new(); |
| 1189 | |
| 1190 if (state == ui::NativeTheme::kPressed) | |
| 1191 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), true); | |
| 1192 else if (state == ui::NativeTheme::kDisabled) | |
| 1193 gtk_widget_set_sensitive(button, false); | |
| 1194 | |
| 1337 gtk_widget_set_size_request(button, width, height); | 1195 gtk_widget_set_size_request(button, width, height); |
| 1338 gtk_container_add(GTK_CONTAINER(window), button); | 1196 gtk_container_add(GTK_CONTAINER(window), button); |
| 1339 gtk_widget_realize(window); | |
| 1340 gtk_widget_realize(button); | |
| 1341 gtk_widget_show(button); | |
| 1342 gtk_widget_show(window); | |
| 1343 | 1197 |
| 1344 if (call_to_action) | 1198 if (class_name == views::BlueButton::kViewClassName) { |
| 1345 GTK_WIDGET_SET_FLAGS(button, GTK_HAS_DEFAULT); | 1199 gtk_widget_set_can_default(button, true); |
| 1346 | 1200 gtk_widget_grab_default(button); |
| 1347 if (focused) { | |
| 1348 // We can't just use gtk_widget_grab_focus() here because that sets | |
| 1349 // gtk_widget_is_focus(), but not gtk_widget_has_focus(), which is what the | |
| 1350 // GtkButton's paint checks. | |
| 1351 GTK_WIDGET_SET_FLAGS(button, GTK_HAS_FOCUS); | |
| 1352 } | 1201 } |
| 1353 | 1202 |
| 1354 gtk_widget_set_state(button, static_cast<GtkStateType>(gtk_state)); | 1203 gtk_widget_show_all(window); |
| 1355 | 1204 |
| 1356 GdkPixmap* pixmap; | 1205 |
| 1357 { | 1206 cairo_surface_t* surface = cairo_image_surface_create_for_data( |
| 1358 // http://crbug.com/346740 | 1207 static_cast<unsigned char*>(border.getAddr(0, 0)), |
| 1359 ANNOTATE_SCOPED_MEMORY_LEAK; | 1208 CAIRO_FORMAT_ARGB32, |
| 1360 pixmap = gtk_widget_get_snapshot(button, NULL); | 1209 width, height, |
| 1361 } | 1210 width * 4); |
| 1211 cairo_t* cr = cairo_create(surface); | |
| 1212 | |
| 1213 #if GTK_MAJOR_VERSION == 2 | |
| 1362 int w, h; | 1214 int w, h; |
| 1215 GdkPixmap* pixmap = gtk_widget_get_snapshot(button, NULL); | |
| 1363 gdk_drawable_get_size(GDK_DRAWABLE(pixmap), &w, &h); | 1216 gdk_drawable_get_size(GDK_DRAWABLE(pixmap), &w, &h); |
| 1364 DCHECK_EQ(w, width); | |
| 1365 DCHECK_EQ(h, height); | |
| 1366 | |
| 1367 // We render the Pixmap to a Pixbuf. This can be slow, as we're scrapping | |
| 1368 // bits from X. | |
| 1369 GdkColormap* colormap = gdk_drawable_get_colormap(pixmap); | 1217 GdkColormap* colormap = gdk_drawable_get_colormap(pixmap); |
| 1370 GdkPixbuf* pixbuf = gdk_pixbuf_get_from_drawable(NULL, | 1218 GdkPixbuf* pixbuf = gdk_pixbuf_get_from_drawable(NULL, |
| 1371 GDK_DRAWABLE(pixmap), | 1219 GDK_DRAWABLE(pixmap), |
| 1372 colormap, | 1220 colormap, |
| 1373 0, 0, 0, 0, w, h); | 1221 0, 0, 0, 0, w, h); |
| 1374 | 1222 |
| 1375 // Finally, we convert our pixbuf into a type we can use. | 1223 gdk_cairo_set_source_pixbuf(cr, pixbuf, 0, 0); |
| 1376 SkBitmap border = GdkPixbufToImageSkia(pixbuf); | 1224 cairo_paint(cr); |
| 1225 | |
| 1377 g_object_unref(pixbuf); | 1226 g_object_unref(pixbuf); |
| 1378 g_object_unref(pixmap); | 1227 g_object_unref(pixmap); |
| 1228 #else | |
| 1229 gtk_widget_draw(button, cr); | |
| 1230 #endif | |
| 1231 | |
| 1232 cairo_destroy(cr); | |
| 1233 cairo_surface_destroy(surface); | |
| 1234 | |
| 1235 | |
| 1379 gtk_widget_destroy(window); | 1236 gtk_widget_destroy(window); |
| 1380 | 1237 |
| 1381 return border; | 1238 return border; |
| 1382 } | 1239 } |
| 1383 | 1240 |
| 1384 void Gtk2UI::ClearAllThemeData() { | 1241 void Gtk2UI::ClearAllThemeData() { |
| 1385 gtk_images_.clear(); | 1242 gtk_images_.clear(); |
| 1386 } | 1243 } |
| 1387 | 1244 |
| 1388 void Gtk2UI::UpdateDefaultFont(const PangoFontDescription* desc) { | 1245 void Gtk2UI::UpdateDefaultFont() { |
| 1246 GtkStyle* style = gtk_rc_get_style(NativeThemeGtk2::instance()->GetLabel()); | |
| 1247 const PangoFontDescription* desc = style->font_desc; | |
| 1248 | |
| 1389 // Use gfx::FontRenderParams to select a family and determine the rendering | 1249 // Use gfx::FontRenderParams to select a family and determine the rendering |
| 1390 // settings. | 1250 // settings. |
| 1391 gfx::FontRenderParamsQuery query; | 1251 gfx::FontRenderParamsQuery query; |
| 1392 query.families = base::SplitString(pango_font_description_get_family(desc), | 1252 query.families = base::SplitString(pango_font_description_get_family(desc), |
| 1393 ",", base::TRIM_WHITESPACE, | 1253 ",", base::TRIM_WHITESPACE, |
| 1394 base::SPLIT_WANT_ALL); | 1254 base::SPLIT_WANT_ALL); |
| 1395 | 1255 |
| 1396 if (pango_font_description_get_size_is_absolute(desc)) { | 1256 if (pango_font_description_get_size_is_absolute(desc)) { |
| 1397 // If the size is absolute, it's specified in Pango units. There are | 1257 // If the size is absolute, it's specified in Pango units. There are |
| 1398 // PANGO_SCALE Pango units in a device unit (pixel). | 1258 // PANGO_SCALE Pango units in a device unit (pixel). |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 1415 query.style |= gfx::Font::BOLD; | 1275 query.style |= gfx::Font::BOLD; |
| 1416 // TODO(davemoore): What about PANGO_STYLE_OBLIQUE? | 1276 // TODO(davemoore): What about PANGO_STYLE_OBLIQUE? |
| 1417 if (pango_font_description_get_style(desc) == PANGO_STYLE_ITALIC) | 1277 if (pango_font_description_get_style(desc) == PANGO_STYLE_ITALIC) |
| 1418 query.style |= gfx::Font::ITALIC; | 1278 query.style |= gfx::Font::ITALIC; |
| 1419 | 1279 |
| 1420 default_font_render_params_ = | 1280 default_font_render_params_ = |
| 1421 gfx::GetFontRenderParams(query, &default_font_family_); | 1281 gfx::GetFontRenderParams(query, &default_font_family_); |
| 1422 default_font_style_ = query.style; | 1282 default_font_style_ = query.style; |
| 1423 } | 1283 } |
| 1424 | 1284 |
| 1425 void Gtk2UI::OnStyleSet(GtkWidget* widget, GtkStyle* previous_style) { | 1285 void Gtk2UI::ResetStyle() { |
| 1426 ClearAllThemeData(); | 1286 ClearAllThemeData(); |
| 1427 LoadGtkValues(); | 1287 LoadGtkValues(); |
| 1428 NativeThemeGtk2::instance()->NotifyObservers(); | 1288 NativeThemeGtk2::instance()->NotifyObservers(); |
| 1429 } | 1289 } |
| 1430 | 1290 |
| 1431 void Gtk2UI::UpdateDeviceScaleFactor(float device_scale_factor) { | 1291 void Gtk2UI::UpdateDeviceScaleFactor(float device_scale_factor) { |
| 1432 device_scale_factor_ = device_scale_factor; | 1292 device_scale_factor_ = device_scale_factor; |
| 1433 GtkStyle* label_style = gtk_rc_get_style(fake_label_.get()); | 1293 UpdateDefaultFont(); |
| 1434 UpdateDefaultFont(label_style->font_desc); | |
| 1435 } | 1294 } |
| 1436 | 1295 |
| 1437 float Gtk2UI::GetDeviceScaleFactor() const { | 1296 float Gtk2UI::GetDeviceScaleFactor() const { |
| 1438 if (gfx::Display::HasForceDeviceScaleFactor()) | 1297 if (gfx::Display::HasForceDeviceScaleFactor()) |
| 1439 return gfx::Display::GetForcedDeviceScaleFactor(); | 1298 return gfx::Display::GetForcedDeviceScaleFactor(); |
| 1440 const int kCSSDefaultDPI = 96; | 1299 const int kCSSDefaultDPI = 96; |
| 1441 float scale = GetDPI() / kCSSDefaultDPI; | 1300 float scale = GetDPI() / kCSSDefaultDPI; |
| 1442 // Round to 1 decimal, e.g. to 1.4. | 1301 // Round to 1 decimal, e.g. to 1.4. |
| 1443 return roundf(scale * 10) / 10; | 1302 return roundf(scale * 10) / 10; |
| 1444 } | 1303 } |
| 1445 | 1304 |
| 1446 } // namespace libgtk2ui | 1305 } // namespace libgtk2ui |
| 1447 | 1306 |
| 1448 views::LinuxUI* BuildGtk2UI() { | 1307 views::LinuxUI* BuildGtk2UI() { |
| 1449 return new libgtk2ui::Gtk2UI; | 1308 return new libgtk2ui::Gtk2UI; |
| 1450 } | 1309 } |
| OLD | NEW |