Gtk3: Refactor GtkButtonImageSource::GetImageForScale
This CL refactors GetImageForScale() on Gtk3 so no widget gets created. Only
a GtkStyleContext is needed.
In addition, it adds GtkStateFlagFocused to the style context if |focus_| is true.
This fixes focused button rendering on Ambiance, which doesn't use a focus
rectangle, but instead changes the button's border directly.
BUG=695357
R=erg@chromium.org
Review-Url: https://codereview.chromium.org/2715153002
Cr-Commit-Position: refs/heads/master@{#453292}
diff --git a/chrome/browser/ui/libgtkui/gtk_ui.cc b/chrome/browser/ui/libgtkui/gtk_ui.cc
index 50e6fbff..9bdb18c 100644
--- a/chrome/browser/ui/libgtkui/gtk_ui.cc
+++ b/chrome/browser/ui/libgtkui/gtk_ui.cc
@@ -116,6 +116,12 @@
border.allocN32Pixels(width, height);
border.eraseColor(0);
+ cairo_surface_t* surface = cairo_image_surface_create_for_data(
+ static_cast<unsigned char*>(border.getAddr(0, 0)), CAIRO_FORMAT_ARGB32,
+ width, height, width * 4);
+ cairo_t* cr = cairo_create(surface);
+
+#if GTK_MAJOR_VERSION == 2
// Create a temporary GTK button to snapshot
GtkWidget* window = gtk_offscreen_window_new();
GtkWidget* button = gtk_toggle_button_new();
@@ -133,12 +139,6 @@
gtk_widget_show_all(window);
- cairo_surface_t* surface = cairo_image_surface_create_for_data(
- static_cast<unsigned char*>(border.getAddr(0, 0)), CAIRO_FORMAT_ARGB32,
- width, height, width * 4);
- cairo_t* cr = cairo_create(surface);
-
-#if GTK_MAJOR_VERSION == 2
if (focus_)
GTK_WIDGET_SET_FLAGS(button, GTK_HAS_FOCUS);
@@ -161,8 +161,18 @@
g_object_unref(pixbuf);
g_object_unref(pixmap);
+
+ gtk_widget_destroy(window);
#else
- GtkStyleContext* context = gtk_widget_get_style_context(button);
+ ScopedStyleContext context = GetStyleContextFromCss(
+ is_blue_ ? "GtkButton#button.default.suggested-action"
+ : "GtkButton#button");
+ GtkStateFlags state_flags = StateToStateFlags(state_);
+ if (focus_) {
+ state_flags =
+ static_cast<GtkStateFlags>(state_flags | GTK_STATE_FLAG_FOCUSED);
+ }
+ gtk_style_context_set_state(context, state_flags);
gtk_render_background(context, cr, 0, 0, width, height);
gtk_render_frame(context, cr, 0, 0, width, height);
if (focus_)
@@ -172,8 +182,6 @@
cairo_destroy(cr);
cairo_surface_destroy(surface);
- gtk_widget_destroy(window);
-
return gfx::ImageSkiaRep(border, scale);
}
diff --git a/chrome/browser/ui/libgtkui/gtk_util.cc b/chrome/browser/ui/libgtkui/gtk_util.cc
index 23808239b..6c10b43 100644
--- a/chrome/browser/ui/libgtkui/gtk_util.cc
+++ b/chrome/browser/ui/libgtkui/gtk_util.cc
@@ -278,6 +278,23 @@
return false;
}
+GtkStateFlags StateToStateFlags(ui::NativeTheme::State state) {
+ switch (state) {
+ case ui::NativeTheme::kDisabled:
+ return GTK_STATE_FLAG_INSENSITIVE;
+ case ui::NativeTheme::kHovered:
+ return GTK_STATE_FLAG_PRELIGHT;
+ case ui::NativeTheme::kNormal:
+ return GTK_STATE_FLAG_NORMAL;
+ case ui::NativeTheme::kPressed:
+ return static_cast<GtkStateFlags>(GTK_STATE_FLAG_PRELIGHT |
+ GTK_STATE_FLAG_ACTIVE);
+ default:
+ NOTREACHED();
+ return GTK_STATE_FLAG_NORMAL;
+ }
+}
+
ScopedStyleContext AppendCssNodeToStyleContext(GtkStyleContext* context,
const std::string& css_node) {
GtkWidgetPath* path =
diff --git a/chrome/browser/ui/libgtkui/gtk_util.h b/chrome/browser/ui/libgtkui/gtk_util.h
index c87f70e0a..1598d99 100644
--- a/chrome/browser/ui/libgtkui/gtk_util.h
+++ b/chrome/browser/ui/libgtkui/gtk_util.h
@@ -177,6 +177,9 @@
typedef ScopedGObject<GtkStyleContext> ScopedStyleContext;
typedef ScopedGObject<GtkCssProvider> ScopedCssProvider;
+// Converts ui::NativeTheme::State to GtkStateFlags.
+GtkStateFlags StateToStateFlags(ui::NativeTheme::State state);
+
// If |context| is nullptr, creates a new top-level style context
// specified by parsing |css_node|. Otherwise, creates the child
// context with |context| as the parent.
diff --git a/chrome/browser/ui/libgtkui/native_theme_gtk3.cc b/chrome/browser/ui/libgtkui/native_theme_gtk3.cc
index 2bf1e90..af7ea82 100644
--- a/chrome/browser/ui/libgtkui/native_theme_gtk3.cc
+++ b/chrome/browser/ui/libgtkui/native_theme_gtk3.cc
@@ -63,23 +63,6 @@
rect.y());
}
-GtkStateFlags StateToStateFlags(NativeThemeGtk3::State state) {
- switch (state) {
- case NativeThemeGtk3::kDisabled:
- return GTK_STATE_FLAG_INSENSITIVE;
- case NativeThemeGtk3::kHovered:
- return GTK_STATE_FLAG_PRELIGHT;
- case NativeThemeGtk3::kNormal:
- return GTK_STATE_FLAG_NORMAL;
- case NativeThemeGtk3::kPressed:
- return static_cast<GtkStateFlags>(GTK_STATE_FLAG_PRELIGHT |
- GTK_STATE_FLAG_ACTIVE);
- default:
- NOTREACHED();
- return GTK_STATE_FLAG_NORMAL;
- }
-}
-
SkColor SkColorFromColorId(ui::NativeTheme::ColorId color_id) {
const SkColor kPositiveTextColor = SkColorSetRGB(0x0b, 0x80, 0x43);
const SkColor kNegativeTextColor = SkColorSetRGB(0xc5, 0x39, 0x29);