summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/renderer_host/render_widget_host_view_gtk.cc17
-rw-r--r--chrome/browser/renderer_host/render_widget_host_view_gtk.h11
-rw-r--r--views/views.gyp2
-rw-r--r--views/widget/tooltip_manager_gtk.cc67
-rw-r--r--views/widget/tooltip_manager_gtk.h8
-rw-r--r--views/widget/tooltip_window_gtk.cc94
-rw-r--r--views/widget/tooltip_window_gtk.h52
7 files changed, 185 insertions, 66 deletions
diff --git a/chrome/browser/renderer_host/render_widget_host_view_gtk.cc b/chrome/browser/renderer_host/render_widget_host_view_gtk.cc
index 403480b..f0ec3a5 100644
--- a/chrome/browser/renderer_host/render_widget_host_view_gtk.cc
+++ b/chrome/browser/renderer_host/render_widget_host_view_gtk.cc
@@ -39,6 +39,10 @@
#include "third_party/WebKit/WebKit/chromium/public/gtk/WebInputEventFactory.h"
#include "webkit/glue/webcursor_gtk_data.h"
+#if defined(OS_CHROMEOS)
+#include "views/widget/tooltip_window_gtk.h"
+#endif // defined(OS_CHROMEOS)
+
static const int kMaxWindowWidth = 4000;
static const int kMaxWindowHeight = 4000;
@@ -349,6 +353,11 @@ void RenderWidgetHostViewGtk::InitAsChild() {
// |key_bindings_handler_| must be created after creating |view_| widget.
key_bindings_handler_.reset(new GtkKeyBindingsHandler(view_.get()));
plugin_container_manager_.set_host_widget(view_.get());
+
+#if defined(OS_CHROMEOS)
+ tooltip_window_.reset(new views::TooltipWindowGtk(view_.get()));
+#endif // defined(OS_CHROMEOS)
+
gtk_widget_show(view_.get());
}
@@ -363,6 +372,11 @@ void RenderWidgetHostViewGtk::InitAsPopup(
// |key_bindings_handler_| must be created after creating |view_| widget.
key_bindings_handler_.reset(new GtkKeyBindingsHandler(view_.get()));
plugin_container_manager_.set_host_widget(view_.get());
+
+#if defined(OS_CHROMEOS)
+ tooltip_window_.reset(new views::TooltipWindowGtk(view_.get()));
+#endif // defined(OS_CHROMEOS)
+
gtk_container_add(GTK_CONTAINER(popup), view_.get());
// If we are not activatable, we don't want to grab keyboard input,
@@ -608,6 +622,9 @@ void RenderWidgetHostViewGtk::SetTooltipText(const std::wstring& tooltip_text) {
} else {
gtk_widget_set_tooltip_text(view_.get(),
WideToUTF8(clamped_tooltip).c_str());
+#if defined(OS_CHROMEOS)
+ tooltip_window_->SetTooltipText(clamped_tooltip);
+#endif // defined(OS_CHROMEOS)
}
}
diff --git a/chrome/browser/renderer_host/render_widget_host_view_gtk.h b/chrome/browser/renderer_host/render_widget_host_view_gtk.h
index e5939b5..3f9d90d 100644
--- a/chrome/browser/renderer_host/render_widget_host_view_gtk.h
+++ b/chrome/browser/renderer_host/render_widget_host_view_gtk.h
@@ -26,6 +26,12 @@ class GtkKeyBindingsHandler;
class MenuGtk;
struct NativeWebKeyboardEvent;
+#if defined(OS_CHROMEOS)
+namespace views {
+class TooltipWindowGtk;
+}
+#endif // defined(OS_CHROMEOS)
+
typedef struct _GtkClipboard GtkClipboard;
typedef struct _GtkSelectionData GtkSelectionData;
@@ -179,6 +185,11 @@ class RenderWidgetHostViewGtk : public RenderWidgetHostView {
// The size that we want the renderer to be. We keep this in a separate
// variable because resizing in GTK+ is async.
gfx::Size requested_size_;
+
+#if defined(OS_CHROMEOS)
+ // Custimized tooltip window.
+ scoped_ptr<views::TooltipWindowGtk> tooltip_window_;
+#endif // defined(OS_CHROMEOS)
};
#endif // CHROME_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_VIEW_GTK_H_
diff --git a/views/views.gyp b/views/views.gyp
index 950fb86..50c15b1 100644
--- a/views/views.gyp
+++ b/views/views.gyp
@@ -277,6 +277,8 @@
'widget/tooltip_manager_win.h',
'widget/tooltip_manager.cc',
'widget/tooltip_manager.h',
+ 'widget/tooltip_window_gtk.cc',
+ 'widget/tooltip_window_gtk.h',
'widget/widget.h',
'widget/widget_gtk.cc',
'widget/widget_gtk.h',
diff --git a/views/widget/tooltip_manager_gtk.cc b/views/widget/tooltip_manager_gtk.cc
index 255f1ca..9ea6a00 100644
--- a/views/widget/tooltip_manager_gtk.cc
+++ b/views/widget/tooltip_manager_gtk.cc
@@ -71,68 +71,10 @@ int TooltipManager::GetMaxWidth(int x, int y) {
return monitor_bounds.width() == 0 ? 800 : (monitor_bounds.width() + 1) / 2;
}
-// Callback from gtk_container_foreach. If |*label_p| is NULL and |widget| is
-// a GtkLabel, |*label_p| is set to |widget|. Used to find the first GtkLabel
-// in a container.
-static void LabelLocatorCallback(GtkWidget* widget,
- gpointer label_p) {
- GtkWidget** label = static_cast<GtkWidget**>(label_p);
- if (!*label && GTK_IS_LABEL(widget))
- *label = widget;
-}
-
-// By default GtkTooltip wraps at a longish string. We want more control over
-// that wrapping. The only way to do that is dig out the label and set
-// gtk_label_set_max_width_chars, which is what this code does. I also tried
-// setting a custom widget on the tooltip, but there is a bug in Gtk that
-// triggers continually hiding/showing the widget in that case.
-static void AdjustLabel(GtkTooltip* tooltip) {
- static const char kAdjustedLabelPropertyValue[] = "_adjusted_label_";
- static const char kTooltipLabel[] = "_tooltip_label_";
- gpointer adjusted_value = g_object_get_data(G_OBJECT(tooltip),
- kAdjustedLabelPropertyValue);
- if (adjusted_value) {
- gpointer label_ptr = g_object_get_data(G_OBJECT(tooltip), kTooltipLabel);
- if (label_ptr) {
- // Setting the text in a label doesn't force recalculating wrap position.
- // We force recalculating wrap position by resetting the max width.
- gtk_label_set_max_width_chars(reinterpret_cast<GtkLabel*>(label_ptr),
- 2999);
- gtk_label_set_max_width_chars(reinterpret_cast<GtkLabel*>(label_ptr),
- 3000);
- }
- return;
- }
-
- adjusted_value = reinterpret_cast<gpointer>(1);
- g_object_set_data(G_OBJECT(tooltip), kAdjustedLabelPropertyValue,
- adjusted_value);
- GtkWidget* parent;
- {
- // Create a label so that we can get the parent. The Tooltip ends up taking
- // ownership of the label and deleting it.
- GtkWidget* label = gtk_label_new("");
- gtk_tooltip_set_custom(tooltip, label);
- parent = gtk_widget_get_parent(label);
- gtk_tooltip_set_custom(tooltip, NULL);
- }
- if (parent) {
- // We found the parent, find the first label, which is where the tooltip
- // text ends up going.
- GtkLabel* real_label = NULL;
- gtk_container_foreach(GTK_CONTAINER(parent), LabelLocatorCallback,
- static_cast<gpointer>(&real_label));
- if (real_label) {
- gtk_label_set_max_width_chars(GTK_LABEL(real_label), 3000);
- g_object_set_data(G_OBJECT(tooltip), kTooltipLabel,
- reinterpret_cast<gpointer>(real_label));
- }
- }
-}
-
TooltipManagerGtk::TooltipManagerGtk(WidgetGtk* widget)
: widget_(widget),
- keyboard_view_(NULL) {
+ keyboard_view_(NULL),
+ tooltip_window_(widget->window_contents()) {
}
bool TooltipManagerGtk::ShowTooltip(int x, int y, bool for_keyboard,
@@ -163,8 +105,6 @@ bool TooltipManagerGtk::ShowTooltip(int x, int y, bool for_keyboard,
if (!view->GetTooltipText(view_loc, &text))
return false;
- AdjustLabel(tooltip);
-
// Sets the area of the tooltip. This way if different views in the same
// widget have tooltips the tooltip doesn't get stuck at the same location.
gfx::Rect vis_bounds = view->GetVisibleBounds();
@@ -179,8 +119,7 @@ bool TooltipManagerGtk::ShowTooltip(int x, int y, bool for_keyboard,
View::ConvertPointToScreen(widget_->GetRootView(), &screen_loc);
TrimTooltipToFit(&text, &max_width, &line_count, screen_loc.x(),
screen_loc.y());
- gtk_tooltip_set_text(tooltip, WideToUTF8(text).c_str());
-
+ tooltip_window_.SetTooltipText(text);
return true;
}
diff --git a/views/widget/tooltip_manager_gtk.h b/views/widget/tooltip_manager_gtk.h
index ca690ab..d939343 100644
--- a/views/widget/tooltip_manager_gtk.h
+++ b/views/widget/tooltip_manager_gtk.h
@@ -5,10 +5,11 @@
#ifndef VIEWS_WIDGET_TOOLTIP_MANAGER_GTK_H_
#define VIEWS_WIDGET_TOOLTIP_MANAGER_GTK_H_
-#include "views/widget/tooltip_manager.h"
-
#include <gtk/gtk.h>
+#include "views/widget/tooltip_manager.h"
+#include "views/widget/tooltip_window_gtk.h"
+
namespace views {
class WidgetGtk;
@@ -40,6 +41,9 @@ class TooltipManagerGtk : public TooltipManager {
// The view supplied to the last invocation of ShowKeyboardTooltip.
View* keyboard_view_;
+ // Custimized tooltip window.
+ TooltipWindowGtk tooltip_window_;
+
DISALLOW_COPY_AND_ASSIGN(TooltipManagerGtk);
};
diff --git a/views/widget/tooltip_window_gtk.cc b/views/widget/tooltip_window_gtk.cc
new file mode 100644
index 0000000..e76338c
--- /dev/null
+++ b/views/widget/tooltip_window_gtk.cc
@@ -0,0 +1,94 @@
+// 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 "views/widget/tooltip_window_gtk.h"
+
+#include "base/utf_string_conversions.h"
+
+namespace views {
+
+TooltipWindowGtk::TooltipWindowGtk(GtkWidget* widget)
+ : host_(widget),
+ window_(NULL),
+ alignment_(NULL),
+ label_(NULL) {
+ Init();
+}
+
+TooltipWindowGtk::~TooltipWindowGtk() {
+ if (window_)
+ gtk_widget_destroy(window_);
+}
+
+void TooltipWindowGtk::SetTooltipText(const std::wstring& text) {
+ const std::string& utf8 = WideToUTF8(text);
+
+ gtk_label_set_text(label(), utf8.c_str());
+ // Setting the text in a label doesn't force recalculating wrap position.
+ // We force recalculating wrap position by resetting the max width.
+ gtk_label_set_max_width_chars(label(), 2999);
+ gtk_label_set_max_width_chars(label(), 3000);
+}
+
+void TooltipWindowGtk::Init() {
+ // Creates and setup tooltip window.
+ window_ = gtk_window_new(GTK_WINDOW_POPUP);
+ gtk_window_set_type_hint(GTK_WINDOW(window_), GDK_WINDOW_TYPE_HINT_TOOLTIP);
+ gtk_widget_set_app_paintable(window_, TRUE);
+ gtk_window_set_resizable(GTK_WINDOW(window_), FALSE);
+ gtk_widget_set_name(window_, "gtk-tooltip");
+
+ GdkColormap* rgba_colormap =
+ gdk_screen_get_rgba_colormap(gdk_screen_get_default());
+ if (rgba_colormap)
+ gtk_widget_set_colormap(window_, rgba_colormap);
+
+ g_signal_connect(G_OBJECT(window_), "expose-event",
+ G_CALLBACK(&OnPaintThunk), this);
+ g_signal_connect(G_OBJECT(window_), "style-set",
+ G_CALLBACK(&OnStyleSetThunk), this);
+
+ alignment_ = gtk_alignment_new(0.5, 0.5, 1.0, 1.0);
+ gtk_container_add(GTK_CONTAINER(window_), alignment_);
+ gtk_widget_show(alignment_);
+
+ label_ = gtk_label_new("");
+ gtk_label_set_line_wrap(GTK_LABEL(label_), TRUE);
+ gtk_label_set_max_width_chars(GTK_LABEL(label_), 3000);
+ gtk_container_add(GTK_CONTAINER(alignment_), label_);
+ gtk_widget_show(label_);
+
+ // Associates the tooltip window with given widget
+ gtk_widget_set_tooltip_window(host_, GTK_WINDOW(window_));
+}
+
+// Paints our customized tooltip window.
+gboolean TooltipWindowGtk::OnPaint(GtkWidget* widget, GdkEventExpose* event) {
+ gtk_paint_flat_box(widget->style,
+ widget->window,
+ GTK_STATE_NORMAL,
+ GTK_SHADOW_OUT,
+ NULL,
+ widget,
+ "tooltip",
+ 0, 0,
+ widget->allocation.width,
+ widget->allocation.height);
+
+ return FALSE;
+}
+
+// Style change handler.
+void TooltipWindowGtk::OnStyleSet(GtkWidget* widget,
+ GtkStyle* previous_style) {
+ gtk_alignment_set_padding(GTK_ALIGNMENT(alignment_),
+ widget->style->ythickness,
+ widget->style->ythickness,
+ widget->style->xthickness,
+ widget->style->xthickness);
+
+ gtk_widget_queue_draw(widget);
+}
+
+} // namespace views
diff --git a/views/widget/tooltip_window_gtk.h b/views/widget/tooltip_window_gtk.h
new file mode 100644
index 0000000..556fa67
--- /dev/null
+++ b/views/widget/tooltip_window_gtk.h
@@ -0,0 +1,52 @@
+// 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 VIEWS_WIDGET_TOOLTIP_WINDOW_GTK_H_
+#define VIEWS_WIDGET_TOOLTIP_WINDOW_GTK_H_
+
+#include <gtk/gtk.h>
+#include <string>
+
+#include "app/gtk_signal.h"
+
+namespace views {
+
+// TooltipWindowGtk provides a customized tooltip window and gives us a
+// chance to apply RGBA colormap on it. This enables the GTK theme engine to
+// draw tooltip with nice shadow and rounded corner on ChromeOS.
+class TooltipWindowGtk {
+ public:
+ explicit TooltipWindowGtk(GtkWidget* widget);
+ ~TooltipWindowGtk();
+
+ // Sets tooltip text to display.
+ void SetTooltipText(const std::wstring& text);
+
+ GtkLabel* label() {
+ return GTK_LABEL(label_);
+ }
+
+ protected:
+ CHROMEGTK_CALLBACK_1(TooltipWindowGtk, gboolean, OnPaint, GdkEventExpose*);
+ CHROMEGTK_CALLBACK_1(TooltipWindowGtk, void, OnStyleSet, GtkStyle*);
+
+ private:
+ void Init();
+
+ // Underlying widget of this tooltip window.
+ GtkWidget* host_;
+
+ // GtkWindow of this tooltip window.
+ GtkWidget* window_;
+
+ // The alignment and label widgets contained of the tooltip window.
+ GtkWidget* alignment_;
+ GtkWidget* label_;
+
+ DISALLOW_COPY_AND_ASSIGN(TooltipWindowGtk);
+};
+
+} // namespace views
+
+#endif // VIEWS_WIDGET_TOOLTIP_WINDOW_GTK_H_