summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/chromeos/login/background_view.cc3
-rw-r--r--chrome/browser/chromeos/login/shutdown_button.cc3
-rw-r--r--chrome/browser/gtk/browser_actions_toolbar_gtk.cc2
-rw-r--r--chrome/browser/gtk/browser_window_gtk.cc19
-rw-r--r--chrome/browser/gtk/gtk_chrome_link_button.cc8
-rw-r--r--chrome/browser/gtk/gtk_util.cc40
-rw-r--r--chrome/browser/gtk/gtk_util.h5
-rw-r--r--chrome/browser/renderer_host/render_widget_host_view_gtk.cc54
-rw-r--r--chrome/browser/renderer_host/render_widget_host_view_views.cc8
-rw-r--r--chrome/browser/renderer_host/render_widget_host_view_views.h7
-rw-r--r--chrome/browser/ui/views/content_setting_bubble_contents.cc6
-rw-r--r--gfx/gtk_util.cc39
-rw-r--r--gfx/gtk_util.h5
-rw-r--r--views/controls/link.cc6
-rw-r--r--views/controls/resize_area.cc6
-rw-r--r--views/controls/single_split_view.cc6
-rw-r--r--views/widget/root_view.cc2
-rw-r--r--views/window/window_gtk.cc9
-rw-r--r--webkit/glue/webcursor.h11
-rw-r--r--webkit/glue/webcursor_gtk.cc33
-rw-r--r--webkit/glue/webcursor_mac.mm4
-rw-r--r--webkit/glue/webcursor_win.cc4
-rw-r--r--webkit/tools/test_shell/test_webview_delegate_gtk.cc5
23 files changed, 164 insertions, 121 deletions
diff --git a/chrome/browser/chromeos/login/background_view.cc b/chrome/browser/chromeos/login/background_view.cc
index a749489..03843ce 100644
--- a/chrome/browser/chromeos/login/background_view.cc
+++ b/chrome/browser/chromeos/login/background_view.cc
@@ -29,6 +29,7 @@
#include "chrome/browser/views/dom_view.h"
#include "cros/chromeos_wm_ipc_enums.h"
#include "googleurl/src/gurl.h"
+#include "gfx/gtk_util.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
@@ -84,7 +85,7 @@ class TextButtonWithHandCursorOver : public views::TextButton {
if (!IsEnabled()) {
return NULL;
}
- return gdk_cursor_new(GDK_HAND2);
+ return gfx::GetCursor(GDK_HAND2);
}
private:
diff --git a/chrome/browser/chromeos/login/shutdown_button.cc b/chrome/browser/chromeos/login/shutdown_button.cc
index 7a3b776..1af583a 100644
--- a/chrome/browser/chromeos/login/shutdown_button.cc
+++ b/chrome/browser/chromeos/login/shutdown_button.cc
@@ -11,6 +11,7 @@
#include "chrome/browser/chromeos/cros/power_library.h"
#include "chrome/browser/chromeos/login/rounded_rect_painter.h"
#include "chrome/browser/chromeos/view_ids.h"
+#include "gfx/gtk_util.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
#include "views/background.h"
@@ -119,7 +120,7 @@ gfx::NativeCursor ShutdownButton::GetCursorForPoint(
if (!IsEnabled()) {
return NULL;
}
- return gdk_cursor_new(GDK_HAND2);
+ return gfx::GetCursor(GDK_HAND2);
}
void ShutdownButton::ButtonPressed(views::Button* sender,
diff --git a/chrome/browser/gtk/browser_actions_toolbar_gtk.cc b/chrome/browser/gtk/browser_actions_toolbar_gtk.cc
index 4d45545..9a493ac 100644
--- a/chrome/browser/gtk/browser_actions_toolbar_gtk.cc
+++ b/chrome/browser/gtk/browser_actions_toolbar_gtk.cc
@@ -823,7 +823,7 @@ gboolean BrowserActionsToolbarGtk::OnGripperExpose(GtkWidget* gripper,
gboolean BrowserActionsToolbarGtk::OnGripperEnterNotify(
GtkWidget* gripper, GdkEventCrossing* event) {
gdk_window_set_cursor(gripper->window,
- gtk_util::GetCursor(GDK_SB_H_DOUBLE_ARROW));
+ gfx::GetCursor(GDK_SB_H_DOUBLE_ARROW));
return FALSE;
}
diff --git a/chrome/browser/gtk/browser_window_gtk.cc b/chrome/browser/gtk/browser_window_gtk.cc
index f502de6c..d08212b 100644
--- a/chrome/browser/gtk/browser_window_gtk.cc
+++ b/chrome/browser/gtk/browser_window_gtk.cc
@@ -79,6 +79,7 @@
#include "chrome/common/native_web_keyboard_event.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/pref_names.h"
+#include "gfx/gtk_util.h"
#include "gfx/rect.h"
#include "gfx/skia_utils_gtk.h"
#include "grit/app_resources.h"
@@ -369,11 +370,6 @@ BrowserWindowGtk::~BrowserWindowGtk() {
ActiveWindowWatcherX::RemoveObserver(this);
browser_->tabstrip_model()->RemoveObserver(this);
-
- if (frame_cursor_) {
- gdk_cursor_unref(frame_cursor_);
- frame_cursor_ = NULL;
- }
}
gboolean BrowserWindowGtk::OnCustomFrameExpose(GtkWidget* widget,
@@ -1403,7 +1399,6 @@ void BrowserWindowGtk::ResetCustomFrameCursor() {
if (!frame_cursor_)
return;
- gdk_cursor_unref(frame_cursor_);
frame_cursor_ = NULL;
gdk_window_set_cursor(GTK_WIDGET(window_)->window, NULL);
}
@@ -1895,7 +1890,6 @@ gboolean BrowserWindowGtk::OnMouseMoveEvent(GtkWidget* widget,
if (!UseCustomFrame() || event->window != widget->window) {
// Reset the cursor.
if (frame_cursor_) {
- gdk_cursor_unref(frame_cursor_);
frame_cursor_ = NULL;
gdk_window_set_cursor(GTK_WIDGET(window_)->window, NULL);
}
@@ -1915,17 +1909,12 @@ gboolean BrowserWindowGtk::OnMouseMoveEvent(GtkWidget* widget,
last_cursor = frame_cursor_->type;
if (last_cursor != new_cursor) {
- if (frame_cursor_) {
- gdk_cursor_unref(frame_cursor_);
- frame_cursor_ = NULL;
- }
if (has_hit_edge) {
- frame_cursor_ = gtk_util::GetCursor(new_cursor);
- gdk_window_set_cursor(GTK_WIDGET(window_)->window,
- frame_cursor_);
+ frame_cursor_ = gfx::GetCursor(new_cursor);
} else {
- gdk_window_set_cursor(GTK_WIDGET(window_)->window, NULL);
+ frame_cursor_ = NULL;
}
+ gdk_window_set_cursor(GTK_WIDGET(window_)->window, frame_cursor_);
}
return FALSE;
}
diff --git a/chrome/browser/gtk/gtk_chrome_link_button.cc b/chrome/browser/gtk/gtk_chrome_link_button.cc
index 6c94600..0da375f 100644
--- a/chrome/browser/gtk/gtk_chrome_link_button.cc
+++ b/chrome/browser/gtk/gtk_chrome_link_button.cc
@@ -7,6 +7,7 @@
#include <stdlib.h>
#include "chrome/browser/gtk/gtk_util.h"
+#include "gfx/gtk_util.h"
static const gchar* kLinkMarkup = "<u><span color=\"%s\">%s</span></u>";
@@ -161,10 +162,7 @@ static void gtk_chrome_link_button_destroy(GtkObject* object) {
gtk_chrome_link_button_destroy_text_resources(button);
- if (button->hand_cursor) {
- gdk_cursor_unref(button->hand_cursor);
- button->hand_cursor = NULL;
- }
+ button->hand_cursor = NULL;
GTK_OBJECT_CLASS(gtk_chrome_link_button_parent_class)->destroy(object);
}
@@ -196,7 +194,7 @@ static void gtk_chrome_link_button_init(GtkChromeLinkButton* button) {
strncpy(button->normal_color, "blue", 9);
button->native_markup = NULL;
button->using_native_theme = TRUE;
- button->hand_cursor = gtk_util::GetCursor(GDK_HAND2);
+ button->hand_cursor = gfx::GetCursor(GDK_HAND2);
button->text = NULL;
gtk_container_add(GTK_CONTAINER(button), button->label);
diff --git a/chrome/browser/gtk/gtk_util.cc b/chrome/browser/gtk/gtk_util.cc
index e07d990..e65def3 100644
--- a/chrome/browser/gtk/gtk_util.cc
+++ b/chrome/browser/gtk/gtk_util.cc
@@ -127,41 +127,6 @@ GList* GetIconList() {
return icon_list;
}
-// A process wide singleton that manages our usage of gdk
-// cursors. gdk_cursor_new() hits the disk in several places and GdkCursor
-// instances can be reused throughout the process.
-class GdkCursorCache {
- public:
- ~GdkCursorCache() {
- for (std::map<GdkCursorType, GdkCursor*>::iterator it =
- cursor_cache_.begin(); it != cursor_cache_.end(); ++it) {
- gdk_cursor_unref(it->second);
- }
- cursor_cache_.clear();
- }
-
- GdkCursor* GetCursorImpl(GdkCursorType type) {
- std::map<GdkCursorType, GdkCursor*>::iterator it = cursor_cache_.find(type);
- GdkCursor* cursor = NULL;
- if (it == cursor_cache_.end()) {
- cursor = gdk_cursor_new(type);
- cursor_cache_.insert(std::make_pair(type, cursor));
- } else {
- cursor = it->second;
- }
-
- // Add a reference to the returned cursor because our consumers mix us with
- // gdk_cursor_new(). Both the normal constructor and GetCursorImpls() need
- // to be paired with a gdk_cursor_unref() so ref it here (as we own the ref
- // that comes from gdk_cursor_new().
- gdk_cursor_ref(cursor);
-
- return cursor;
- }
-
- std::map<GdkCursorType, GdkCursor*> cursor_cache_;
-};
-
// Expose event handler for a container that simply suppresses the default
// drawing and propagates the expose event to the container's children.
gboolean PaintNoBackground(GtkWidget* widget,
@@ -876,11 +841,6 @@ void SetAlwaysShowImage(GtkWidget* image_menu_item) {
#endif
}
-GdkCursor* GetCursor(GdkCursorType type) {
- static GdkCursorCache impl;
- return impl.GetCursorImpl(type);
-}
-
void StackPopupWindow(GtkWidget* popup, GtkWidget* toplevel) {
DCHECK(GTK_IS_WINDOW(popup) && GTK_WIDGET_TOPLEVEL(popup) &&
GTK_WIDGET_REALIZED(popup));
diff --git a/chrome/browser/gtk/gtk_util.h b/chrome/browser/gtk/gtk_util.h
index c8c3c4f..894abc6 100644
--- a/chrome/browser/gtk/gtk_util.h
+++ b/chrome/browser/gtk/gtk_util.h
@@ -260,11 +260,6 @@ GdkColor AverageColors(GdkColor color_one, GdkColor color_two);
// crucial to its functionality.
void SetAlwaysShowImage(GtkWidget* image_menu_item);
-// Returns a static instance of a GdkCursor* object, sharable across the
-// process. Returns a GdkCursor with a +1 refcount, as if it was just created
-// with gdk_cursor_new(); owner must gdk_cursor_unref() it when done with it.
-GdkCursor* GetCursor(GdkCursorType type);
-
// Stacks a |popup| window directly on top of a |toplevel| window.
void StackPopupWindow(GtkWidget* popup, GtkWidget* toplevel);
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 414c540..9d824fc 100644
--- a/chrome/browser/renderer_host/render_widget_host_view_gtk.cc
+++ b/chrome/browser/renderer_host/render_widget_host_view_gtk.cc
@@ -898,40 +898,34 @@ void RenderWidgetHostViewGtk::ShowCurrentCursor() {
if (!view_.get()->window)
return;
+ // TODO(port): WebKit bug https://bugs.webkit.org/show_bug.cgi?id=16388 is
+ // that calling gdk_window_set_cursor repeatedly is expensive. We should
+ // avoid it here where possible.
GdkCursor* gdk_cursor;
- switch (current_cursor_.GetCursorType()) {
- case GDK_CURSOR_IS_PIXMAP:
- // TODO(port): WebKit bug https://bugs.webkit.org/show_bug.cgi?id=16388 is
- // that calling gdk_window_set_cursor repeatedly is expensive. We should
- // avoid it here where possible.
- gdk_cursor = current_cursor_.GetCustomCursor();
- break;
-
- case GDK_LAST_CURSOR:
- if (is_loading_) {
- // Use MOZ_CURSOR_SPINNING if we are showing the default cursor and
- // the page is loading.
- static const GdkColor fg = { 0, 0, 0, 0 };
- static const GdkColor bg = { 65535, 65535, 65535, 65535 };
- GdkPixmap* source =
- gdk_bitmap_create_from_data(NULL, moz_spinning_bits, 32, 32);
- GdkPixmap* mask =
- gdk_bitmap_create_from_data(NULL, moz_spinning_mask_bits, 32, 32);
- gdk_cursor = gdk_cursor_new_from_pixmap(source, mask, &fg, &bg, 2, 2);
- g_object_unref(source);
- g_object_unref(mask);
- } else {
- gdk_cursor = NULL;
- }
- break;
-
- default:
- gdk_cursor = gtk_util::GetCursor(
- static_cast<GdkCursorType>(current_cursor_.GetCursorType()));
+ bool should_unref = false;
+ if (current_cursor_.GetCursorType() == GDK_LAST_CURSOR) {
+ if (is_loading_) {
+ // Use MOZ_CURSOR_SPINNING if we are showing the default cursor and
+ // the page is loading.
+ static const GdkColor fg = { 0, 0, 0, 0 };
+ static const GdkColor bg = { 65535, 65535, 65535, 65535 };
+ GdkPixmap* source =
+ gdk_bitmap_create_from_data(NULL, moz_spinning_bits, 32, 32);
+ GdkPixmap* mask =
+ gdk_bitmap_create_from_data(NULL, moz_spinning_mask_bits, 32, 32);
+ gdk_cursor = gdk_cursor_new_from_pixmap(source, mask, &fg, &bg, 2, 2);
+ should_unref = true;
+ g_object_unref(source);
+ g_object_unref(mask);
+ } else {
+ gdk_cursor = NULL;
+ }
+ } else {
+ gdk_cursor = current_cursor_.GetNativeCursor();
}
gdk_window_set_cursor(view_.get()->window, gdk_cursor);
// The window now owns the cursor.
- if (gdk_cursor)
+ if (should_unref && gdk_cursor)
gdk_cursor_unref(gdk_cursor);
}
diff --git a/chrome/browser/renderer_host/render_widget_host_view_views.cc b/chrome/browser/renderer_host/render_widget_host_view_views.cc
index f5cdaeb..591e398 100644
--- a/chrome/browser/renderer_host/render_widget_host_view_views.cc
+++ b/chrome/browser/renderer_host/render_widget_host_view_views.cc
@@ -76,6 +76,7 @@ RenderWidgetHostViewViews::RenderWidgetHostViewViews(RenderWidgetHost* host)
about_to_validate_and_paint_(false),
is_hidden_(false),
is_loading_(false),
+ native_cursor_(NULL),
is_showing_context_menu_(false),
visually_deemphasized_(false) {
SetFocusable(true);
@@ -365,6 +366,11 @@ void RenderWidgetHostViewViews::Paint(gfx::Canvas* canvas) {
}
}
+gfx::NativeCursor RenderWidgetHostViewViews::GetCursorForPoint(
+ views::Event::EventType type, const gfx::Point& point) {
+ return native_cursor_;
+}
+
bool RenderWidgetHostViewViews::OnMousePressed(const views::MouseEvent& event) {
RequestFocus();
@@ -511,7 +517,7 @@ void RenderWidgetHostViewViews::ShowCurrentCursor() {
if (!native_view()->window)
return;
- // TODO(anicolao): change to set cursors without GTK
+ native_cursor_ = current_cursor_.GetNativeCursor();
}
void RenderWidgetHostViewViews::CreatePluginContainer(
diff --git a/chrome/browser/renderer_host/render_widget_host_view_views.h b/chrome/browser/renderer_host/render_widget_host_view_views.h
index 0ef343e..88a4746 100644
--- a/chrome/browser/renderer_host/render_widget_host_view_views.h
+++ b/chrome/browser/renderer_host/render_widget_host_view_views.h
@@ -81,6 +81,10 @@ class RenderWidgetHostViewViews : public RenderWidgetHostView,
virtual void Paint(gfx::Canvas* canvas);
+ // Overridden from views::View.
+ gfx::NativeCursor GetCursorForPoint(views::Event::EventType type,
+ const gfx::Point& point);
+
// Views mouse events
virtual bool OnMousePressed(const views::MouseEvent& event);
virtual bool OnMouseDragged(const views::MouseEvent& event);
@@ -138,6 +142,9 @@ class RenderWidgetHostViewViews : public RenderWidgetHostView,
// The cursor for the page. This is passed up from the renderer.
WebCursor current_cursor_;
+ // The native cursor.
+ gfx::NativeCursor native_cursor_;
+
// Whether we are showing a context menu.
bool is_showing_context_menu_;
diff --git a/chrome/browser/ui/views/content_setting_bubble_contents.cc b/chrome/browser/ui/views/content_setting_bubble_contents.cc
index cea404d..40a2acc 100644
--- a/chrome/browser/ui/views/content_setting_bubble_contents.cc
+++ b/chrome/browser/ui/views/content_setting_bubble_contents.cc
@@ -30,6 +30,10 @@
#include "views/standard_layout.h"
#include "webkit/glue/plugins/plugin_list.h"
+#if defined(OS_LINUX)
+#include "gfx/gtk_util.h"
+#endif
+
// If we don't clamp the maximum width, then very long URLs and titles can make
// the bubble arbitrarily wide.
const int kMaxContentsWidth = 500;
@@ -99,7 +103,7 @@ gfx::NativeCursor ContentSettingBubbleContents::Favicon::GetCursorForPoint(
g_hand_cursor = LoadCursor(NULL, IDC_HAND);
return g_hand_cursor;
#elif defined(OS_LINUX)
- return gdk_cursor_new(GDK_HAND2);
+ return gfx::GetCursor(GDK_HAND2);
#endif
}
diff --git a/gfx/gtk_util.cc b/gfx/gtk_util.cc
index b30b827..96195fe 100644
--- a/gfx/gtk_util.cc
+++ b/gfx/gtk_util.cc
@@ -17,6 +17,40 @@
namespace {
+// A process wide singleton that manages our usage of gdk
+// cursors. gdk_cursor_new() hits the disk in several places and GdkCursor
+// instances can be reused throughout the process.
+class GdkCursorCache {
+ public:
+ GdkCursorCache() {}
+ ~GdkCursorCache() {
+ for (std::map<GdkCursorType, GdkCursor*>::iterator it =
+ cursor_cache_.begin(); it != cursor_cache_.end(); ++it) {
+ gdk_cursor_unref(it->second);
+ }
+ cursor_cache_.clear();
+ }
+
+ GdkCursor* GetCursorImpl(GdkCursorType type) {
+ std::map<GdkCursorType, GdkCursor*>::iterator it = cursor_cache_.find(type);
+ GdkCursor* cursor = NULL;
+ if (it == cursor_cache_.end()) {
+ cursor = gdk_cursor_new(type);
+ cursor_cache_.insert(std::make_pair(type, cursor));
+ } else {
+ cursor = it->second;
+ }
+
+ // It is not necessary to add a reference here. The callers can ref the
+ // cursor if they need it for something.
+ return cursor;
+ }
+
+ std::map<GdkCursorType, GdkCursor*> cursor_cache_;
+
+ DISALLOW_COPY_AND_ASSIGN(GdkCursorCache);
+};
+
void FreePixels(guchar* pixels, gpointer data) {
free(data);
}
@@ -146,6 +180,11 @@ double GetPangoResolution() {
return resolution;
}
+GdkCursor* GetCursor(int type) {
+ static GdkCursorCache impl;
+ return impl.GetCursorImpl(static_cast<GdkCursorType>(type));
+}
+
std::string ConvertAcceleratorsFromWindowsStyle(const std::string& label) {
return ConvertAmperstandsTo(label, "_");
}
diff --git a/gfx/gtk_util.h b/gfx/gtk_util.h
index 8f9618d..683b80c 100644
--- a/gfx/gtk_util.h
+++ b/gfx/gtk_util.h
@@ -16,6 +16,7 @@
typedef struct _GdkPixbuf GdkPixbuf;
typedef struct _GdkRegion GdkRegion;
+typedef struct _GdkCursor GdkCursor;
class CommandLine;
class SkBitmap;
@@ -42,6 +43,10 @@ void SubtractRectanglesFromRegion(GdkRegion* region,
// resolution hasn't been set.
double GetPangoResolution();
+// Returns a static instance of a GdkCursor* object, sharable across the
+// process. Caller must gdk_cursor_ref() it if they want to assume ownership.
+GdkCursor* GetCursor(int type);
+
// Change windows accelerator style to GTK style. (GTK uses _ for
// accelerators. Windows uses & with && as an escape for &.)
std::string ConvertAcceleratorsFromWindowsStyle(const std::string& label);
diff --git a/views/controls/link.cc b/views/controls/link.cc
index b392902..6101e49 100644
--- a/views/controls/link.cc
+++ b/views/controls/link.cc
@@ -14,6 +14,10 @@
#include "gfx/font.h"
#include "views/event.h"
+#if defined(OS_LINUX)
+#include "gfx/gtk_util.h"
+#endif
+
namespace {
void GetColors(const SkColor* background_color, // NULL means "use default"
@@ -170,7 +174,7 @@ gfx::NativeCursor Link::GetCursorForPoint(Event::EventType event_type,
g_hand_cursor = LoadCursor(NULL, IDC_HAND);
return g_hand_cursor;
#elif defined(OS_LINUX)
- return gdk_cursor_new(GDK_HAND2);
+ return gfx::GetCursor(GDK_HAND2);
#endif
}
diff --git a/views/controls/resize_area.cc b/views/controls/resize_area.cc
index 950d97c..56a78b8 100644
--- a/views/controls/resize_area.cc
+++ b/views/controls/resize_area.cc
@@ -7,6 +7,10 @@
#include "app/resource_bundle.h"
#include "base/logging.h"
+#if defined(OS_LINUX)
+#include "gfx/gtk_util.h"
+#endif
+
namespace views {
const char ResizeArea::kViewClassName[] = "views/ResizeArea";
@@ -39,7 +43,7 @@ gfx::NativeCursor ResizeArea::GetCursorForPoint(Event::EventType event_type,
g_resize_cursor = LoadCursor(NULL, IDC_SIZEWE);
return g_resize_cursor;
#elif defined(OS_LINUX)
- return gdk_cursor_new(GDK_SB_H_DOUBLE_ARROW);
+ return gfx::GetCursor(GDK_SB_H_DOUBLE_ARROW);
#endif
}
diff --git a/views/controls/single_split_view.cc b/views/controls/single_split_view.cc
index debe716..f997f31 100644
--- a/views/controls/single_split_view.cc
+++ b/views/controls/single_split_view.cc
@@ -12,6 +12,10 @@
#include "skia/ext/skia_utils_win.h"
#include "views/background.h"
+#if defined(OS_LINUX)
+#include "gfx/gtk_util.h"
+#endif
+
namespace views {
// Size of the divider in pixels.
@@ -128,7 +132,7 @@ gfx::NativeCursor SingleSplitView::GetCursorForPoint(
static HCURSOR ns_resize_cursor = LoadCursor(NULL, IDC_SIZENS);
return is_horizontal_ ? we_resize_cursor : ns_resize_cursor;
#elif defined(OS_LINUX)
- return gdk_cursor_new(is_horizontal_ ?
+ return gfx::GetCursor(is_horizontal_ ?
GDK_SB_H_DOUBLE_ARROW :
GDK_SB_V_DOUBLE_ARROW);
#endif
diff --git a/views/widget/root_view.cc b/views/widget/root_view.cc
index 91d639c..753e9de 100644
--- a/views/widget/root_view.cc
+++ b/views/widget/root_view.cc
@@ -779,8 +779,6 @@ void RootView::SetActiveCursor(gfx::NativeCursor cursor) {
if (!native_view)
return;
gdk_window_set_cursor(native_view->window, cursor);
- if (cursor)
- gdk_cursor_destroy(cursor);
#endif
}
diff --git a/views/window/window_gtk.cc b/views/window/window_gtk.cc
index 3d7f788..d59d7a5 100644
--- a/views/window/window_gtk.cc
+++ b/views/window/window_gtk.cc
@@ -7,6 +7,7 @@
#include "gfx/rect.h"
#include "base/i18n/rtl.h"
#include "base/utf_string_conversions.h"
+#include "gfx/gtk_util.h"
#include "gfx/path.h"
#include "views/event.h"
#include "views/screen.h"
@@ -329,9 +330,7 @@ gboolean WindowGtk::OnMotionNotify(GtkWidget* widget, GdkEventMotion* event) {
non_client_view_->NonClientHitTest(gfx::Point(x, y));
if (hittest_code != HTCLIENT) {
GdkCursorType cursor_type = HitTestCodeToGdkCursorType(hittest_code);
- GdkCursor* cursor = gdk_cursor_new(cursor_type);
- gdk_window_set_cursor(widget->window, cursor);
- gdk_cursor_destroy(cursor);
+ gdk_window_set_cursor(widget->window, gfx::GetCursor(cursor_type));
}
return WidgetGtk::OnMotionNotify(widget, event);
@@ -362,9 +361,7 @@ gboolean WindowGtk::OnWindowStateEvent(GtkWidget* widget,
}
gboolean WindowGtk::OnLeaveNotify(GtkWidget* widget, GdkEventCrossing* event) {
- GdkCursor* cursor = gdk_cursor_new(GDK_LEFT_PTR);
- gdk_window_set_cursor(widget->window, cursor);
- gdk_cursor_destroy(cursor);
+ gdk_window_set_cursor(widget->window, gfx::GetCursor(GDK_LEFT_PTR));
return WidgetGtk::OnLeaveNotify(widget, event);
}
diff --git a/webkit/glue/webcursor.h b/webkit/glue/webcursor.h
index 35eb001..daad15f 100644
--- a/webkit/glue/webcursor.h
+++ b/webkit/glue/webcursor.h
@@ -6,6 +6,7 @@
#define WEBKIT_GLUE_WEBCURSOR_H_
#include "base/basictypes.h"
+#include "gfx/native_widget_types.h"
#include "gfx/point.h"
#include "gfx/size.h"
@@ -65,6 +66,9 @@ class WebCursor {
// compare the bitmaps to verify whether they are equal.
bool IsEqual(const WebCursor& other) const;
+ // Returns a native cursor representing the current WebCursor instance.
+ gfx::NativeCursor GetNativeCursor();
+
#if defined(OS_WIN)
// Returns a HCURSOR representing the current WebCursor instance.
// The ownership of the HCURSOR (does not apply to external cursors) remains
@@ -85,7 +89,7 @@ class WebCursor {
// Return a new GdkCursor* for this cursor. Only valid if GetCursorType
// returns GDK_CURSOR_IS_PIXMAP.
- GdkCursor* GetCustomCursor() const;
+ GdkCursor* GetCustomCursor();
#elif defined(OS_MACOSX)
// Gets an NSCursor* for this cursor.
NSCursor* GetCursor() const;
@@ -147,6 +151,11 @@ class WebCursor {
// A custom cursor created from custom bitmap data by Webkit.
HCURSOR custom_cursor_;
#endif // OS_WIN
+
+#if defined(USE_X11)
+ // A custom cursor created that should be unref'ed from the destructor.
+ GdkCursor* unref_;
+#endif
};
#endif // WEBKIT_GLUE_WEBCURSOR_H_
diff --git a/webkit/glue/webcursor_gtk.cc b/webkit/glue/webcursor_gtk.cc
index 6734ef2..1ff8316 100644
--- a/webkit/glue/webcursor_gtk.cc
+++ b/webkit/glue/webcursor_gtk.cc
@@ -22,9 +22,12 @@ namespace {
// It attempts to create a custom cursor from the data inlined in
// webcursor_gtk_data.h.
GdkCursor* GetInlineCustomCursor(CustomCursorType type) {
+ static GdkCursor* CustomCursorsGdk[G_N_ELEMENTS(CustomCursors)];
+ GdkCursor* cursor = CustomCursorsGdk[type];
+ if (cursor)
+ return cursor;
const CustomCursor& custom = CustomCursors[type];
- GdkCursor* cursor = gdk_cursor_new_from_name(gdk_display_get_default(),
- custom.name);
+ cursor = gdk_cursor_new_from_name(gdk_display_get_default(), custom.name);
if (!cursor) {
const GdkColor fg = { 0, 0, 0, 0 };
const GdkColor bg = { 65535, 65535, 65535, 65535 };
@@ -37,6 +40,7 @@ GdkCursor* GetInlineCustomCursor(CustomCursorType type) {
g_object_unref(source);
g_object_unref(mask);
}
+ CustomCursorsGdk[type] = cursor;
return cursor;
}
@@ -45,11 +49,13 @@ GdkCursor* GetInlineCustomCursor(CustomCursorType type) {
#if !GTK_CHECK_VERSION(2, 16, 0)
// Get/create a custom cursor which is invisible.
GdkCursor* GetInvisibleCustomCursor() {
+ static GdkCursor* cursor = NULL;
+ if (cursor)
+ return cursor;
const char bits[] = { 0 };
const GdkColor color = { 0, 0, 0, 0 };
GdkPixmap* bitmap = gdk_bitmap_create_from_data(NULL, bits, 1, 1);
- GdkCursor* cursor =
- gdk_cursor_new_from_pixmap(bitmap, bitmap, &color, &color, 0, 0);
+ cursor = gdk_cursor_new_from_pixmap(bitmap, bitmap, &color, &color, 0, 0);
g_object_unref(bitmap);
return cursor;
}
@@ -154,7 +160,14 @@ int WebCursor::GetCursorType() const {
return GDK_LAST_CURSOR;
}
-GdkCursor* WebCursor::GetCustomCursor() const {
+gfx::NativeCursor WebCursor::GetNativeCursor() {
+ int type = GetCursorType();
+ if (type == GDK_CURSOR_IS_PIXMAP)
+ return GetCustomCursor();
+ return gfx::GetCursor(type);
+}
+
+GdkCursor* WebCursor::GetCustomCursor() {
switch (type_) {
// See comment above |GetInvisibleCustomCursor()|.
#if !GTK_CHECK_VERSION(2, 16, 0)
@@ -186,10 +199,14 @@ GdkCursor* WebCursor::GetCustomCursor() const {
gdk_pixbuf_unref(pixbuf);
+ if (unref_)
+ gdk_cursor_unref(unref_);
+ unref_ = cursor;
return cursor;
}
void WebCursor::InitPlatformData() {
+ unref_ = NULL;
return;
}
@@ -206,9 +223,15 @@ bool WebCursor::IsPlatformDataEqual(const WebCursor& other) const {
}
void WebCursor::CleanupPlatformData() {
+ if (unref_) {
+ gdk_cursor_unref(unref_);
+ unref_ = NULL;
+ }
return;
}
void WebCursor::CopyPlatformData(const WebCursor& other) {
+ if (other.unref_)
+ unref_ = gdk_cursor_ref(other.unref_);
return;
}
diff --git a/webkit/glue/webcursor_mac.mm b/webkit/glue/webcursor_mac.mm
index 6b2729e..1aeb1e0 100644
--- a/webkit/glue/webcursor_mac.mm
+++ b/webkit/glue/webcursor_mac.mm
@@ -160,6 +160,10 @@ NSCursor* WebCursor::GetCursor() const {
return nil;
}
+gfx::NativeCursor WebCursor::GetNativeCursor() {
+ return GetCursor();
+}
+
void WebCursor::InitFromThemeCursor(ThemeCursor cursor) {
WebKit::WebCursorInfo cursor_info;
diff --git a/webkit/glue/webcursor_win.cc b/webkit/glue/webcursor_win.cc
index 4435e06..2141969 100644
--- a/webkit/glue/webcursor_win.cc
+++ b/webkit/glue/webcursor_win.cc
@@ -186,6 +186,10 @@ HCURSOR WebCursor::GetCursor(HINSTANCE module_handle){
return custom_cursor_;
}
+gfx::NativeCursor WebCursor::GetNativeCursor() {
+ return GetCursor(NULL);
+}
+
void WebCursor::InitFromExternalCursor(HCURSOR cursor) {
WebCursorInfo::Type cursor_type = ToCursorType(cursor);
diff --git a/webkit/tools/test_shell/test_webview_delegate_gtk.cc b/webkit/tools/test_shell/test_webview_delegate_gtk.cc
index ed99cbb..51cfde3 100644
--- a/webkit/tools/test_shell/test_webview_delegate_gtk.cc
+++ b/webkit/tools/test_shell/test_webview_delegate_gtk.cc
@@ -131,13 +131,10 @@ void TestWebViewDelegate::didChangeCursor(const WebCursorInfo& cursor_info) {
if (cursor_type == GDK_LAST_CURSOR)
gdk_cursor = NULL;
else
- gdk_cursor = gdk_cursor_new(cursor_type);
+ gdk_cursor = gfx::GetCursor(cursor_type);
}
cursor_type_ = cursor_type;
gdk_window_set_cursor(shell_->webViewWnd()->window, gdk_cursor);
- // The window now owns the cursor.
- if (gdk_cursor)
- gdk_cursor_unref(gdk_cursor);
}
WebRect TestWebViewDelegate::windowRect() {