diff options
author | amanda@chromium.org <amanda@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-11-20 18:26:16 +0000 |
---|---|---|
committer | amanda@chromium.org <amanda@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-11-20 18:26:16 +0000 |
commit | 27f5a6c85610ac97a87bc64918ead7891f58fda5 (patch) | |
tree | 8454f2a3e2526b203628c0e434ebee62e563ad0b /webkit/glue | |
parent | 8806b8a53168e161e8a2cbbf4051067c095832a9 (diff) | |
download | chromium_src-27f5a6c85610ac97a87bc64918ead7891f58fda5.zip chromium_src-27f5a6c85610ac97a87bc64918ead7891f58fda5.tar.gz chromium_src-27f5a6c85610ac97a87bc64918ead7891f58fda5.tar.bz2 |
Mac: Simulate the OS-level focus handling that windows and linux plugins
rely on to trigger NPAPI keyboard focus notifications.
BUG=26585
TEST=On pages with multiple Flash text entry fields, only one should have
a blinking caret at any time. Flash elements that use the ActionScript2
"Key.IsDown()" function should only detect keydowns when they are in a
visible tab and focused.
Review URL: http://codereview.chromium.org/399090
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@32631 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/glue')
-rw-r--r-- | webkit/glue/plugins/webplugin_delegate_impl.h | 19 | ||||
-rw-r--r-- | webkit/glue/plugins/webplugin_delegate_impl_mac.mm | 41 |
2 files changed, 57 insertions, 3 deletions
diff --git a/webkit/glue/plugins/webplugin_delegate_impl.h b/webkit/glue/plugins/webplugin_delegate_impl.h index 1665a8b..5d6757d 100644 --- a/webkit/glue/plugins/webplugin_delegate_impl.h +++ b/webkit/glue/plugins/webplugin_delegate_impl.h @@ -9,6 +9,7 @@ #include <string> #include <list> +#include <set> #include "app/gfx/native_widget_types.h" #include "base/file_path.h" @@ -113,6 +114,20 @@ 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. + 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 + // |instance_id| are both 0, this signifies that no plugin has keyboard + // focus. + void FocusNotify(WebPluginDelegateImpl* focused_delegate); + // Set a notifier function that gets called when the delegate is accepting + // the focus. If no notifier function has been set, the delegate will just + // call FocusNotify(this). This is used in a multiprocess environment to + // propagate focus notifications to all running plugin processes. + void SetFocusNotifier(void (*notifier)(WebPluginDelegateImpl*)) { + focus_notifier_ = notifier; + } #endif private: @@ -305,6 +320,10 @@ class WebPluginDelegateImpl : public webkit_glue::WebPluginDelegate { // Last mouse position within the plugin's rect (used for null events). int last_mouse_x_; int last_mouse_y_; + // True if the plugin thinks it has keyboard focus + bool have_focus_; + // A function to call when we want to accept keyboard focus + void (*focus_notifier_)(WebPluginDelegateImpl* notifier); #endif // Called by the message filter hook when the plugin enters a modal loop. diff --git a/webkit/glue/plugins/webplugin_delegate_impl_mac.mm b/webkit/glue/plugins/webplugin_delegate_impl_mac.mm index 262b002..28daa29 100644 --- a/webkit/glue/plugins/webplugin_delegate_impl_mac.mm +++ b/webkit/glue/plugins/webplugin_delegate_impl_mac.mm @@ -7,6 +7,7 @@ #include "webkit/glue/plugins/webplugin_delegate_impl.h" #include <string> +#include <unistd.h> #include <vector> #include "base/file_util.h" @@ -72,6 +73,9 @@ const int kPluginIdleThrottleDelayMs = 20; // 20ms (50Hz) int g_current_x_offset = 0; int g_current_y_offset = 0; +base::LazyInstance<std::set<WebPluginDelegateImpl*> > g_active_delegates( + base::LINKER_INITIALIZED); + } // namespace WebPluginDelegateImpl::WebPluginDelegateImpl( @@ -89,6 +93,7 @@ WebPluginDelegateImpl::WebPluginDelegateImpl( waiting_to_die_(false), last_mouse_x_(0), last_mouse_y_(0), + have_focus_(false), handle_event_depth_(0), user_gesture_message_posted_(this), user_gesture_msg_factory_(this) { @@ -105,9 +110,13 @@ WebPluginDelegateImpl::WebPluginDelegateImpl( // CoreAnimation, just ignore what QuickTime asks for. quirks_ |= PLUGIN_QUIRK_IGNORE_NEGOTIATED_DRAWING_MODEL; } + std::set<WebPluginDelegateImpl*>* delegates = g_active_delegates.Pointer(); + delegates->insert(this); } WebPluginDelegateImpl::~WebPluginDelegateImpl() { + std::set<WebPluginDelegateImpl*>* delegates = g_active_delegates.Pointer(); + delegates->erase(this); #ifndef NP_NO_QUICKDRAW if (qd_port_.port) { DisposeGWorld(qd_port_.port); @@ -402,11 +411,24 @@ void WebPluginDelegateImpl::WindowlessSetWindow(bool force_set_window) { DCHECK(err == NPERR_NO_ERROR); } -void WebPluginDelegateImpl::SetFocus() { +std::set<WebPluginDelegateImpl*> WebPluginDelegateImpl::GetActiveDelegates() { + std::set<WebPluginDelegateImpl*>* delegates = g_active_delegates.Pointer(); + return *delegates; +} + +void WebPluginDelegateImpl::FocusNotify(WebPluginDelegateImpl* delegate) { + if (waiting_to_die_) + return; + + have_focus_ = (delegate == this); + switch (instance()->event_model()) { case NPEventModelCarbon: { NPEvent focus_event = { 0 }; - focus_event.what = NPEventType_GetFocusEvent; + if (have_focus_) + focus_event.what = NPEventType_GetFocusEvent; + else + focus_event.what = NPEventType_LoseFocusEvent; focus_event.when = TickCount(); instance()->NPP_HandleEvent(&focus_event); break; @@ -415,13 +437,20 @@ void WebPluginDelegateImpl::SetFocus() { NPCocoaEvent focus_event; memset(&focus_event, 0, sizeof(focus_event)); focus_event.type = NPCocoaEventFocusChanged; - focus_event.data.focus.hasFocus = true; + focus_event.data.focus.hasFocus = have_focus_; instance()->NPP_HandleEvent(reinterpret_cast<NPEvent*>(&focus_event)); break; } } } +void WebPluginDelegateImpl::SetFocus() { + if (focus_notifier_) + focus_notifier_(this); + else + FocusNotify(this); +} + int WebPluginDelegateImpl::PluginDrawingModel() { if (quirks_ & PLUGIN_QUIRK_IGNORE_NEGOTIATED_DRAWING_MODEL) return NPDrawingModelQuickDraw; @@ -699,6 +728,12 @@ bool WebPluginDelegateImpl::HandleInputEvent(const WebInputEvent& event, UpdateWindowLocation(reinterpret_cast<WindowRef>(cg_context_.window), *mouse_event); } + // if we do not currently have focus and this is a mouseDown, trigger a + // notification that we are taking the keyboard focus. We can't just key + // off of incoming calls to SetFocus, since WebKit may already think we + // have it if we were the most recently focused element on our parent tab. + if (np_event.what == mouseDown && !have_focus_) + SetFocus(); } #endif |