diff options
author | erg@chromium.org <erg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-13 19:04:00 +0000 |
---|---|---|
committer | erg@chromium.org <erg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-13 19:04:00 +0000 |
commit | 033de111cd6e9ff09f1c785ee8f3d38b0e14bab5 (patch) | |
tree | 37a6a08719339af92e617d56f358321004050a38 /chrome | |
parent | edc75aaccb3dbc06e27173212f8f1e9fa6649ee1 (diff) | |
download | chromium_src-033de111cd6e9ff09f1c785ee8f3d38b0e14bab5.zip chromium_src-033de111cd6e9ff09f1c785ee8f3d38b0e14bab5.tar.gz chromium_src-033de111cd6e9ff09f1c785ee8f3d38b0e14bab5.tar.bz2 |
GTK: Require gtk theme authors to specify their own frame colors.
1) Fix our heuristics to not be terribly wrong, while discouraging their use. If the theme author doesn't specify colors in the form of ChromeGtkFrame::frame-color, use the old MetaFrames/selection color fallback (tinting slightly darker).
2) Give the ChromeGtkFrame several optional widget style properties allowing theme authors to explicitly specify colors for the frame and scrollbars, and control the gradient on top of the chrome frame.
TODO: Do we want to let theme authors override the close/min/max button images?
BUG=62377, 35317
TEST=for now, compiles, as the needed data hasn't been added by theme authors.
Review URL: http://codereview.chromium.org/4715005
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@66064 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/gtk/chrome_gtk_frame.cc | 155 | ||||
-rw-r--r-- | chrome/browser/gtk/chrome_gtk_frame.h | 56 | ||||
-rw-r--r-- | chrome/browser/gtk/gtk_theme_provider.cc | 259 | ||||
-rw-r--r-- | chrome/browser/gtk/gtk_theme_provider.h | 35 | ||||
-rw-r--r-- | chrome/browser/gtk/meta_frames.cc | 25 | ||||
-rw-r--r-- | chrome/browser/gtk/meta_frames.h | 39 | ||||
-rw-r--r-- | chrome/chrome_browser.gypi | 4 |
7 files changed, 401 insertions, 172 deletions
diff --git a/chrome/browser/gtk/chrome_gtk_frame.cc b/chrome/browser/gtk/chrome_gtk_frame.cc new file mode 100644 index 0000000..77f28d1 --- /dev/null +++ b/chrome/browser/gtk/chrome_gtk_frame.cc @@ -0,0 +1,155 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/gtk/chrome_gtk_frame.h" + +G_BEGIN_DECLS + +// MetaFrames declaration +G_DEFINE_TYPE(MetaFrames, meta_frames, GTK_TYPE_WINDOW) + +static void meta_frames_class_init(MetaFramesClass* frames_class) { + // Noop since we don't declare anything. +} + +static void meta_frames_init(MetaFrames* button) { +} + + +// ChromeGtkFrame declaration +G_DEFINE_TYPE(ChromeGtkFrame, chrome_gtk_frame, meta_frames_get_type()) + +static void chrome_gtk_frame_class_init(ChromeGtkFrameClass* frame_class) { + GtkWidgetClass* widget_class = reinterpret_cast<GtkWidgetClass*>(frame_class); + + // Frame tints: + gtk_widget_class_install_style_property( + widget_class, + g_param_spec_boxed( + "frame-color", + "Frame Color", + "The color that the chrome frame will be. (If unspecified, " + " Chrome will take ChromeGtkFrame::bg[SELECTED] and slightly darken" + " it.)", + GDK_TYPE_COLOR, + G_PARAM_READABLE)); + gtk_widget_class_install_style_property( + widget_class, + g_param_spec_boxed( + "inactive-frame-color", + "Inactive Frame Color", + "The color that the inactive chrome frame will be. (If" + " unspecified, Chrome will take ChromeGtkFrame::bg[INSENSITIVE]" + " and slightly darken it.)", + GDK_TYPE_COLOR, + G_PARAM_READABLE)); + gtk_widget_class_install_style_property( + widget_class, + g_param_spec_boxed( + "incognito-frame-color", + "Incognito Frame Color", + "The color that the incognito frame will be. (If unspecified," + " Chrome will take the frame color and tint it by Chrome's default" + " incognito tint.)", + GDK_TYPE_COLOR, + G_PARAM_READABLE)); + gtk_widget_class_install_style_property( + widget_class, + g_param_spec_boxed( + "incognito-inactive-frame-color", + "Incognito Inactive Frame Color", + "The color that the inactive incognito frame will be. (If" + " unspecified, Chrome will take the frame color and tint it by" + " Chrome's default incognito tint.)", + GDK_TYPE_COLOR, + G_PARAM_READABLE)); + + // Frame gradient control: + gtk_widget_class_install_style_property( + widget_class, + g_param_spec_int( + "frame-gradient-size", + "Chrome Frame Gradient Size", + "The size of the gradient on top of the frame image. Specify 0 to" + " make the frame a solid color.", + 0, // 0 disables the gradient + 128, // The frame image is only up to 128 pixels tall. + 16, // By default, gradients are 16 pixels high. + G_PARAM_READABLE)); + gtk_widget_class_install_style_property( + widget_class, + g_param_spec_boxed( + "frame-gradient-color", + "Frame Gradient Color", + "The top color of the chrome frame gradient. (If unspecified," + " chrome will create a lighter tint of frame-color", + GDK_TYPE_COLOR, + G_PARAM_READABLE)); + gtk_widget_class_install_style_property( + widget_class, + g_param_spec_boxed( + "inactive-frame-gradient-color", + "Inactive Frame Gradient Color", + "The top color of the inactive chrome frame gradient. (If" + " unspecified, chrome will create a lighter tint of frame-color", + GDK_TYPE_COLOR, + G_PARAM_READABLE)); + gtk_widget_class_install_style_property( + widget_class, + g_param_spec_boxed( + "incognito-frame-gradient-color", + "Incognito Frame Gradient Color", + "The top color of the incognito chrome frame gradient. (If" + " unspecified, chrome will create a lighter tint of frame-color", + GDK_TYPE_COLOR, + G_PARAM_READABLE)); + gtk_widget_class_install_style_property( + widget_class, + g_param_spec_boxed( + "incognito-inactive-frame-gradient-color", + "Incognito Inactive Frame Gradient Color", + "The top color of the incognito inactive chrome frame gradient. (If" + " unspecified, chrome will create a lighter tint of frame-color", + GDK_TYPE_COLOR, + G_PARAM_READABLE)); + + // Scrollbar color properties: + gtk_widget_class_install_style_property( + widget_class, + g_param_spec_boxed( + "scrollbar-slider-prelight-color", + "Scrollbar Slider Prelight Color", + "The color applied to the mouse is above the tab", + GDK_TYPE_COLOR, + G_PARAM_READABLE)); + gtk_widget_class_install_style_property( + widget_class, + g_param_spec_boxed( + "scrollbar-slider-normal-color", + "Scrollbar Slider Normal Color", + "The color applied to the slider normally", + GDK_TYPE_COLOR, + G_PARAM_READABLE)); + gtk_widget_class_install_style_property( + widget_class, + g_param_spec_boxed( + "scrollbar-trough-color", + "Scrollbar Trough Color", + "The background color of the slider track", + GDK_TYPE_COLOR, + G_PARAM_READABLE)); +} + +static void chrome_gtk_frame_init(ChromeGtkFrame* frame) { +} + +GtkWidget* chrome_gtk_frame_new(void) { + GtkWindow* window = + GTK_WINDOW(g_object_new(chrome_gtk_frame_get_type(), NULL)); + window->type = GTK_WINDOW_TOPLEVEL; + return GTK_WIDGET(window); +} + + +G_END_DECLS diff --git a/chrome/browser/gtk/chrome_gtk_frame.h b/chrome/browser/gtk/chrome_gtk_frame.h new file mode 100644 index 0000000..0fd7d28 --- /dev/null +++ b/chrome/browser/gtk/chrome_gtk_frame.h @@ -0,0 +1,56 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_GTK_CHROME_GTK_FRAME_H_ +#define CHROME_BROWSER_GTK_CHROME_GTK_FRAME_H_ +#pragma once + +#include <gdk/gdk.h> +#include <gtk/gtkwindow.h> + +G_BEGIN_DECLS + +// This file declares two subclasses of GtkWindow for easier gtk+ theme +// integration. +// +// The first is "MetaFrames," which is (was?) the name of a gobject class in +// the metacity window manager. To actually get at those values, we need to +// have an object whose gobject class name string matches the definitions in +// the gtkrc file. MetaFrames derives from GtkWindow. +// +// Metaframes can not be instantiated. It has no constructor; instantiate +// ChromeGtkFrame instead. +typedef struct _MetaFrames MetaFrames; +typedef struct _MetaFramesClass MetaFramesClass; + +struct _MetaFrames { + GtkWindow window; +}; + +struct _MetaFramesClass { + GtkWindowClass parent_class; +}; + + +// The second is ChromeGtkFrame, which defines a number of optional style +// properties so theme authors can control how chromium appears in gtk-theme +// mode. It derives from MetaFrames in chrome so older themes that declare a +// MetaFrames theme will still work. New themes should target this class. +typedef struct _ChromeGtkFrame ChromeGtkFrame; +typedef struct _ChromeGtkFrameClass ChromeGtkFrameClass; + +struct _ChromeGtkFrame { + MetaFrames frames; +}; + +struct _ChromeGtkFrameClass { + MetaFramesClass frames_class; +}; + +// Creates a GtkWindow object the the class name "ChromeGtkFrame". +GtkWidget* chrome_gtk_frame_new(); + +G_END_DECLS + +#endif // CHROME_BROWSER_GTK_CHROME_GTK_FRAME_H_ diff --git a/chrome/browser/gtk/gtk_theme_provider.cc b/chrome/browser/gtk/gtk_theme_provider.cc index 6d04b57..a57ab6b 100644 --- a/chrome/browser/gtk/gtk_theme_provider.cc +++ b/chrome/browser/gtk/gtk_theme_provider.cc @@ -14,10 +14,10 @@ #include "base/stl_util-inl.h" #include "base/nix/xdg_util.h" #include "chrome/browser/gtk/cairo_cached_surface.h" +#include "chrome/browser/gtk/chrome_gtk_frame.h" #include "chrome/browser/gtk/gtk_chrome_button.h" #include "chrome/browser/gtk/gtk_util.h" #include "chrome/browser/gtk/hover_controller_gtk.h" -#include "chrome/browser/gtk/meta_frames.h" #include "chrome/browser/metrics/user_metrics.h" #include "chrome/browser/prefs/pref_service.h" #include "chrome/browser/profile.h" @@ -26,15 +26,18 @@ #include "chrome/common/notification_source.h" #include "chrome/common/notification_type.h" #include "chrome/common/pref_names.h" +#include "gfx/canvas_skia.h" #include "gfx/color_utils.h" #include "gfx/gtk_util.h" #include "gfx/skbitmap_operations.h" +#include "gfx/skia_util.h" #include "gfx/skia_utils_gtk.h" #include "grit/app_resources.h" #include "grit/theme_resources.h" #include "third_party/skia/include/core/SkBitmap.h" #include "third_party/skia/include/core/SkCanvas.h" #include "third_party/skia/include/core/SkColor.h" +#include "third_party/skia/include/core/SkShader.h" namespace { @@ -42,8 +45,11 @@ namespace { const int kToolbarImageWidth = 64; const int kToolbarImageHeight = 128; -const color_utils::HSL kExactColor = { -1, -1, -1 }; +// How much to tint the GTK+ color lighter at the top of the window. +const color_utils::HSL kGtkFrameShift = { -1, -1, 0.58 }; +// How much to tint the GTK+ color when an explicit frame color hasn't been +// specified. const color_utils::HSL kDefaultFrameShift = { -1, -1, 0.4 }; // Values used as the new luminance and saturation values in the inactive tab @@ -53,10 +59,6 @@ const double kLightInactiveLuminance = 0.15; const double kHeavyInactiveSaturation = 0.7; const double kLightInactiveSaturation = 0.3; -// Minimum difference between the toolbar and the button color before we try a -// different color. -const double kMinimumLuminanceDifference = 0.1; - // Number of times that the background color should be counted when trying to // calculate the border color in GTK theme mode. const int kBgWeight = 3; @@ -227,6 +229,14 @@ void BuildIconFromIDRWithColor(int id, gtk_icon_source_free(icon); } +// Applies an HSL shift to a GdkColor (instead of an SkColor) +void GdkColorHSLShift(const color_utils::HSL& shift, GdkColor* frame_color) { + SkColor shifted = color_utils::HSLShift(GdkToSkColor(frame_color), shift); + frame_color->pixel = 0; + frame_color->red = SkColorGetR(shifted) * kSkiaToGDKMultiplier; + frame_color->green = SkColorGetG(shifted) * kSkiaToGDKMultiplier; + frame_color->blue = SkColorGetB(shifted) * kSkiaToGDKMultiplier; +} } // namespace @@ -242,7 +252,7 @@ GtkThemeProvider* GtkThemeProvider::GetFrom(Profile* profile) { GtkThemeProvider::GtkThemeProvider() : BrowserThemeProvider(), fake_window_(gtk_window_new(GTK_WINDOW_TOPLEVEL)), - fake_frame_(meta_frames_new()), + fake_frame_(chrome_gtk_frame_new()), signals_(new GtkSignalRegistrar), fullscreen_icon_set_(NULL) { fake_label_.Own(gtk_label_new("")); @@ -414,6 +424,24 @@ GtkIconSet* GtkThemeProvider::GetIconSetForId(int id) const { void GtkThemeProvider::GetScrollbarColors(GdkColor* thumb_active_color, GdkColor* thumb_inactive_color, GdkColor* track_color) { + const GdkColor* theme_thumb_active = NULL; + const GdkColor* theme_thumb_inactive = NULL; + const GdkColor* theme_trough_color = NULL; + gtk_widget_style_get(GTK_WIDGET(fake_frame_), + "scrollbar-slider-prelight-color", &theme_thumb_active, + "scrollbar-slider-normal-color", &theme_thumb_inactive, + "scrollbar-trough-color", &theme_trough_color, + NULL); + + // Ask the theme if the theme specifies all the scrollbar colors and short + // circuit the expensive painting/compositing if we have all of them. + if (theme_thumb_active && theme_thumb_inactive && theme_trough_color) { + *thumb_active_color = *theme_thumb_active; + *thumb_inactive_color = *theme_thumb_inactive; + *track_color = *theme_trough_color; + return; + } + // Create window containing scrollbar elements GtkWidget* window = gtk_window_new(GTK_WINDOW_POPUP); GtkWidget* fixed = gtk_fixed_new(); @@ -479,6 +507,17 @@ void GtkThemeProvider::GetScrollbarColors(GdkColor* thumb_active_color, g_object_unref(pm); gtk_widget_destroy(window); + + // Override any of the default colors with ones that were specified by the + // theme. + if (theme_thumb_active) + *thumb_active_color = *theme_thumb_active; + + if (theme_thumb_inactive) + *thumb_inactive_color = *theme_thumb_inactive; + + if (theme_trough_color) + *track_color = *theme_trough_color; } CairoCachedSurface* GtkThemeProvider::GetSurfaceNamed( @@ -630,87 +669,29 @@ void GtkThemeProvider::LoadGtkValues() { pref_images->Clear(); GtkStyle* frame_style = gtk_rc_get_style(fake_frame_); - GdkColor frame_color = frame_style->bg[GTK_STATE_SELECTED]; - GdkColor inactive_frame_color = frame_style->bg[GTK_STATE_INSENSITIVE]; GtkStyle* window_style = gtk_rc_get_style(fake_window_); + SetThemeColorFromGtk(BrowserThemeProvider::COLOR_CONTROL_BACKGROUND, + &window_style->bg[GTK_STATE_NORMAL]); + SetThemeColorFromGtk(BrowserThemeProvider::COLOR_BUTTON_BACKGROUND, + &window_style->bg[GTK_STATE_NORMAL]); + GdkColor toolbar_color = window_style->bg[GTK_STATE_NORMAL]; + SetThemeColorFromGtk(BrowserThemeProvider::COLOR_TOOLBAR, &toolbar_color); + GdkColor button_color = window_style->bg[GTK_STATE_SELECTED]; + SetThemeTintFromGtk(BrowserThemeProvider::TINT_BUTTONS, &button_color); GtkStyle* label_style = gtk_rc_get_style(fake_label_.get()); GdkColor label_color = label_style->fg[GTK_STATE_NORMAL]; - - GtkSettings* settings = gtk_settings_get_default(); - bool theme_has_frame_color = false; - if (settings) { - GHashTable* color_scheme = NULL; - g_object_get(settings, "color-hash", &color_scheme, NULL); - - if (color_scheme) { - // If we have a "gtk-color-scheme" set in this theme, mine it for hints - // about what we should actually set the frame color to. - GdkColor* color = NULL; - if ((color = static_cast<GdkColor*>( - g_hash_table_lookup(color_scheme, "frame_color")))) { - frame_color = *color; - theme_has_frame_color = true; - } - - if ((color = static_cast<GdkColor*>( - g_hash_table_lookup(color_scheme, "inactive_frame_color")))) { - inactive_frame_color = *color; - } - } - } - - if (!theme_has_frame_color) { - // If the theme's gtkrc doesn't explicitly tell us to use a specific frame - // color, change the luminosity of the frame color downwards to 80% of what - // it currently is. This is in a futile attempt to match the default - // metacity and xfwm themes. - SkColor shifted = color_utils::HSLShift(GdkToSkColor(&frame_color), - kDefaultFrameShift); - frame_color.pixel = 0; - frame_color.red = SkColorGetR(shifted) * kSkiaToGDKMultiplier; - frame_color.green = SkColorGetG(shifted) * kSkiaToGDKMultiplier; - frame_color.blue = SkColorGetB(shifted) * kSkiaToGDKMultiplier; - } + SetThemeColorFromGtk(BrowserThemeProvider::COLOR_TAB_TEXT, &label_color); + SetThemeColorFromGtk(BrowserThemeProvider::COLOR_BOOKMARK_TEXT, &label_color); // Build the various icon tints. GetNormalButtonTintHSL(&button_tint_); GetNormalEntryForegroundHSL(&entry_tint_); GetSelectedEntryForegroundHSL(&selected_entry_tint_); - - SetThemeTintFromGtk(BrowserThemeProvider::TINT_BUTTONS, &button_color); - SetThemeTintFromGtk(BrowserThemeProvider::TINT_FRAME, &frame_color); - SetThemeTintFromGtk(BrowserThemeProvider::TINT_FRAME_INCOGNITO, &frame_color); - SetThemeTintFromGtk(BrowserThemeProvider::TINT_BACKGROUND_TAB, &frame_color); - - // The inactive color/tint is special: We *must* use the exact insensitive - // color for all inactive windows, otherwise we end up neon pink half the - // time. - SetThemeColorFromGtk(BrowserThemeProvider::COLOR_FRAME_INACTIVE, - &inactive_frame_color); - SetTintToExactColor(BrowserThemeProvider::TINT_FRAME_INACTIVE, - &inactive_frame_color); - SetTintToExactColor(BrowserThemeProvider::TINT_FRAME_INCOGNITO_INACTIVE, - &inactive_frame_color); - - SetThemeColorFromGtk(BrowserThemeProvider::COLOR_FRAME, &frame_color); - BuildTintedFrameColor(BrowserThemeProvider::COLOR_FRAME_INACTIVE, - BrowserThemeProvider::TINT_FRAME_INACTIVE); - BuildTintedFrameColor(BrowserThemeProvider::COLOR_FRAME_INCOGNITO, - BrowserThemeProvider::TINT_FRAME_INCOGNITO); - BuildTintedFrameColor(BrowserThemeProvider::COLOR_FRAME_INCOGNITO_INACTIVE, - BrowserThemeProvider::TINT_FRAME_INCOGNITO_INACTIVE); - - SetThemeColorFromGtk(BrowserThemeProvider::COLOR_TOOLBAR, &toolbar_color); - SetThemeColorFromGtk(BrowserThemeProvider::COLOR_TAB_TEXT, &label_color); - SetThemeColorFromGtk(BrowserThemeProvider::COLOR_BOOKMARK_TEXT, &label_color); - SetThemeColorFromGtk(BrowserThemeProvider::COLOR_CONTROL_BACKGROUND, - &window_style->bg[GTK_STATE_NORMAL]); - SetThemeColorFromGtk(BrowserThemeProvider::COLOR_BUTTON_BACKGROUND, - &window_style->bg[GTK_STATE_NORMAL]); + GdkColor frame_color = BuildFrameColors(frame_style); // The inactive frame color never occurs naturally in the theme, as it is a // tinted version of |frame_color|. We generate another color based on the @@ -794,6 +775,51 @@ void GtkThemeProvider::LoadGtkValues() { GdkToSkColor(&entry_style->text[GTK_STATE_ACTIVE]); } +GdkColor GtkThemeProvider::BuildFrameColors(GtkStyle* frame_style) { + const GdkColor* theme_frame = NULL; + const GdkColor* theme_inactive_frame = NULL; + const GdkColor* theme_incognito_frame = NULL; + const GdkColor* theme_incognito_inactive_frame = NULL; + gtk_widget_style_get(GTK_WIDGET(fake_frame_), + "frame-color", &theme_frame, + "inactive-frame-color", &theme_inactive_frame, + "incognito-frame-color", &theme_incognito_frame, + "incognito-inactive-frame-color", + &theme_incognito_inactive_frame, + NULL); + + GdkColor frame_color = BuildAndSetFrameColor( + &frame_style->bg[GTK_STATE_SELECTED], + theme_frame, + kDefaultFrameShift, + BrowserThemeProvider::COLOR_FRAME, + BrowserThemeProvider::TINT_FRAME); + SetThemeTintFromGtk(BrowserThemeProvider::TINT_BACKGROUND_TAB, &frame_color); + + BuildAndSetFrameColor( + &frame_style->bg[GTK_STATE_INSENSITIVE], + theme_inactive_frame, + kDefaultFrameShift, + BrowserThemeProvider::COLOR_FRAME_INACTIVE, + BrowserThemeProvider::TINT_FRAME_INACTIVE); + + BuildAndSetFrameColor( + &frame_color, + theme_incognito_frame, + GetDefaultTint(BrowserThemeProvider::TINT_FRAME_INCOGNITO), + BrowserThemeProvider::COLOR_FRAME_INCOGNITO, + BrowserThemeProvider::TINT_FRAME_INCOGNITO); + + BuildAndSetFrameColor( + &frame_color, + theme_incognito_inactive_frame, + GetDefaultTint(BrowserThemeProvider::TINT_FRAME_INCOGNITO_INACTIVE), + BrowserThemeProvider::COLOR_FRAME_INCOGNITO_INACTIVE, + BrowserThemeProvider::TINT_FRAME_INCOGNITO_INACTIVE); + + return frame_color; +} + void GtkThemeProvider::LoadDefaultValues() { focus_ring_color_ = SkColorSetARGB(255, 229, 151, 0); thumb_active_color_ = SkColorSetRGB(244, 244, 244); @@ -840,16 +866,24 @@ void GtkThemeProvider::SetThemeTintFromGtk(int id, const GdkColor* color) { tints_[id] = hsl; } -void GtkThemeProvider::BuildTintedFrameColor(int color_id, int tint_id) { - colors_[color_id] = HSLShift( - GetDefaultColor(BrowserThemeProvider::COLOR_FRAME), - tints_[tint_id]); -} +GdkColor GtkThemeProvider::BuildAndSetFrameColor(const GdkColor* base, + const GdkColor* gtk_base, + const color_utils::HSL& tint, + int color_id, + int tint_id) { + GdkColor out_color = *base; + if (gtk_base) { + // The theme author specified a color to use, use it without modification. + out_color = *gtk_base; + } else { + // Tint the basic color since this is a heuristic color instead of one + // specified by the theme author. + GdkColorHSLShift(tint, &out_color); + } + SetThemeColorFromGtk(color_id, &out_color); + SetThemeTintFromGtk(tint_id, &out_color); -void GtkThemeProvider::SetTintToExactColor(int id, const GdkColor* color) { - color_utils::HSL hsl; - color_utils::SkColorToHSL(GdkToSkColor(color), &hsl); - tints_[id] = hsl; + return out_color; } void GtkThemeProvider::FreePerDisplaySurfaces( @@ -888,14 +922,18 @@ SkBitmap* GtkThemeProvider::GenerateGtkThemeBitmap(int id) const { case IDR_THEME_TAB_BACKGROUND_INCOGNITO: return GenerateTabImage(IDR_THEME_FRAME_INCOGNITO); case IDR_THEME_FRAME: - return GenerateFrameImage(BrowserThemeProvider::TINT_FRAME); + return GenerateFrameImage(BrowserThemeProvider::COLOR_FRAME, + "frame-gradient-color"); case IDR_THEME_FRAME_INACTIVE: - return GenerateFrameImage(BrowserThemeProvider::TINT_FRAME_INACTIVE); + return GenerateFrameImage(BrowserThemeProvider::COLOR_FRAME_INACTIVE, + "inactive-frame-gradient-color"); case IDR_THEME_FRAME_INCOGNITO: - return GenerateFrameImage(BrowserThemeProvider::TINT_FRAME_INCOGNITO); + return GenerateFrameImage(BrowserThemeProvider::COLOR_FRAME_INCOGNITO, + "incognito-frame-gradient-color"); case IDR_THEME_FRAME_INCOGNITO_INACTIVE: { return GenerateFrameImage( - BrowserThemeProvider::TINT_FRAME_INCOGNITO_INACTIVE); + BrowserThemeProvider::COLOR_FRAME_INCOGNITO_INACTIVE, + "incognito-inactive-frame-gradient-color"); } // Icons that sit inside the omnibox shouldn't receive TINT_BUTTONS and // instead should tint based on the foreground text entry color in GTK+ @@ -927,13 +965,42 @@ SkBitmap* GtkThemeProvider::GenerateGtkThemeBitmap(int id) const { } } -SkBitmap* GtkThemeProvider::GenerateFrameImage(int tint_id) const { - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - scoped_ptr<SkBitmap> frame(new SkBitmap(*rb.GetBitmapNamed(IDR_THEME_FRAME))); - TintMap::const_iterator it = tints_.find(tint_id); - DCHECK(it != tints_.end()); - return new SkBitmap(SkBitmapOperations::CreateHSLShiftedBitmap(*frame, - it->second)); +SkBitmap* GtkThemeProvider::GenerateFrameImage( + int color_id, + const char* gradient_name) const { + // We use two colors: the main color (passed in) and a lightened version of + // that color (which is supposed to match the light gradient at the top of + // several GTK+ themes, such as Ambiance, Clearlooks or Bluebird). + ColorMap::const_iterator it = colors_.find(color_id); + DCHECK(it != colors_.end()); + SkColor base = it->second; + + gfx::CanvasSkia canvas(kToolbarImageWidth, kToolbarImageHeight, true); + + int gradient_size; + const GdkColor* gradient_top_color = NULL; + gtk_widget_style_get(GTK_WIDGET(fake_frame_), + "frame-gradient-size", &gradient_size, + gradient_name, &gradient_top_color, + NULL); + if (gradient_size) { + SkColor lighter = gradient_top_color ? GdkToSkColor(gradient_top_color) + : color_utils::HSLShift(base, kGtkFrameShift); + SkShader* shader = gfx::CreateGradientShader( + 0, gradient_size, lighter, base); + SkPaint paint; + paint.setStyle(SkPaint::kFill_Style); + paint.setAntiAlias(true); + paint.setShader(shader); + shader->unref(); + + canvas.DrawRectInt(0, 0, kToolbarImageWidth, gradient_size, paint); + } + + canvas.FillRectInt(base, 0, gradient_size, + kToolbarImageWidth, + kToolbarImageHeight - gradient_size); + return new SkBitmap(canvas.ExtractBitmap()); } SkBitmap* GtkThemeProvider::GenerateTabImage(int base_id) const { diff --git a/chrome/browser/gtk/gtk_theme_provider.h b/chrome/browser/gtk/gtk_theme_provider.h index f31d974..630fdbc 100644 --- a/chrome/browser/gtk/gtk_theme_provider.h +++ b/chrome/browser/gtk/gtk_theme_provider.h @@ -84,11 +84,12 @@ class GtkThemeProvider : public BrowserThemeProvider, // label colors for the IDR resource |id|. GtkIconSet* GetIconSetForId(int id) const; - // This method returns averages of the thumb part and of the track colors. - // Used when rendering scrollbars. - static void GetScrollbarColors(GdkColor* thumb_active_color, - GdkColor* thumb_inactive_color, - GdkColor* track_color); + // This method returns the colors webkit will use for the scrollbars. When no + // colors are specified by the GTK+ theme, this function averages of the + // thumb part and of the track colors. + void GetScrollbarColors(GdkColor* thumb_active_color, + GdkColor* thumb_inactive_color, + GdkColor* track_color); // Expose the inner label. Only used for testing. GtkWidget* fake_label() { return fake_label_.get(); } @@ -162,6 +163,10 @@ class GtkThemeProvider : public BrowserThemeProvider, // BrowserThemeProvider interface and the colors we send to webkit. void LoadGtkValues(); + // Reads in explicit theme frame colors from the ChromeGtkFrame style class + // or generates them per our fallback algorithm. + GdkColor BuildFrameColors(GtkStyle* frame_style); + // Sets the values that we send to webkit to safe defaults. void LoadDefaultValues(); @@ -173,8 +178,15 @@ class GtkThemeProvider : public BrowserThemeProvider, // Sets the underlying theme colors/tints from a GTK color. void SetThemeColorFromGtk(int id, const GdkColor* color); void SetThemeTintFromGtk(int id, const GdkColor* color); - void BuildTintedFrameColor(int color_id, int tint_id); - void SetTintToExactColor(int id, const GdkColor* color); + + // Creates and returns a frame color, either using |gtk_base| verbatim if + // non-NULL, or tinting |base| with |tint|. Also sets |color_id| and + // |tint_id| to the returned color. + GdkColor BuildAndSetFrameColor(const GdkColor* base, + const GdkColor* gtk_base, + const color_utils::HSL& tint, + int color_id, + int tint_id); // Split out from FreePlatformCaches so it can be called in our destructor; // FreePlatformCaches() is called from the BrowserThemeProvider's destructor, @@ -188,9 +200,12 @@ class GtkThemeProvider : public BrowserThemeProvider, // Lazily generates each bitmap used in the gtk theme. SkBitmap* GenerateGtkThemeBitmap(int id) const; - // Tints IDR_THEME_FRAME based based on |tint_id|. Used during lazy - // generation of the gtk theme bitmaps. - SkBitmap* GenerateFrameImage(int tint_id) const; + // Creates a GTK+ version of IDR_THEME_FRAME. Instead of tinting, this + // creates a theme configurable gradient ending with |color_id| at the + // bottom, and |gradient_name| at the top if that color is specified in the + // theme. + SkBitmap* GenerateFrameImage(int color_id, + const char* gradient_name) const; // Takes the base frame image |base_id| and tints it with |tint_id|. SkBitmap* GenerateTabImage(int base_id) const; diff --git a/chrome/browser/gtk/meta_frames.cc b/chrome/browser/gtk/meta_frames.cc deleted file mode 100644 index e95ac87..0000000 --- a/chrome/browser/gtk/meta_frames.cc +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/gtk/meta_frames.h" - -G_BEGIN_DECLS - -G_DEFINE_TYPE(MetaFrames, meta_frames, GTK_TYPE_WINDOW) - -static void meta_frames_class_init(MetaFramesClass* frames_class) { - // Noop since we don't declare anything. -} - -static void meta_frames_init(MetaFrames* button) { -} - -GtkWidget* meta_frames_new(void) { - GtkWindow* window = - GTK_WINDOW(g_object_new(meta_frames_get_type(), NULL)); - window->type = GTK_WINDOW_TOPLEVEL; - return GTK_WIDGET(window); -} - -G_END_DECLS diff --git a/chrome/browser/gtk/meta_frames.h b/chrome/browser/gtk/meta_frames.h deleted file mode 100644 index bc8a493..0000000 --- a/chrome/browser/gtk/meta_frames.h +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_GTK_META_FRAMES_H_ -#define CHROME_BROWSER_GTK_META_FRAMES_H_ -#pragma once - -#include <gdk/gdk.h> -#include <gtk/gtkwindow.h> - -G_BEGIN_DECLS - -// For the sake of gtk+ theme integration, we define a class called -// "MetaFrames," which is the name of a gobject class in the metacity window -// manager. To actually get at those values, we need to have an object whose -// gobject class name string matches the definitions in the gtkrc -// file. MetaFrames derives from GtkWindow. -// -// TODO(erg): http://crbug.com/35317 for getting rid of this hack class, as we -// should be able to use gtk_rc_get_style_by_path() but can't? - -typedef struct _MetaFrames MetaFrames; -typedef struct _MetaFramesClass MetaFramesClass; - -struct _MetaFrames { - GtkWindow window; -}; - -struct _MetaFramesClass { - GtkWindowClass parent_class; -}; - -// Creates a GtkWindow object with the class name "MetaFrames". -GtkWidget* meta_frames_new(); - -G_END_DECLS - -#endif // CHROME_BROWSER_GTK_META_FRAMES_H_ diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index a96d38c..a410eea 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -1778,6 +1778,8 @@ 'browser/gtk/certificate_dialogs.h', 'browser/gtk/certificate_viewer.cc', 'browser/gtk/certificate_viewer.h', + 'browser/gtk/chrome_gtk_frame.cc', + 'browser/gtk/chrome_gtk_frame.h', 'browser/gtk/clear_browsing_data_dialog_gtk.cc', 'browser/gtk/clear_browsing_data_dialog_gtk.h', 'browser/gtk/collected_cookies_gtk.cc', @@ -1882,8 +1884,6 @@ 'browser/gtk/menu_bar_helper.h', 'browser/gtk/menu_gtk.cc', 'browser/gtk/menu_gtk.h', - 'browser/gtk/meta_frames.cc', - 'browser/gtk/meta_frames.h', 'browser/gtk/nine_box.cc', 'browser/gtk/nine_box.h', 'browser/gtk/notifications/balloon_view_gtk.cc', |