Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(92)

Unified Diff: webkit/glue/plugins/webplugin_delegate_impl.cc

Issue 15088: Add support for custom cursors set by windowless plugins. Windowless plugins... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « webkit/glue/plugins/webplugin_delegate_impl.h ('k') | webkit/glue/webcursor.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: webkit/glue/plugins/webplugin_delegate_impl.cc
===================================================================
--- webkit/glue/plugins/webplugin_delegate_impl.cc (revision 7750)
+++ webkit/glue/plugins/webplugin_delegate_impl.cc (working copy)
@@ -47,8 +47,8 @@
WebPluginDelegateImpl* WebPluginDelegateImpl::current_plugin_instance_ = NULL;
-bool WebPluginDelegateImpl::track_popup_menu_patched_ = false;
-iat_patch::IATPatchFunction WebPluginDelegateImpl::iat_patch_helper_;
+iat_patch::IATPatchFunction WebPluginDelegateImpl::iat_patch_track_popup_menu_;
+iat_patch::IATPatchFunction WebPluginDelegateImpl::iat_patch_set_cursor_;
WebPluginDelegateImpl* WebPluginDelegateImpl::Create(
const FilePath& filename,
@@ -153,6 +153,7 @@
// agent.
instance_->set_use_mozilla_user_agent();
quirks_ |= PLUGIN_QUIRK_THROTTLE_WM_USER_PLUS_ONE;
+ quirks_ |= PLUGIN_QUIRK_PATCH_SETCURSOR;
} else if (filename == L"nppdf32.dll") {
// Check for the version number above or equal 9.
std::vector<std::wstring> version;
@@ -181,6 +182,7 @@
// Explanation for this quirk can be found in
// WebPluginDelegateImpl::Initialize.
quirks_ |= PLUGIN_QUIRK_PATCH_TRACKPOPUP_MENU;
+ quirks_ |= PLUGIN_QUIRK_PATCH_SETCURSOR;
}
plugin_module_handle_ = ::GetModuleHandle(filename.c_str());
@@ -260,13 +262,25 @@
// lives on the browser thread. Our workaround is to intercept the
// TrackPopupMenu API for Silverlight and replace the window handle
// with the dummy activation window.
- if (windowless_ && !track_popup_menu_patched_ &&
+ if (windowless_ && !iat_patch_track_popup_menu_.is_patched() &&
(quirks_ & PLUGIN_QUIRK_PATCH_TRACKPOPUP_MENU)) {
- iat_patch_helper_.Patch(plugin_module_handle_, "user32.dll",
- "TrackPopupMenu",
- WebPluginDelegateImpl::TrackPopupMenuPatch);
- track_popup_menu_patched_ = true;
+ iat_patch_track_popup_menu_.Patch(
+ plugin_module_handle_, "user32.dll", "TrackPopupMenu",
+ WebPluginDelegateImpl::TrackPopupMenuPatch);
}
+
+ // Windowless plugins can set cursors by calling the SetCursor API. This
+ // works because the thread inputs of the browser UI thread and the plugin
+ // thread are attached. We intercept the SetCursor API for windowless plugins
+ // and remember the cursor being set. This is shipped over to the browser
+ // in the HandleEvent call, which ensures that the cursor does not change
+ // when a windowless plugin instance changes the cursor in a background tab.
+ if (windowless_ && !iat_patch_set_cursor_.is_patched() &&
+ (quirks_ & PLUGIN_QUIRK_PATCH_SETCURSOR)) {
+ iat_patch_set_cursor_.Patch(plugin_module_handle_, "user32.dll",
+ "SetCursor",
+ WebPluginDelegateImpl::SetCursorPatch);
+ }
return true;
}
@@ -287,6 +301,19 @@
instance_->set_web_plugin(NULL);
+ if (instance_->plugin_lib()) {
+ // Unpatch if this is the last plugin instance.
+ if (instance_->plugin_lib()->instance_count() == 1) {
+ if (iat_patch_set_cursor_.is_patched()) {
+ iat_patch_set_cursor_.Unpatch();
+ }
+
+ if (iat_patch_track_popup_menu_.is_patched()) {
+ iat_patch_track_popup_menu_.Unpatch();
+ }
+ }
+ }
+
instance_ = 0;
}
}
@@ -801,6 +828,8 @@
return TRUE;
}
+ current_plugin_instance_ = delegate;
+
switch (message) {
case WM_NCDESTROY: {
RemoveProp(hwnd, kWebPluginDelegateProperty);
@@ -818,6 +847,7 @@
if (delegate->quirks() & PLUGIN_QUIRK_THROTTLE_WM_USER_PLUS_ONE) {
WebPluginDelegateImpl::ThrottleMessage(delegate->plugin_wnd_proc_, hwnd,
message, wparam, lparam);
+ current_plugin_instance_ = NULL;
return FALSE;
}
break;
@@ -844,6 +874,7 @@
LRESULT result = CallWindowProc(delegate->plugin_wnd_proc_, hwnd, message,
wparam, lparam);
delegate->is_calling_wndproc = false;
+ current_plugin_instance_ = NULL;
return result;
}
@@ -998,12 +1029,11 @@
bool ret = instance()->NPP_HandleEvent(event) != 0;
- // Snag a reference to the current cursor ASAP in case the plugin modified
- // it. There is a nasty race condition here with the multiprocess browser
- // as someone might be setting the cursor in the main process as well.
- HCURSOR last_cursor;
- if (WM_MOUSEMOVE == event->event) {
- last_cursor = ::GetCursor();
+ if (event->event == WM_MOUSEMOVE) {
+ // Snag a reference to the current cursor ASAP in case the plugin modified
+ // it. There is a nasty race condition here with the multiprocess browser
+ // as someone might be setting the cursor in the main process as well.
+ *cursor = current_windowless_cursor_;
}
if (pop_user_gesture) {
@@ -1032,10 +1062,6 @@
::SetFocus(prev_focus_window);
}
- if (WM_MOUSEMOVE == event->event) {
- cursor->InitFromCursor(last_cursor);
- }
-
return ret;
}
@@ -1124,3 +1150,25 @@
}
return TrackPopupMenu(menu, flags, x, y, reserved, window, rect);
}
+
+HCURSOR WINAPI WebPluginDelegateImpl::SetCursorPatch(HCURSOR cursor) {
+ // The windowless flash plugin periodically calls SetCursor in a wndproc
+ // instantiated on the plugin thread. This causes annoying cursor flicker
+ // when the mouse is moved on a foreground tab, with a windowless plugin
+ // instance in a background tab. We just ignore the call here.
+ if (!current_plugin_instance_)
+ return GetCursor();
+
+ if (!current_plugin_instance_->windowless()) {
+ return SetCursor(cursor);
+ }
+
+ // It is ok to pass NULL here to GetCursor as we are not looking for cursor
+ // types defined by Webkit.
+ HCURSOR previous_cursor =
+ current_plugin_instance_->current_windowless_cursor_.GetCursor(NULL);
+
+ current_plugin_instance_->current_windowless_cursor_.InitFromExternalCursor(
+ cursor);
+ return previous_cursor;
+}
« no previous file with comments | « webkit/glue/plugins/webplugin_delegate_impl.h ('k') | webkit/glue/webcursor.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698