summaryrefslogtreecommitdiffstats
path: root/webkit/glue/webcursor_win.cc
diff options
context:
space:
mode:
authorananta@chromium.org <ananta@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-01-09 01:20:38 +0000
committerananta@chromium.org <ananta@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-01-09 01:20:38 +0000
commitcf4e5eb1df0fcbf192584b61e83e0b85cf23a1cf (patch)
treebce3c121d9679666d8acdf73cb082a684cf491e4 /webkit/glue/webcursor_win.cc
parent710e056bd5005f8d0f9f9d5f4b8623f9c9dd7004 (diff)
downloadchromium_src-cf4e5eb1df0fcbf192584b61e83e0b85cf23a1cf.zip
chromium_src-cf4e5eb1df0fcbf192584b61e83e0b85cf23a1cf.tar.gz
chromium_src-cf4e5eb1df0fcbf192584b61e83e0b85cf23a1cf.tar.bz2
Add support for custom cursors set by windowless plugins. Windowless plugins typically set the cursor in NPP_HandleEvent for WM_MOUSEMOVE.The current implementation looks for the cursor type and if the typedoes not match predefinedcursor types defaults to the pointer cursor.
The fixes are as below:- 1. Marshal the HCURSOR after copying it to ensure that it remains valid. This works as a HCURSOR is a user object and can be used across processes. Ideally we would like to convert it to a skia bitmap but there are issues with converting monochrome cursors. 2. Added support for marshaling platform specific data in the webcursor Serialize/Deserialize functions. This is in the form of functions like InitPlatformData, SerializePlatformData, DeserializePlatformData, etc. which are stubbed out for the other platforms. 3. Mimic webkit windowless plugin behavior where it sets a flag to ignore the next setCursor after HandleEvent of WM_MOUSEMOVE. If we don't do this the cursor keeps changing between a pointerCursor and the cursor set by the plugin which also causes flicker. 4. Fixed the WebCursor::IsEqual function to ensure that it checks all fields for equality. 5. The browser(RenderWidgetHostViewWin) now maintains a WebCursor instance representing the current cursor. Any cursor updates received from the renderer update the current cursor member maintained by the browser. 6. We intercept the SetCursor API for windowless plugins like Flash and Silverlight and remember the cursor being set. We don't invoke the original API as the browser UI thread would do it anyways. This fixes the annoying cursor flicker caused by the windowless flash plugin instance constantly setting the cursor even when the tab is not visible. This fixes bug http://code.google.com/p/chromium/issues/detail?id=3800. Review URL: http://codereview.chromium.org/15088 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@7798 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/glue/webcursor_win.cc')
-rw-r--r--webkit/glue/webcursor_win.cc83
1 files changed, 66 insertions, 17 deletions
diff --git a/webkit/glue/webcursor_win.cc b/webkit/glue/webcursor_win.cc
index f4d05d8..b529e06 100644
--- a/webkit/glue/webcursor_win.cc
+++ b/webkit/glue/webcursor_win.cc
@@ -9,6 +9,7 @@
#undef LOG
#include "base/gfx/gdi_util.h"
#include "base/logging.h"
+#include "base/pickle.h"
#include "skia/include/SkBitmap.h"
#include "webkit/glue/webcursor.h"
#include "webkit/glue/webkit_resources.h"
@@ -131,24 +132,27 @@ static PlatformCursor::Type ToPlatformCursorType(HCURSOR cursor) {
if (cursor == kStandardCursors[i].cursor)
return kStandardCursors[i].type;
}
- return PlatformCursor::typePointer;
+ return PlatformCursor::typeCustom;
}
-HCURSOR WebCursor::GetCursor(HINSTANCE module_handle) const {
- if (IsCustom())
- return NULL;
+HCURSOR WebCursor::GetCursor(HINSTANCE module_handle){
+ if (!IsCustom()) {
+ const wchar_t* cursor_id =
+ ToCursorID(static_cast<PlatformCursor::Type>(type_));
- LPCWSTR cursor_id = ToCursorID(static_cast<PlatformCursor::Type>(type_));
+ if (IsSystemCursorID(cursor_id))
+ module_handle = NULL;
- if (IsSystemCursorID(cursor_id))
- module_handle = NULL;
+ return LoadCursor(module_handle, cursor_id);
+ }
- return LoadCursor(module_handle, cursor_id);
-}
+ if (custom_cursor_) {
+ DCHECK(external_cursor_ == NULL);
+ return custom_cursor_;
+ }
-HCURSOR WebCursor::GetCustomCursor() const {
- if (!IsCustom())
- return NULL;
+ if (external_cursor_)
+ return external_cursor_;
BITMAPINFO cursor_bitmap_info = {0};
gfx::CreateBitmapHeader(
@@ -176,16 +180,61 @@ HCURSOR WebCursor::GetCustomCursor() const {
ii.hbmMask = mask;
ii.hbmColor = bitmap_handle;
- HCURSOR cursor_handle = CreateIconIndirect(&ii);
+ custom_cursor_ = CreateIconIndirect(&ii);
DeleteObject(mask);
DeleteObject(bitmap_handle);
DeleteDC(workingDC);
ReleaseDC(0, dc);
- return cursor_handle;
+ return custom_cursor_;
+}
+
+void WebCursor::InitFromExternalCursor(HCURSOR cursor) {
+ WebCore::PlatformCursor::Type cursor_type = ToPlatformCursorType(cursor);
+
+ *this = WebCursor(cursor_type);
+
+ if (cursor_type == WebCore::PlatformCursor::typeCustom) {
+ external_cursor_ = cursor;
+ }
}
-void WebCursor::InitFromCursor(HCURSOR cursor) {
- // TODO(iyengar) Add support for custom cursors.
- *this = WebCursor(ToPlatformCursorType(cursor));
+void WebCursor::InitPlatformData() {
+ external_cursor_ = NULL;
+ custom_cursor_ = NULL;
+}
+
+bool WebCursor::SerializePlatformData(Pickle* pickle) const {
+ // There are some issues with converting certain HCURSORS to bitmaps. The
+ // HCURSOR being a user object can be marshaled as is.
+ return pickle->WriteIntPtr(reinterpret_cast<intptr_t>(external_cursor_));
+}
+
+bool WebCursor::DeserializePlatformData(const Pickle* pickle, void** iter) {
+ return pickle->ReadIntPtr(iter,
+ reinterpret_cast<intptr_t*>(&external_cursor_));
+}
+
+bool WebCursor::IsPlatformDataEqual(const WebCursor& other) const {
+ if (!IsCustom())
+ return true;
+
+ return (external_cursor_ == other.external_cursor_);
+}
+
+void WebCursor::CopyPlatformData(const WebCursor& other) {
+ external_cursor_ = other.external_cursor_;
+ // The custom_cursor_ member will be initialized to a HCURSOR the next time
+ // the GetCursor member function is invoked on this WebCursor instance. The
+ // cursor is created using the data in the custom_data_ vector.
+ custom_cursor_ = NULL;
+}
+
+void WebCursor::CleanupPlatformData() {
+ external_cursor_ = NULL;
+
+ if (custom_cursor_) {
+ DestroyIcon(custom_cursor_);
+ custom_cursor_ = NULL;
+ }
}