Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / libgtk2ui / gtk2_ui.cc
index 293feeb..c5b729c 100644 (file)
@@ -6,12 +6,15 @@
 
 #include <set>
 
+#include <pango/pango.h>
+
 #include "base/command_line.h"
 #include "base/debug/leak_annotations.h"
 #include "base/environment.h"
 #include "base/i18n/rtl.h"
 #include "base/logging.h"
 #include "base/nix/mime_util_xdg.h"
+#include "base/nix/xdg_util.h"
 #include "base/stl_util.h"
 #include "base/strings/stringprintf.h"
 #include "chrome/browser/themes/theme_properties.h"
@@ -30,8 +33,8 @@
 #include "chrome/browser/ui/libgtk2ui/skia_utils_gtk2.h"
 #include "chrome/browser/ui/libgtk2ui/unity_service.h"
 #include "chrome/browser/ui/libgtk2ui/x11_input_method_context_impl_gtk2.h"
+#include "grit/components_scaled_resources.h"
 #include "grit/theme_resources.h"
-#include "grit/ui_resources.h"
 #include "printing/printing_context_linux.h"
 #include "third_party/skia/include/core/SkBitmap.h"
 #include "third_party/skia/include/core/SkCanvas.h"
 #include "ui/base/resource/resource_bundle.h"
 #include "ui/gfx/canvas.h"
 #include "ui/gfx/image/image.h"
+#include "ui/gfx/pango_util.h"
 #include "ui/gfx/rect.h"
 #include "ui/gfx/size.h"
 #include "ui/gfx/skbitmap_operations.h"
 #include "ui/gfx/skia_util.h"
+#include "ui/resources/grit/ui_resources.h"
 #include "ui/views/controls/button/label_button.h"
 #include "ui/views/controls/button/label_button_border.h"
 #include "ui/views/linux_ui/window_button_order_observer.h"
 // - Render and inject the omnibox background.
 // - Make sure to test with a light on dark theme, too.
 
