diff options
Diffstat (limited to 'webkit/glue')
-rw-r--r-- | webkit/glue/plugins/fake_plugin_window_tracker_mac.cc | 34 | ||||
-rw-r--r-- | webkit/glue/plugins/fake_plugin_window_tracker_mac.h | 39 | ||||
-rw-r--r-- | webkit/glue/plugins/webplugin_delegate_impl.h | 4 | ||||
-rw-r--r-- | webkit/glue/plugins/webplugin_delegate_impl_mac.mm | 37 |
4 files changed, 60 insertions, 54 deletions
diff --git a/webkit/glue/plugins/fake_plugin_window_tracker_mac.cc b/webkit/glue/plugins/fake_plugin_window_tracker_mac.cc index 5be919e..1099a99 100644 --- a/webkit/glue/plugins/fake_plugin_window_tracker_mac.cc +++ b/webkit/glue/plugins/fake_plugin_window_tracker_mac.cc @@ -5,9 +5,7 @@ #include "base/logging.h" #include "webkit/glue/plugins/fake_plugin_window_tracker_mac.h" -FakePluginWindowTracker::FakePluginWindowTracker() - : window_to_delegate_map_(CFDictionaryCreateMutable(kCFAllocatorDefault, - 0, NULL, NULL)) { +FakePluginWindowTracker::FakePluginWindowTracker() { } FakePluginWindowTracker* FakePluginWindowTracker::SharedInstance() { @@ -29,30 +27,34 @@ WindowRef FakePluginWindowTracker::GenerateFakeWindowForDelegate( kWindowNoTitleBarAttribute, &window_bounds, &new_ref) == noErr) { - CFDictionaryAddValue(window_to_delegate_map_, new_ref, delegate); + window_to_delegate_map_[new_ref] = delegate; + delegate_to_window_map_[delegate] = new_ref; } return new_ref; } WebPluginDelegateImpl* FakePluginWindowTracker::GetDelegateForFakeWindow( WindowRef window) const { - return const_cast<WebPluginDelegateImpl*>( - static_cast<const WebPluginDelegateImpl*>( - CFDictionaryGetValue(window_to_delegate_map_, window))); + WindowToDelegateMap::const_iterator i = window_to_delegate_map_.find(window); + if (i != window_to_delegate_map_.end()) + return i->second; + return NULL; +} + +WindowRef FakePluginWindowTracker::GetFakeWindowForDelegate( + WebPluginDelegateImpl* delegate) const { + DelegateToWindowMap::const_iterator i = + delegate_to_window_map_.find(delegate); + if (i != delegate_to_window_map_.end()) + return i->second; + return NULL; } void FakePluginWindowTracker::RemoveFakeWindowForDelegate( WebPluginDelegateImpl* delegate, WindowRef window) { DCHECK(GetDelegateForFakeWindow(window) == delegate); - CFDictionaryRemoveValue(window_to_delegate_map_, delegate); + window_to_delegate_map_.erase(window); + delegate_to_window_map_.erase(delegate); if (window) // Check just in case the initial window creation failed. DisposeWindow(window); } - -WindowRef FakePluginWindowTracker::get_active_plugin_window() { - return active_plugin_window_; -} - -void FakePluginWindowTracker::set_active_plugin_window(WindowRef window) { - active_plugin_window_ = window; -} diff --git a/webkit/glue/plugins/fake_plugin_window_tracker_mac.h b/webkit/glue/plugins/fake_plugin_window_tracker_mac.h index eeb2c81..d6576bf 100644 --- a/webkit/glue/plugins/fake_plugin_window_tracker_mac.h +++ b/webkit/glue/plugins/fake_plugin_window_tracker_mac.h @@ -6,9 +6,9 @@ #define WEBKIT_GLUE_PLUGINS_FAKE_PLUGIN_WINDOW_TRACKER_MAC_H_ #include <Carbon/Carbon.h> +#include <map> #include "base/basictypes.h" -#include "base/scoped_cftyperef.h" class ScopedActivePluginWindow; class WebPluginDelegateImpl; @@ -30,43 +30,20 @@ class __attribute__((visibility("default"))) FakePluginWindowTracker { // Returns the WebPluginDelegate associated with the given fake window ref. WebPluginDelegateImpl* GetDelegateForFakeWindow(WindowRef window) const; + // Returns the fake window ref associated with |delegate|. + WindowRef GetFakeWindowForDelegate(WebPluginDelegateImpl* delegate) const; + // Removes the fake window ref entry for |delegate|. void RemoveFakeWindowForDelegate(WebPluginDelegateImpl* delegate, WindowRef window); - // Gets the window for the plugin that is currently handling an input event. - // To set the value, use ScopedActivePluginWindow. - WindowRef get_active_plugin_window(); - private: - friend class ScopedActivePluginWindow; - // Sets the window corresponding to the plugin that is currently handling an - // input event. - void set_active_plugin_window(WindowRef window); - - scoped_cftyperef<CFMutableDictionaryRef> window_to_delegate_map_; - - WindowRef active_plugin_window_; // weak reference + typedef std::map<WindowRef, WebPluginDelegateImpl*> WindowToDelegateMap; + typedef std::map<WebPluginDelegateImpl*, WindowRef> DelegateToWindowMap; + WindowToDelegateMap window_to_delegate_map_; + DelegateToWindowMap delegate_to_window_map_; DISALLOW_COPY_AND_ASSIGN(FakePluginWindowTracker); }; -// Helper to simplify correct usage of set_active_plugin_window. -// Instantiating will set the shared plugin window tracker's active window to -// |window| for the lifetime of the object, then NULL when it goes out of scope. -class ScopedActivePluginWindow { - public: - explicit ScopedActivePluginWindow(WindowRef window) : window_(window) { - FakePluginWindowTracker::SharedInstance()->set_active_plugin_window( - window_); - } - ~ScopedActivePluginWindow() { - FakePluginWindowTracker::SharedInstance()->set_active_plugin_window( - NULL); - } -private: - WindowRef window_; // weak ref - DISALLOW_COPY_AND_ASSIGN(ScopedActivePluginWindow); -}; - #endif // WEBKIT_GLUE_PLUGINS_FAKE_PLUGIN_WINDOW_TRACKER_MAC_H_ diff --git a/webkit/glue/plugins/webplugin_delegate_impl.h b/webkit/glue/plugins/webplugin_delegate_impl.h index 3e407aa..4e66936 100644 --- a/webkit/glue/plugins/webplugin_delegate_impl.h +++ b/webkit/glue/plugins/webplugin_delegate_impl.h @@ -117,7 +117,9 @@ class WebPluginDelegateImpl : public webkit_glue::WebPluginDelegate { // Informs the delegate that the context used for painting windowless plugins // has changed. void UpdateContext(gfx::NativeDrawingContext context); - // returns a vector of currently active delegates in this process. + // Returns the delegate currently processing events. + static WebPluginDelegateImpl* GetActiveDelegate(); + // Returns a vector of currently active delegates in this process. static std::set<WebPluginDelegateImpl*> GetActiveDelegates(); // Informs the delegate which plugin instance has just received keyboard focus // so that it can notify the plugin as appropriate. If |process_id| and diff --git a/webkit/glue/plugins/webplugin_delegate_impl_mac.mm b/webkit/glue/plugins/webplugin_delegate_impl_mac.mm index e7918a9..92edf23 100644 --- a/webkit/glue/plugins/webplugin_delegate_impl_mac.mm +++ b/webkit/glue/plugins/webplugin_delegate_impl_mac.mm @@ -65,6 +65,23 @@ const int kPluginIdleThrottleDelayMs = 20; // 20ms (50Hz) base::LazyInstance<std::set<WebPluginDelegateImpl*> > g_active_delegates( base::LINKER_INITIALIZED); +WebPluginDelegateImpl* g_active_delegate; + +// Helper to simplify correct usage of g_active_delegate. Instantiating will +// set the active delegate to |delegate| for the lifetime of the object, then +// NULL when it goes out of scope. +class ScopedActiveDelegate { +public: + explicit ScopedActiveDelegate(WebPluginDelegateImpl* delegate) { + g_active_delegate = delegate; + } + ~ScopedActiveDelegate() { + g_active_delegate = NULL; + } +private: + DISALLOW_COPY_AND_ASSIGN(ScopedActiveDelegate); +}; + } // namespace WebPluginDelegateImpl::WebPluginDelegateImpl( @@ -278,6 +295,8 @@ void WebPluginDelegateImpl::WindowlessPaint(gfx::NativeDrawingContext context, static StatsRate plugin_paint("Plugin.Paint"); StatsScope<StatsRate> scope(plugin_paint); + ScopedActiveDelegate active_delegate(this); + switch (instance()->drawing_model()) { #ifndef NP_NO_QUICKDRAW case NPDrawingModelQuickDraw: { @@ -371,6 +390,10 @@ void WebPluginDelegateImpl::WindowlessSetWindow(bool force_set_window) { DCHECK(err == NPERR_NO_ERROR); } +WebPluginDelegateImpl* WebPluginDelegateImpl::GetActiveDelegate() { + return g_active_delegate; +} + std::set<WebPluginDelegateImpl*> WebPluginDelegateImpl::GetActiveDelegates() { std::set<WebPluginDelegateImpl*>* delegates = g_active_delegates.Pointer(); return *delegates; @@ -382,6 +405,8 @@ void WebPluginDelegateImpl::FocusNotify(WebPluginDelegateImpl* delegate) { have_focus_ = (delegate == this); + ScopedActiveDelegate active_delegate(this); + switch (instance()->event_model()) { case NPEventModelCarbon: { NPEvent focus_event = { 0 }; @@ -743,6 +768,8 @@ bool WebPluginDelegateImpl::HandleInputEvent(const WebInputEvent& event, } #endif + ScopedActiveDelegate active_delegate(this); + // Create the plugin event structure, and send it to the plugin. bool ret = false; switch (instance()->event_model()) { @@ -753,9 +780,6 @@ bool WebPluginDelegateImpl::HandleInputEvent(const WebInputEvent& event, LOG(WARNING) << "NPEventFromWebInputEvent failed"; return false; } - // Set this plugin's window as the active one, for global Carbon calls. - ScopedActivePluginWindow active_window_scope( - reinterpret_cast<WindowRef>(cg_context_.window)); ret = instance()->NPP_HandleEvent(&np_event) != 0; break; } @@ -798,9 +822,13 @@ void WebPluginDelegateImpl::OnNullEvent() { delete this; return; } + // Avoid a race condition between IO and UI threads during plugin shutdown if (!instance_) return; + + ScopedActiveDelegate active_delegate(this); + #ifndef NP_NO_CARBON if (!webkit_glue::IsPluginRunningInRendererProcess()) { switch (instance()->event_model()) { @@ -830,9 +858,6 @@ void WebPluginDelegateImpl::OnNullEvent() { np_event.modifiers |= btnState; np_event.where.h = last_mouse_x_; np_event.where.v = last_mouse_y_; - // Set this plugin's window as the active one, for global Carbon calls. - ScopedActivePluginWindow active_window_scope( - reinterpret_cast<WindowRef>(cg_context_.window)); instance()->NPP_HandleEvent(&np_event); } #endif |