diff options
author | jam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-07-18 18:12:48 +0000 |
---|---|---|
committer | jam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-07-18 18:12:48 +0000 |
commit | fee3a98bd7c9d1fe862c053f1d3582ce0b6cedb4 (patch) | |
tree | 41a51bce9e9d6d4ebf2dccfd4ebad6573e11ed18 | |
parent | b939397d175b7d73345d9b5467ffa6c374bd22cb (diff) | |
download | chromium_src-fee3a98bd7c9d1fe862c053f1d3582ce0b6cedb4.zip chromium_src-fee3a98bd7c9d1fe862c053f1d3582ce0b6cedb4.tar.gz chromium_src-fee3a98bd7c9d1fe862c053f1d3582ce0b6cedb4.tar.bz2 |
Remove support for internal NPAPI plugins (i.e. those linked into the binary). We don't use that anymore.
BUG=237249
R=scottmg@chromium.org
Review URL: https://codereview.chromium.org/19745002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@212369 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | webkit/plugins/npapi/plugin_lib.cc | 125 | ||||
-rw-r--r-- | webkit/plugins/npapi/plugin_lib.h | 22 | ||||
-rw-r--r-- | webkit/plugins/npapi/plugin_lib_unittest.cc | 2 | ||||
-rw-r--r-- | webkit/plugins/npapi/plugin_list.cc | 34 | ||||
-rw-r--r-- | webkit/plugins/npapi/plugin_list.h | 35 | ||||
-rw-r--r-- | webkit/plugins/npapi/plugin_list_posix.cc | 1 | ||||
-rw-r--r-- | webkit/plugins/npapi/plugin_list_win.cc | 2 | ||||
-rw-r--r-- | webkit/plugins/npapi/webplugin_delegate_impl_win.cc | 80 |
8 files changed, 124 insertions, 177 deletions
diff --git a/webkit/plugins/npapi/plugin_lib.cc b/webkit/plugins/npapi/plugin_lib.cc index 05aca6c..f62775e 100644 --- a/webkit/plugins/npapi/plugin_lib.cc +++ b/webkit/plugins/npapi/plugin_lib.cc @@ -35,11 +35,10 @@ PluginLib* PluginLib::CreatePluginLib(const base::FilePath& filename) { } webkit::WebPluginInfo info; - const PluginEntryPoints* entry_points = NULL; - if (!PluginList::Singleton()->ReadPluginInfo(filename, &info, &entry_points)) + if (!PluginList::Singleton()->ReadPluginInfo(filename, &info)) return NULL; - return new PluginLib(info, entry_points); + return new PluginLib(info); } void PluginLib::UnloadAllPlugins() { @@ -65,8 +64,7 @@ void PluginLib::ShutdownAllPlugins() { } } -PluginLib::PluginLib(const webkit::WebPluginInfo& info, - const PluginEntryPoints* entry_points) +PluginLib::PluginLib(const webkit::WebPluginInfo& info) : web_plugin_info_(info), library_(NULL), initialized_(false), @@ -78,14 +76,7 @@ PluginLib::PluginLib(const webkit::WebPluginInfo& info, memset(static_cast<void*>(&plugin_funcs_), 0, sizeof(plugin_funcs_)); g_loaded_libs->push_back(make_scoped_refptr(this)); - if (entry_points) { - internal_ = true; - entry_points_ = *entry_points; - } else { - internal_ = false; - // We will read the entry points from the plugin directly. - memset(&entry_points_, 0, sizeof(entry_points_)); - } + memset(&entry_points_, 0, sizeof(entry_points_)); } PluginLib::~PluginLib() { @@ -183,62 +174,58 @@ bool PluginLib::Load() { base::NativeLibrary library = 0; std::string error; - if (!internal_) { #if defined(OS_WIN) - // This is to work around a bug in the Real player recorder plugin which - // intercepts LoadLibrary calls from chrome.dll and wraps NPAPI functions - // provided by the plugin. It crashes if the media player plugin is being - // loaded. Workaround is to load the dll dynamically by getting the - // LoadLibrary API address from kernel32.dll which bypasses the recorder - // plugin. - if (web_plugin_info_.name.find(L"Windows Media Player") != - std::wstring::npos) { - library = base::LoadNativeLibraryDynamically(web_plugin_info_.path); - } else { - library = base::LoadNativeLibrary(web_plugin_info_.path, &error); - } -#else + // This is to work around a bug in the Real player recorder plugin which + // intercepts LoadLibrary calls from chrome.dll and wraps NPAPI functions + // provided by the plugin. It crashes if the media player plugin is being + // loaded. Workaround is to load the dll dynamically by getting the + // LoadLibrary API address from kernel32.dll which bypasses the recorder + // plugin. + if (web_plugin_info_.name.find(L"Windows Media Player") != + std::wstring::npos) { + library = base::LoadNativeLibraryDynamically(web_plugin_info_.path); + } else { library = base::LoadNativeLibrary(web_plugin_info_.path, &error); + } +#else + library = base::LoadNativeLibrary(web_plugin_info_.path, &error); #endif - if (!library) { - LOG_IF(ERROR, PluginList::DebugPluginLoading()) - << "Couldn't load plugin " << web_plugin_info_.path.value() << " " - << error; - return rv; - } + if (!library) { + LOG_IF(ERROR, PluginList::DebugPluginLoading()) + << "Couldn't load plugin " << web_plugin_info_.path.value() << " " + << error; + return rv; + } #if defined(OS_MACOSX) - // According to the WebKit source, QuickTime at least requires us to call - // UseResFile on the plugin resources before loading. - if (library->bundle_resource_ref != -1) - UseResFile(library->bundle_resource_ref); + // According to the WebKit source, QuickTime at least requires us to call + // UseResFile on the plugin resources before loading. + if (library->bundle_resource_ref != -1) + UseResFile(library->bundle_resource_ref); #endif - rv = true; // assume success now + rv = true; // assume success now - entry_points_.np_initialize = - (NP_InitializeFunc)base::GetFunctionPointerFromNativeLibrary(library, - "NP_Initialize"); - if (entry_points_.np_initialize == 0) - rv = false; + entry_points_.np_initialize = + (NP_InitializeFunc)base::GetFunctionPointerFromNativeLibrary(library, + "NP_Initialize"); + if (entry_points_.np_initialize == 0) + rv = false; #if defined(OS_WIN) || defined(OS_MACOSX) - entry_points_.np_getentrypoints = - (NP_GetEntryPointsFunc)base::GetFunctionPointerFromNativeLibrary( - library, "NP_GetEntryPoints"); - if (entry_points_.np_getentrypoints == 0) - rv = false; + entry_points_.np_getentrypoints = + (NP_GetEntryPointsFunc)base::GetFunctionPointerFromNativeLibrary( + library, "NP_GetEntryPoints"); + if (entry_points_.np_getentrypoints == 0) + rv = false; #endif - entry_points_.np_shutdown = - (NP_ShutdownFunc)base::GetFunctionPointerFromNativeLibrary(library, - "NP_Shutdown"); - if (entry_points_.np_shutdown == 0) - rv = false; - } else { - rv = true; - } + entry_points_.np_shutdown = + (NP_ShutdownFunc)base::GetFunctionPointerFromNativeLibrary(library, + "NP_Shutdown"); + if (entry_points_.np_shutdown == 0) + rv = false; if (rv) { plugin_funcs_.size = sizeof(plugin_funcs_); @@ -251,18 +238,16 @@ bool PluginLib::Load() { #endif } - if (!internal_) { - if (rv) { - LOG_IF(ERROR, PluginList::DebugPluginLoading()) - << "Plugin " << web_plugin_info_.path.value() - << " loaded successfully."; - library_ = library; - } else { - LOG_IF(ERROR, PluginList::DebugPluginLoading()) - << "Plugin " << web_plugin_info_.path.value() - << " failed to load, unloading."; - base::UnloadNativeLibrary(library); - } + if (rv) { + LOG_IF(ERROR, PluginList::DebugPluginLoading()) + << "Plugin " << web_plugin_info_.path.value() + << " loaded successfully."; + library_ = library; + } else { + LOG_IF(ERROR, PluginList::DebugPluginLoading()) + << "Plugin " << web_plugin_info_.path.value() + << " failed to load, unloading."; + base::UnloadNativeLibrary(library); } return rv; @@ -295,7 +280,7 @@ void FreePluginLibraryHelper(const base::FilePath& path, } void PluginLib::Unload() { - if (!internal_ && library_) { + if (library_) { // In case of single process mode, a plugin can delete itself // by executing a script. So delay the unloading of the library // so that the plugin will have a chance to unwind. @@ -342,7 +327,7 @@ void PluginLib::Unload() { } void PluginLib::Shutdown() { - if (initialized_ && !internal_) { + if (initialized_) { NP_Shutdown(); initialized_ = false; } diff --git a/webkit/plugins/npapi/plugin_lib.h b/webkit/plugins/npapi/plugin_lib.h index 8884754..21ac124 100644 --- a/webkit/plugins/npapi/plugin_lib.h +++ b/webkit/plugins/npapi/plugin_lib.h @@ -12,9 +12,10 @@ #include "base/memory/ref_counted.h" #include "base/native_library.h" #include "build/build_config.h" -#include "webkit/plugins/npapi/plugin_list.h" +#include "third_party/npapi/bindings/nphostapi.h" #include "webkit/plugins/npapi/webplugin.h" #include "webkit/plugins/webkit_plugins_export.h" +#include "webkit/plugins/webplugininfo.h" namespace base { class FilePath; @@ -25,6 +26,18 @@ namespace npapi { class PluginInstance; +// This struct holds entry points into a plugin. The entry points are +// slightly different between Win/Mac and Unixes. Note that the interface for +// querying plugins is synchronous and it is preferable to use a higher-level +// asynchronous information to query information. +struct PluginEntryPoints { +#if !defined(OS_POSIX) || defined(OS_MACOSX) + NP_GetEntryPointsFunc np_getentrypoints; +#endif + NP_InitializeFunc np_initialize; + NP_ShutdownFunc np_shutdown; +}; + // A PluginLib is a single NPAPI Plugin Library, and is the lifecycle // manager for new PluginInstances. class WEBKIT_PLUGINS_EXPORT PluginLib : public base::RefCounted<PluginLib> { @@ -50,8 +63,6 @@ class WEBKIT_PLUGINS_EXPORT PluginLib : public base::RefCounted<PluginLib> { // supports. const webkit::WebPluginInfo& plugin_info() { return web_plugin_info_; } - bool internal() { return internal_; } - // // NPAPI functions // @@ -86,9 +97,7 @@ class WEBKIT_PLUGINS_EXPORT PluginLib : public base::RefCounted<PluginLib> { friend class base::RefCounted<PluginLib>; // Creates a new PluginLib. - // |entry_points| is non-NULL for internal plugins. - PluginLib(const webkit::WebPluginInfo& info, - const PluginEntryPoints* entry_points); + explicit PluginLib(const webkit::WebPluginInfo& info); virtual ~PluginLib(); @@ -103,7 +112,6 @@ class WEBKIT_PLUGINS_EXPORT PluginLib : public base::RefCounted<PluginLib> { void Shutdown(); private: - bool internal_; // True for plugins that are built-in into chrome binaries. webkit::WebPluginInfo web_plugin_info_; // Supported mime types, description base::NativeLibrary library_; // The opened library reference. NPPluginFuncs plugin_funcs_; // The struct of plugin side functions. diff --git a/webkit/plugins/npapi/plugin_lib_unittest.cc b/webkit/plugins/npapi/plugin_lib_unittest.cc index 10659ce..3dc2a9c 100644 --- a/webkit/plugins/npapi/plugin_lib_unittest.cc +++ b/webkit/plugins/npapi/plugin_lib_unittest.cc @@ -17,7 +17,7 @@ namespace npapi { // variable, we can get a crash if no plugin libs were marked as always loaded. class PluginLibTest : public PluginLib { public: - PluginLibTest() : PluginLib(WebPluginInfo(), NULL) {} + PluginLibTest() : PluginLib(WebPluginInfo()) {} using PluginLib::Unload; protected: diff --git a/webkit/plugins/npapi/plugin_list.cc b/webkit/plugins/npapi/plugin_list.cc index 71c5ef2..3ade2ab 100644 --- a/webkit/plugins/npapi/plugin_list.cc +++ b/webkit/plugins/npapi/plugin_list.cc @@ -110,25 +110,15 @@ void PluginList::AddExtraPluginDir(const base::FilePath& plugin_dir) { void PluginList::RegisterInternalPlugin(const webkit::WebPluginInfo& info, bool add_at_beginning) { - PluginEntryPoints entry_points = {0}; - RegisterInternalPluginWithEntryPoints(info, add_at_beginning, entry_points); -} - -void PluginList::RegisterInternalPluginWithEntryPoints( - const webkit::WebPluginInfo& info, - bool add_at_beginning, - const PluginEntryPoints& entry_points) { if (!NPAPIPluginsSupported() && info.type == WebPluginInfo::PLUGIN_TYPE_NPAPI) { DLOG(INFO) << "Don't register NPAPI plugins when they're not supported"; return; } - InternalPlugin plugin = { info, entry_points }; - base::AutoLock lock(lock_); - internal_plugins_.push_back(plugin); + internal_plugins_.push_back(info); if (add_at_beginning) { // Newer registrations go earlier in the list so they can override the MIME // types of older registrations. @@ -141,7 +131,7 @@ void PluginList::RegisterInternalPluginWithEntryPoints( void PluginList::UnregisterInternalPlugin(const base::FilePath& path) { base::AutoLock lock(lock_); for (size_t i = 0; i < internal_plugins_.size(); i++) { - if (internal_plugins_[i].info.path == path) { + if (internal_plugins_[i].path == path) { internal_plugins_.erase(internal_plugins_.begin() + i); return; } @@ -153,30 +143,26 @@ void PluginList::GetInternalPlugins( std::vector<webkit::WebPluginInfo>* internal_plugins) { base::AutoLock lock(lock_); - for (std::vector<InternalPlugin>::iterator it = internal_plugins_.begin(); + for (std::vector<webkit::WebPluginInfo>::iterator it = + internal_plugins_.begin(); it != internal_plugins_.end(); ++it) { - internal_plugins->push_back(it->info); + internal_plugins->push_back(*it); } } bool PluginList::ReadPluginInfo(const base::FilePath& filename, - webkit::WebPluginInfo* info, - const PluginEntryPoints** entry_points) { + webkit::WebPluginInfo* info) { { base::AutoLock lock(lock_); for (size_t i = 0; i < internal_plugins_.size(); ++i) { - if (filename == internal_plugins_[i].info.path) { - *entry_points = &internal_plugins_[i].entry_points; - *info = internal_plugins_[i].info; + if (filename == internal_plugins_[i].path) { + *info = internal_plugins_[i]; return true; } } } - // Not an internal plugin. - *entry_points = NULL; - return PluginList::ReadWebPluginInfo(filename, info); } @@ -278,9 +264,7 @@ bool PluginList::LoadPluginIntoPluginList( WebPluginInfo* plugin_info) { LOG_IF(ERROR, PluginList::DebugPluginLoading()) << "Loading plugin " << path.value(); - const PluginEntryPoints* entry_points; - - if (!ReadPluginInfo(path, plugin_info, &entry_points)) + if (!ReadPluginInfo(path, plugin_info)) return false; if (!ShouldLoadPluginUsingPluginList(*plugin_info, plugins)) diff --git a/webkit/plugins/npapi/plugin_list.h b/webkit/plugins/npapi/plugin_list.h index 2b800d8..eac8b0f 100644 --- a/webkit/plugins/npapi/plugin_list.h +++ b/webkit/plugins/npapi/plugin_list.h @@ -17,7 +17,6 @@ #include "base/memory/linked_ptr.h" #include "base/memory/scoped_vector.h" #include "base/synchronization/lock.h" -#include "third_party/npapi/bindings/nphostapi.h" #include "webkit/plugins/webkit_plugins_export.h" #include "webkit/plugins/webplugininfo.h" @@ -26,18 +25,6 @@ class GURL; namespace webkit { namespace npapi { -// This struct holds entry points into a plugin. The entry points are -// slightly different between Win/Mac and Unixes. Note that the interface for -// querying plugins is synchronous and it is preferable to use a higher-level -// asynchronous information to query information. -struct PluginEntryPoints { -#if !defined(OS_POSIX) || defined(OS_MACOSX) - NP_GetEntryPointsFunc np_getentrypoints; -#endif - NP_InitializeFunc np_initialize; - NP_ShutdownFunc np_shutdown; -}; - // The PluginList is responsible for loading our NPAPI based plugins. It does // so in whatever manner is appropriate for the platform. On Windows, it loads // plugins from a known directory by looking for DLLs which start with "NP", @@ -89,14 +76,6 @@ class PluginList { void RegisterInternalPlugin(const webkit::WebPluginInfo& info, bool add_at_beginning); - // This second version is for "plugins" that have been compiled directly into - // the binary -- callers must provide the plugin information and the entry - // points. - void RegisterInternalPluginWithEntryPoints( - const webkit::WebPluginInfo& info, - bool add_at_beginning, - const PluginEntryPoints& entry_points); - // Removes a specified internal plugin from the list. The search will match // on the path from the version info previously registered. void UnregisterInternalPlugin(const base::FilePath& path); @@ -105,13 +84,10 @@ class PluginList { void GetInternalPlugins(std::vector<webkit::WebPluginInfo>* plugins); // Creates a WebPluginInfo structure given a plugin's path. On success - // returns true, with the information being put into "info". If it's an - // internal plugin, "entry_points" is filled in as well with a - // internally-owned PluginEntryPoints pointer. + // returns true, with the information being put into "info". // Returns false if the library couldn't be found, or if it's not a plugin. bool ReadPluginInfo(const base::FilePath& filename, - webkit::WebPluginInfo* info, - const PluginEntryPoints** entry_points); + webkit::WebPluginInfo* info); // In Windows plugins, the mime types are passed as a specially formatted list // of strings. This function parses those strings into a WebPluginMimeType @@ -194,11 +170,6 @@ class PluginList { LOADING_STATE_UP_TO_DATE, }; - struct InternalPlugin { - webkit::WebPluginInfo info; - PluginEntryPoints entry_points; - }; - friend class PluginListTest; friend struct base::DefaultLazyInstanceTraits<PluginList>; @@ -257,7 +228,7 @@ class PluginList { std::vector<base::FilePath> extra_plugin_dirs_; // Holds information about internal plugins. - std::vector<InternalPlugin> internal_plugins_; + std::vector<webkit::WebPluginInfo> internal_plugins_; // A list holding all plug-ins. std::vector<webkit::WebPluginInfo> plugins_list_; diff --git a/webkit/plugins/npapi/plugin_list_posix.cc b/webkit/plugins/npapi/plugin_list_posix.cc index f73e9850..86dc227 100644 --- a/webkit/plugins/npapi/plugin_list_posix.cc +++ b/webkit/plugins/npapi/plugin_list_posix.cc @@ -29,6 +29,7 @@ #include "base/strings/sys_string_conversions.h" #include "base/strings/utf_string_conversions.h" #include "build/build_config.h" +#include "third_party/npapi/bindings/nphostapi.h" // These headers must be included in this order to make the declaration gods // happy. diff --git a/webkit/plugins/npapi/plugin_list_win.cc b/webkit/plugins/npapi/plugin_list_win.cc index 242ba9b..af8e002 100644 --- a/webkit/plugins/npapi/plugin_list_win.cc +++ b/webkit/plugins/npapi/plugin_list_win.cc @@ -396,7 +396,7 @@ bool PluginList::ShouldLoadPluginUsingPluginList( // If the plugin is in our internal list we should load it. for (size_t i = 0; i < internal_plugins_.size(); ++i) { - if (info.path == internal_plugins_[i].info.path) + if (info.path == internal_plugins_[i].path) return true; } diff --git a/webkit/plugins/npapi/webplugin_delegate_impl_win.cc b/webkit/plugins/npapi/webplugin_delegate_impl_win.cc index 9e239e2..90d8586 100644 --- a/webkit/plugins/npapi/webplugin_delegate_impl_win.cc +++ b/webkit/plugins/npapi/webplugin_delegate_impl_win.cc @@ -5,6 +5,7 @@ #include "webkit/plugins/npapi/webplugin_delegate_impl.h" #include <map> +#include <set> #include <string> #include <vector> @@ -394,7 +395,7 @@ WebPluginDelegateImpl::~WebPluginDelegateImpl() { bool WebPluginDelegateImpl::PlatformInitialize() { plugin_->SetWindow(windowed_handle_); - if (windowless_ && !instance_->plugin_lib()->internal()) { + if (windowless_) { CreateDummyWindowForActivation(); handle_event_pump_messages_event_ = CreateEvent(NULL, TRUE, FALSE, NULL); plugin_->SetWindowlessData( @@ -402,48 +403,45 @@ bool WebPluginDelegateImpl::PlatformInitialize() { reinterpret_cast<gfx::NativeViewId>(dummy_window_for_activation_)); } - // We cannot patch internal plugins as they are not shared libraries. - if (!instance_->plugin_lib()->internal()) { - // Windowless plugins call the WindowFromPoint API and passes the result of - // that to the TrackPopupMenu API call as the owner window. This causes the - // API to fail as the API expects the window handle to live on the same - // thread as the caller. It works in the other browsers as the plugin lives - // on the browser thread. Our workaround is to intercept the TrackPopupMenu - // API and replace the window handle with the dummy activation window. - if (windowless_ && !g_iat_patch_track_popup_menu.Pointer()->is_patched()) { - g_iat_patch_track_popup_menu.Pointer()->Patch( - GetPluginPath().value().c_str(), "user32.dll", "TrackPopupMenu", - WebPluginDelegateImpl::TrackPopupMenuPatch); - } + // Windowless plugins call the WindowFromPoint API and passes the result of + // that to the TrackPopupMenu API call as the owner window. This causes the + // API to fail as the API expects the window handle to live on the same + // thread as the caller. It works in the other browsers as the plugin lives + // on the browser thread. Our workaround is to intercept the TrackPopupMenu + // API and replace the window handle with the dummy activation window. + if (windowless_ && !g_iat_patch_track_popup_menu.Pointer()->is_patched()) { + g_iat_patch_track_popup_menu.Pointer()->Patch( + GetPluginPath().value().c_str(), "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_ && !g_iat_patch_set_cursor.Pointer()->is_patched() && - (quirks_ & PLUGIN_QUIRK_PATCH_SETCURSOR)) { - g_iat_patch_set_cursor.Pointer()->Patch( - GetPluginPath().value().c_str(), "user32.dll", "SetCursor", - WebPluginDelegateImpl::SetCursorPatch); - } + // 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_ && !g_iat_patch_set_cursor.Pointer()->is_patched() && + (quirks_ & PLUGIN_QUIRK_PATCH_SETCURSOR)) { + g_iat_patch_set_cursor.Pointer()->Patch( + GetPluginPath().value().c_str(), "user32.dll", "SetCursor", + WebPluginDelegateImpl::SetCursorPatch); + } - // The windowed flash plugin has a bug which occurs when the plugin enters - // fullscreen mode. It basically captures the mouse on WM_LBUTTONDOWN and - // does not release capture correctly causing it to stop receiving - // subsequent mouse events. This problem is also seen in Safari where there - // is code to handle this in the wndproc. However the plugin subclasses the - // window again in WM_LBUTTONDOWN before entering full screen. As a result - // Safari does not receive the WM_LBUTTONUP message. To workaround this - // issue we use a per thread mouse hook. This bug does not occur in Firefox - // and opera. Firefox has code similar to Safari. It could well be a bug in - // the flash plugin, which only occurs in webkit based browsers. - if (quirks_ & PLUGIN_QUIRK_HANDLE_MOUSE_CAPTURE) { - mouse_hook_ = SetWindowsHookEx(WH_MOUSE, MouseHookProc, NULL, - GetCurrentThreadId()); - } + // The windowed flash plugin has a bug which occurs when the plugin enters + // fullscreen mode. It basically captures the mouse on WM_LBUTTONDOWN and + // does not release capture correctly causing it to stop receiving + // subsequent mouse events. This problem is also seen in Safari where there + // is code to handle this in the wndproc. However the plugin subclasses the + // window again in WM_LBUTTONDOWN before entering full screen. As a result + // Safari does not receive the WM_LBUTTONUP message. To workaround this + // issue we use a per thread mouse hook. This bug does not occur in Firefox + // and opera. Firefox has code similar to Safari. It could well be a bug in + // the flash plugin, which only occurs in webkit based browsers. + if (quirks_ & PLUGIN_QUIRK_HANDLE_MOUSE_CAPTURE) { + mouse_hook_ = SetWindowsHookEx(WH_MOUSE, MouseHookProc, NULL, + GetCurrentThreadId()); } // On XP, WMP will use its old UI unless a registry key under HKLM has the |