+// Work around a header bug:
+// linux/debian_wheezy_i386-sysroot/usr/include/linux/stddef.h redefines NULL
+// to 0, which breaks -Wsentinel. Get back the normal definition of NULL.
+// TODO(thakis): Remove this once we update sysroots.
+#define __need_NULL
+#include <stddef.h>
+
+namespace libgtk2ui {
+
 namespace {
 
 struct GObjectDeleter {
@@ -166,38 +180,24 @@ struct IDRGtkMapping {
 } const kGtkIcons[] = {
   { IDR_BACK,      GTK_STOCK_GO_BACK,    GTK_STATE_NORMAL },
   { IDR_BACK_D,    GTK_STOCK_GO_BACK,    GTK_STATE_INSENSITIVE },
-  { IDR_BACK_H,    GTK_STOCK_GO_BACK,    GTK_STATE_PRELIGHT },
-  { IDR_BACK_P,    GTK_STOCK_GO_BACK,    GTK_STATE_ACTIVE },
 
   { IDR_FORWARD,   GTK_STOCK_GO_FORWARD, GTK_STATE_NORMAL },
   { IDR_FORWARD_D, GTK_STOCK_GO_FORWARD, GTK_STATE_INSENSITIVE },
-  { IDR_FORWARD_H, GTK_STOCK_GO_FORWARD, GTK_STATE_PRELIGHT },
-  { IDR_FORWARD_P, GTK_STOCK_GO_FORWARD, GTK_STATE_ACTIVE },
 
   { IDR_HOME,      GTK_STOCK_HOME,       GTK_STATE_NORMAL },
-  { IDR_HOME_H,    GTK_STOCK_HOME,       GTK_STATE_PRELIGHT },
-  { IDR_HOME_P,    GTK_STOCK_HOME,       GTK_STATE_ACTIVE },
 
   { IDR_RELOAD,    GTK_STOCK_REFRESH,    GTK_STATE_NORMAL },
   { IDR_RELOAD_D,  GTK_STOCK_REFRESH,    GTK_STATE_INSENSITIVE },
-  { IDR_RELOAD_H,  GTK_STOCK_REFRESH,    GTK_STATE_PRELIGHT },
-  { IDR_RELOAD_P,  GTK_STOCK_REFRESH,    GTK_STATE_ACTIVE },
 
   { IDR_STOP,      GTK_STOCK_STOP,       GTK_STATE_NORMAL },
   { IDR_STOP_D,    GTK_STOCK_STOP,       GTK_STATE_INSENSITIVE },
-  { IDR_STOP_H,    GTK_STOCK_STOP,       GTK_STATE_PRELIGHT },
-  { IDR_STOP_P,    GTK_STOCK_STOP,       GTK_STATE_ACTIVE },
 };
 
 // The image resources that will be tinted by the 'button' tint value.
 const int kOtherToolbarButtonIDs[] = {
   IDR_TOOLBAR_BEZEL_HOVER,
   IDR_TOOLBAR_BEZEL_PRESSED,
-  IDR_BROWSER_ACTION_H,
-  IDR_BROWSER_ACTION_P,
   IDR_BROWSER_ACTIONS_OVERFLOW,
-  IDR_BROWSER_ACTIONS_OVERFLOW_H,
-  IDR_BROWSER_ACTIONS_OVERFLOW_P,
   IDR_THROBBER,
   IDR_THROBBER_WAITING,
   IDR_THROBBER_LIGHT,
@@ -238,16 +238,16 @@ void PickButtonTintFromColors(const GdkColor& accent_gdk_color,
                               const GdkColor& text_color,
                               const GdkColor& background_color,
                               color_utils::HSL* tint) {
-  SkColor accent_color = libgtk2ui::GdkColorToSkColor(accent_gdk_color);
+  SkColor accent_color = GdkColorToSkColor(accent_gdk_color);
   color_utils::HSL accent_tint;
   color_utils::SkColorToHSL(accent_color, &accent_tint);
 
   color_utils::HSL text_tint;
-  color_utils::SkColorToHSL(libgtk2ui::GdkColorToSkColor(text_color),
+  color_utils::SkColorToHSL(GdkColorToSkColor(text_color),
                             &text_tint);
 
   color_utils::HSL background_tint;
-  color_utils::SkColorToHSL(libgtk2ui::GdkColorToSkColor(background_color),
+  color_utils::SkColorToHSL(GdkColorToSkColor(background_color),
                             &background_tint);
 
   // If the accent color is gray, then our normal HSL tomfoolery will bring out
@@ -298,7 +298,7 @@ void PickButtonTintFromColors(const GdkColor& accent_gdk_color,
 // 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(
-      libgtk2ui::GdkColorToSkColor(*frame_color), shift);
+      GdkColorToSkColor(*frame_color), shift);
 
   frame_color->pixel = 0;
   frame_color->red = SkColorGetR(shifted) * kSkiaToGDKMultiplier;
@@ -327,11 +327,75 @@ color_utils::HSL GetDefaultTint(int id) {
   }
 }
 
-}  // namespace
+// Returns a FontRenderParams corresponding to GTK's configuration.
+gfx::FontRenderParams GetGtkFontRenderParams() {
+  GtkSettings* gtk_settings = gtk_settings_get_default();
+  CHECK(gtk_settings);
+  gint antialias = 0;
+  gint hinting = 0;
+  gchar* hint_style = NULL;
+  gchar* rgba = NULL;
+  g_object_get(gtk_settings,
+               "gtk-xft-antialias", &antialias,
+               "gtk-xft-hinting", &hinting,
+               "gtk-xft-hintstyle", &hint_style,
+               "gtk-xft-rgba", &rgba,
+               NULL);
 
-namespace libgtk2ui {
+  gfx::FontRenderParams params;
+  params.antialiasing = antialias != 0;
+
+  if (hinting == 0 || !hint_style || strcmp(hint_style, "hintnone") == 0) {
+    params.hinting = gfx::FontRenderParams::HINTING_NONE;
+  } else if (strcmp(hint_style, "hintslight") == 0) {
+    params.hinting = gfx::FontRenderParams::HINTING_SLIGHT;
+  } else if (strcmp(hint_style, "hintmedium") == 0) {
+    params.hinting = gfx::FontRenderParams::HINTING_MEDIUM;
+  } else if (strcmp(hint_style, "hintfull") == 0) {
+    params.hinting = gfx::FontRenderParams::HINTING_FULL;
+  } else {
+    LOG(WARNING) << "Unexpected gtk-xft-hintstyle \"" << hint_style << "\"";
+    params.hinting = gfx::FontRenderParams::HINTING_NONE;
+  }
+
+  if (!rgba || strcmp(rgba, "none") == 0) {
+    params.subpixel_rendering = gfx::FontRenderParams::SUBPIXEL_RENDERING_NONE;
+  } else if (strcmp(rgba, "rgb") == 0) {
+    params.subpixel_rendering = gfx::FontRenderParams::SUBPIXEL_RENDERING_RGB;
+  } else if (strcmp(rgba, "bgr") == 0) {
+    params.subpixel_rendering = gfx::FontRenderParams::SUBPIXEL_RENDERING_BGR;
+  } else if (strcmp(rgba, "vrgb") == 0) {
+    params.subpixel_rendering = gfx::FontRenderParams::SUBPIXEL_RENDERING_VRGB;
+  } else if (strcmp(rgba, "vbgr") == 0) {
+    params.subpixel_rendering = gfx::FontRenderParams::SUBPIXEL_RENDERING_VBGR;
+  } else {
+    LOG(WARNING) << "Unexpected gtk-xft-rgba \"" << rgba << "\"";
+    params.subpixel_rendering = gfx::FontRenderParams::SUBPIXEL_RENDERING_NONE;
+  }
+
+  g_free(hint_style);
+  g_free(rgba);
+
+  return params;
+}
+
+views::LinuxUI::NonClientMiddleClickAction GetDefaultMiddleClickAction() {
+  scoped_ptr<base::Environment> env(base::Environment::Create());
+  switch (base::nix::GetDesktopEnvironment(env.get())) {
+    case base::nix::DESKTOP_ENVIRONMENT_KDE4:
+      // Starting with KDE 4.4, windows' titlebars can be dragged with the
+      // middle mouse button to create tab groups. We don't support that in
+      // Chrome, but at least avoid lowering windows in response to middle
+      // clicks to avoid surprising users who expect the KDE behavior.
+      return views::LinuxUI::MIDDLE_CLICK_ACTION_NONE;
+    default:
+      return views::LinuxUI::MIDDLE_CLICK_ACTION_LOWER;
+  }
+}
+
+}  // namespace
 
-Gtk2UI::Gtk2UI() : middle_click_action_(MIDDLE_CLICK_ACTION_LOWER) {
+Gtk2UI::Gtk2UI() : middle_click_action_(GetDefaultMiddleClickAction()) {
   GtkInitFromCommandLine(*CommandLine::ForCurrentProcess());
 }
 
@@ -560,10 +624,9 @@ scoped_ptr<views::Border> Gtk2UI::CreateNativeBorder(
     views::LabelButton* owning_button,
     scoped_ptr<views::LabelButtonBorder> border) {
   if (owning_button->GetNativeTheme() != NativeThemeGtk2::instance())
-    return border.PassAs<views::Border>();
+    return border.Pass();
 
-  return scoped_ptr<views::Border>(
-      new Gtk2Border(this, owning_button, border.Pass()));
+  return make_scoped_ptr(new Gtk2Border(this, owning_button, border.Pass()));
 }
 
 void Gtk2UI::AddWindowButtonOrderObserver(
@@ -602,87 +665,26 @@ scoped_ptr<ui::LinuxInputMethodContext> Gtk2UI::CreateInputMethodContext(
       new X11InputMethodContextImplGtk2(delegate));
 }
 
-bool Gtk2UI::UseAntialiasing() const {
-  GtkSettings* gtk_settings = gtk_settings_get_default();
-  CHECK(gtk_settings);
-  gint gtk_antialias = 0;
-  g_object_get(gtk_settings,
-               "gtk-xft-antialias", &gtk_antialias,
-               NULL);
-  return gtk_antialias != 0;
+gfx::FontRenderParams Gtk2UI::GetDefaultFontRenderParams() const {
+  static gfx::FontRenderParams params = GetGtkFontRenderParams();
+  return params;
 }
 
-gfx::FontRenderParams::Hinting Gtk2UI::GetHintingStyle() const {
-  GtkSettings* gtk_settings = gtk_settings_get_default();
-  CHECK(gtk_settings);
-  gfx::FontRenderParams::Hinting hinting =
-      gfx::FontRenderParams::HINTING_SLIGHT;
-  gint gtk_hinting = 0;
-  gchar* gtk_hint_style = NULL;
-  g_object_get(gtk_settings,
-               "gtk-xft-hinting", &gtk_hinting,
-               "gtk-xft-hintstyle", &gtk_hint_style,
-               NULL);
-
-  if (gtk_hint_style) {
-    if (gtk_hinting == 0 || strcmp(gtk_hint_style, "hintnone") == 0)
-      hinting = gfx::FontRenderParams::HINTING_NONE;
-    else if (strcmp(gtk_hint_style, "hintslight") == 0)
-      hinting = gfx::FontRenderParams::HINTING_SLIGHT;
-    else if (strcmp(gtk_hint_style, "hintmedium") == 0)
-      hinting = gfx::FontRenderParams::HINTING_MEDIUM;
-    else if (strcmp(gtk_hint_style, "hintfull") == 0)
-      hinting = gfx::FontRenderParams::HINTING_FULL;
-
-    g_free(gtk_hint_style);
-  }
-
-  return hinting;
+scoped_ptr<gfx::ScopedPangoFontDescription>
+Gtk2UI::GetDefaultPangoFontDescription() const {
+  return scoped_ptr<gfx::ScopedPangoFontDescription>(
+      new gfx::ScopedPangoFontDescription(
+          pango_font_description_copy(default_font_description_->get())));
 }
 
-gfx::FontRenderParams::SubpixelRendering
-Gtk2UI::GetSubpixelRenderingStyle() const {
+double Gtk2UI::GetFontDPI() const {
   GtkSettings* gtk_settings = gtk_settings_get_default();
   CHECK(gtk_settings);
-  gfx::FontRenderParams::SubpixelRendering subpixel_rendering =
-      gfx::FontRenderParams::SUBPIXEL_RENDERING_NONE;
-  gchar* gtk_rgba = NULL;
-  g_object_get(gtk_settings,
-               "gtk-xft-rgba", &gtk_rgba,
-               NULL);
+  gint dpi = -1;
+  g_object_get(gtk_settings, "gtk-xft-dpi", &dpi, NULL);
 
-  if (gtk_rgba) {
-    if (strcmp(gtk_rgba, "none") == 0)
-      subpixel_rendering = gfx::FontRenderParams::SUBPIXEL_RENDERING_NONE;
-    else if (strcmp(gtk_rgba, "rgb") == 0)
-      subpixel_rendering = gfx::FontRenderParams::SUBPIXEL_RENDERING_RGB;
-    else if (strcmp(gtk_rgba, "bgr") == 0)
-      subpixel_rendering = gfx::FontRenderParams::SUBPIXEL_RENDERING_BGR;
-    else if (strcmp(gtk_rgba, "vrgb") == 0)
-      subpixel_rendering = gfx::FontRenderParams::SUBPIXEL_RENDERING_VRGB;
-    else if (strcmp(gtk_rgba, "vbgr") == 0)
-      subpixel_rendering = gfx::FontRenderParams::SUBPIXEL_RENDERING_VBGR;
-
-    g_free(gtk_rgba);
-  }
-
-  return subpixel_rendering;
-}
-
-std::string Gtk2UI::GetDefaultFontName() const {
-  GtkSettings* gtk_settings = gtk_settings_get_default();
-  CHECK(gtk_settings);
-
-  std::string out_font_name = "sans 10";
-  gchar* font_name = NULL;
-  g_object_get(gtk_settings, "gtk-font-name", &font_name, NULL);
-
-  if (font_name) {
-    out_font_name = std::string(font_name);
-    g_free(font_name);
-  }
-
-  return out_font_name;
+  // GTK multiplies the DPI by 1024 before storing it.
+  return (dpi > 0) ? dpi / 1024.0 : dpi;
 }
 
 ui::SelectFileDialog* Gtk2UI::CreateSelectFileDialog(
@@ -849,6 +851,9 @@ void Gtk2UI::LoadGtkValues() {
   SetThemeColorFromGtk(ThemeProperties::COLOR_BOOKMARK_TEXT, &label_color);
   SetThemeColorFromGtk(ThemeProperties::COLOR_STATUS_BAR_TEXT, &label_color);
 
+  default_font_description_.reset(new gfx::ScopedPangoFontDescription(
+      pango_font_description_copy(label_style->font_desc)));
+
   // Build the various icon tints.
   GetNormalButtonTintHSL(&button_tint_);
   GetNormalEntryForegroundHSL(&entry_tint_);
@@ -1043,9 +1048,7 @@ SkBitmap Gtk2UI::GenerateGtkThemeBitmap(int id) const {
       GtkStyle* style = gtk_rc_get_style(fake_window_);
       GdkColor* color = &style->bg[GTK_STATE_NORMAL];
       SkBitmap bitmap;
-      bitmap.setConfig(SkBitmap::kARGB_8888_Config,
-                       kToolbarImageWidth, kToolbarImageHeight);
-      bitmap.allocPixels();
+      bitmap.allocN32Pixels(kToolbarImageWidth, kToolbarImageHeight);
       bitmap.eraseARGB(0xff, color->red >> 8, color->green >> 8,
                        color->blue >> 8);
       return bitmap;
@@ -1099,33 +1102,19 @@ SkBitmap Gtk2UI::GenerateGtkThemeBitmap(int id) const {
     // In GTK mode, we need to manually render several icons.
     case IDR_BACK:
     case IDR_BACK_D:
-    case IDR_BACK_H:
-    case IDR_BACK_P:
     case IDR_FORWARD:
     case IDR_FORWARD_D:
-    case IDR_FORWARD_H:
-    case IDR_FORWARD_P:
     case IDR_HOME:
-    case IDR_HOME_H:
-    case IDR_HOME_P:
     case IDR_RELOAD:
     case IDR_RELOAD_D:
-    case IDR_RELOAD_H:
-    case IDR_RELOAD_P:
     case IDR_STOP:
-    case IDR_STOP_D:
-    case IDR_STOP_H:
-    case IDR_STOP_P: {
+    case IDR_STOP_D: {
       return GenerateGTKIcon(id);
     }
     case IDR_TOOLBAR_BEZEL_HOVER:
       return GenerateToolbarBezel(GTK_STATE_PRELIGHT, IDR_TOOLBAR_BEZEL_HOVER);
     case IDR_TOOLBAR_BEZEL_PRESSED:
       return GenerateToolbarBezel(GTK_STATE_ACTIVE, IDR_TOOLBAR_BEZEL_PRESSED);
-    case IDR_BROWSER_ACTION_H:
-      return GenerateToolbarBezel(GTK_STATE_PRELIGHT, IDR_BROWSER_ACTION_H);
-    case IDR_BROWSER_ACTION_P:
-      return GenerateToolbarBezel(GTK_STATE_ACTIVE, IDR_BROWSER_ACTION_P);
     default: {
       return GenerateTintedIcon(id, button_tint_);
     }
@@ -1229,10 +1218,7 @@ SkBitmap Gtk2UI::GenerateGTKIcon(int base_id) const {
   }
 
   SkBitmap retval;
-  retval.setConfig(SkBitmap::kARGB_8888_Config,
-                   default_bitmap.width(),
-                   default_bitmap.height());
-  retval.allocPixels();
+  retval.allocN32Pixels(default_bitmap.width(), default_bitmap.height());
   retval.eraseColor(0);
 
   const SkBitmap icon = GdkPixbufToImageSkia(gdk_icon);
@@ -1243,6 +1229,7 @@ SkBitmap Gtk2UI::GenerateGTKIcon(int base_id) const {
   if (gtk_state == GTK_STATE_ACTIVE || gtk_state == GTK_STATE_PRELIGHT) {
     SkBitmap border = DrawGtkButtonBorder(gtk_state,
                                           false,
+                                          false,
                                           default_bitmap.width(),
                                           default_bitmap.height());
     canvas.drawBitmap(border, 0, 0);
@@ -1261,16 +1248,14 @@ SkBitmap Gtk2UI::GenerateToolbarBezel(int gtk_state, int sizing_idr) const {
       rb.GetImageNamed(sizing_idr).AsBitmap();
 
   SkBitmap retval;
-  retval.setConfig(SkBitmap::kARGB_8888_Config,
-                   default_bitmap.width(),
-                   default_bitmap.height());
-  retval.allocPixels();
+  retval.allocN32Pixels(default_bitmap.width(), default_bitmap.height());
   retval.eraseColor(0);
 
   SkCanvas canvas(retval);
   SkBitmap border = DrawGtkButtonBorder(
       gtk_state,
       false,
+      false,
       default_bitmap.width(),
       default_bitmap.height());
   canvas.drawBitmap(border, 0, 0);
@@ -1311,6 +1296,7 @@ void Gtk2UI::GetSelectedEntryForegroundHSL(color_utils::HSL* tint) const {
 
 SkBitmap Gtk2UI::DrawGtkButtonBorder(int gtk_state,
                                      bool focused,
+                                     bool call_to_action,
                                      int width,
                                      int height) const {
   // Create a temporary GTK button to snapshot
@@ -1323,6 +1309,9 @@ SkBitmap Gtk2UI::DrawGtkButtonBorder(int gtk_state,
   gtk_widget_show(button);
   gtk_widget_show(window);
 
+  if (call_to_action)
+    GTK_WIDGET_SET_FLAGS(button, GTK_HAS_DEFAULT);
+
   if (focused) {
     // We can't just use gtk_widget_grab_focus() here because that sets
     // gtk_widget_is_focus(), but not gtk_widget_has_focus(), which is what the