diff options
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() { |