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);