summaryrefslogtreecommitdiffstats
path: root/webkit/glue
diff options
context:
space:
mode:
authoramanda@chromium.org <amanda@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-11-20 18:26:16 +0000
committeramanda@chromium.org <amanda@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-11-20 18:26:16 +0000
commit27f5a6c85610ac97a87bc64918ead7891f58fda5 (patch)
tree8454f2a3e2526b203628c0e434ebee62e563ad0b /webkit/glue
parent8806b8a53168e161e8a2cbbf4051067c095832a9 (diff)
downloadchromium_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.h19
-rw-r--r--webkit/glue/plugins/webplugin_delegate_impl_mac.mm41
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