summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoravi@chromium.org <avi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-01-19 19:24:24 +0000
committeravi@chromium.org <avi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-01-19 19:24:24 +0000
commitb4ec5d95f7ae134d69449e1715f7f744dee31448 (patch)
tree0b6a33c21c431b5e7f609c682f14721002143432
parent388f3ad136953404388befdfab941b9749d96bc7 (diff)
downloadchromium_src-b4ec5d95f7ae134d69449e1715f7f744dee31448.zip
chromium_src-b4ec5d95f7ae134d69449e1715f7f744dee31448.tar.gz
chromium_src-b4ec5d95f7ae134d69449e1715f7f744dee31448.tar.bz2
(Mac) Allow the tracking of the "active" plugin delegate separate from the fake windows.
BUG=http://crbug.com/20717 TEST=none; no visible change Review URL: http://codereview.chromium.org/549085 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@36533 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/app/framework.order16
-rw-r--r--chrome/browser/plugin_carbon_interpose_mac.cc7
-rw-r--r--chrome/plugin/plugin_interpose_util_mac.h3
-rw-r--r--chrome/plugin/plugin_interpose_util_mac.mm5
-rw-r--r--webkit/glue/plugins/fake_plugin_window_tracker_mac.cc34
-rw-r--r--webkit/glue/plugins/fake_plugin_window_tracker_mac.h39
-rw-r--r--webkit/glue/plugins/webplugin_delegate_impl.h4
-rw-r--r--webkit/glue/plugins/webplugin_delegate_impl_mac.mm37
8 files changed, 79 insertions, 66 deletions
diff --git a/chrome/app/framework.order b/chrome/app/framework.order
index 167d45f..814cecc 100644
--- a/chrome/app/framework.order
+++ b/chrome/app/framework.order
@@ -23,20 +23,20 @@ _NP_GetValue
_NP_Initialize
_NP_Shutdown
__ZN22mac_plugin_interposing21SwitchToPluginProcessEv
-__ZN22mac_plugin_interposing31NotifyBrowserOfPluginHideWindowEj6CGRect
-__ZN22mac_plugin_interposing31NotifyBrowserOfPluginShowWindowEj6CGRectb
+__ZN22mac_plugin_interposing17GetActiveDelegateEv
__ZN22mac_plugin_interposing33NotifyBrowserOfPluginSelectWindowEj6CGRectb
+__ZN22mac_plugin_interposing31NotifyBrowserOfPluginShowWindowEj6CGRectb
+__ZN22mac_plugin_interposing31NotifyBrowserOfPluginHideWindowEj6CGRect
__ZN22mac_plugin_interposing28NotifyPluginOfSetThemeCursorEP21WebPluginDelegateImplm
-__ZN23FakePluginWindowTracker14SharedInstanceEv
-__ZN23FakePluginWindowTracker27RemoveFakeWindowForDelegateEP21WebPluginDelegateImplP15OpaqueWindowPtr
-__ZN23FakePluginWindowTracker29GenerateFakeWindowForDelegateEP21WebPluginDelegateImpl
-__ZN23FakePluginWindowTracker24get_active_plugin_windowEv
-__ZN23FakePluginWindowTracker24set_active_plugin_windowEP15OpaqueWindowPtr
__ZN23FakePluginWindowTrackerC1Ev
__ZN23FakePluginWindowTrackerC2Ev
+__ZN23FakePluginWindowTracker14SharedInstanceEv
+__ZN23FakePluginWindowTracker29GenerateFakeWindowForDelegateEP21WebPluginDelegateImpl
+__ZNK23FakePluginWindowTracker24GetDelegateForFakeWindowEP15OpaqueWindowPtr
+__ZNK23FakePluginWindowTracker24GetFakeWindowForDelegateEP21WebPluginDelegateImpl
+__ZN23FakePluginWindowTracker27RemoveFakeWindowForDelegateEP21WebPluginDelegateImplP15OpaqueWindowPtr
__ZN7WebCore22narrowPrecisionToFloatIdEEfT_
__ZN7WebCore24narrowPrecisionToCGFloatIdEEfT_
-__ZNK23FakePluginWindowTracker24GetDelegateForFakeWindowEP15OpaqueWindowPtr
__ZnwmPv
_catch_exception_raise
diff --git a/chrome/browser/plugin_carbon_interpose_mac.cc b/chrome/browser/plugin_carbon_interpose_mac.cc
index 45f0ffe..adbba7e 100644
--- a/chrome/browser/plugin_carbon_interpose_mac.cc
+++ b/chrome/browser/plugin_carbon_interpose_mac.cc
@@ -126,8 +126,9 @@ static void ChromePluginDisposeDialog(DialogRef dialog) {
}
static WindowPartCode ChromePluginFindWindow(Point point, WindowRef* window) {
+ WebPluginDelegateImpl* delegate = mac_plugin_interposing::GetActiveDelegate();
FakePluginWindowTracker* tracker = FakePluginWindowTracker::SharedInstance();
- WindowRef plugin_window = tracker->get_active_plugin_window();
+ WindowRef plugin_window = tracker->GetFakeWindowForDelegate(delegate);
if (plugin_window) {
// If plugin_window is non-NULL, then we are in the middle of routing an
// event to the plugin, so we know it's destined for this window already,
@@ -145,9 +146,7 @@ static WindowPartCode ChromePluginFindWindow(Point point, WindowRef* window) {
}
static OSStatus ChromePluginSetThemeCursor(ThemeCursor cursor) {
- FakePluginWindowTracker* tracker = FakePluginWindowTracker::SharedInstance();
- WebPluginDelegateImpl* delegate =
- tracker->GetDelegateForFakeWindow(tracker->get_active_plugin_window());
+ WebPluginDelegateImpl* delegate = mac_plugin_interposing::GetActiveDelegate();
if (delegate) {
mac_plugin_interposing::NotifyPluginOfSetThemeCursor(delegate, cursor);
return noErr;
diff --git a/chrome/plugin/plugin_interpose_util_mac.h b/chrome/plugin/plugin_interpose_util_mac.h
index 75d1142..deabe6c 100644
--- a/chrome/plugin/plugin_interpose_util_mac.h
+++ b/chrome/plugin/plugin_interpose_util_mac.h
@@ -20,6 +20,9 @@ void SetUpCocoaInterposing();
// Brings the plugin process to the front so that the user can see its windows.
void SwitchToPluginProcess();
+// Returns the delegate currently processing events.
+WebPluginDelegateImpl* GetActiveDelegate();
+
// Sends a message to the browser process to inform it that the given window
// has been brought forward.
void NotifyBrowserOfPluginSelectWindow(uint32 window_id, CGRect bounds,
diff --git a/chrome/plugin/plugin_interpose_util_mac.mm b/chrome/plugin/plugin_interpose_util_mac.mm
index 1cad1bb..7743175 100644
--- a/chrome/plugin/plugin_interpose_util_mac.mm
+++ b/chrome/plugin/plugin_interpose_util_mac.mm
@@ -31,6 +31,11 @@ void SwitchToPluginProcess() {
}
__attribute__((visibility("default")))
+WebPluginDelegateImpl* GetActiveDelegate() {
+ return WebPluginDelegateImpl::GetActiveDelegate();
+}
+
+__attribute__((visibility("default")))
void NotifyBrowserOfPluginSelectWindow(uint32 window_id, CGRect bounds,
bool modal) {
PluginThread* plugin_thread = PluginThread::current();
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