| 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;
|
| +}
|
|
|