summaryrefslogtreecommitdiffstats
path: root/webkit/glue/plugins
diff options
context:
space:
mode:
authorstuartmorgan@chromium.org <stuartmorgan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-15 22:18:09 +0000
committerstuartmorgan@chromium.org <stuartmorgan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-15 22:18:09 +0000
commit3be438a82625d80192d3ecd49c3b6cfe16f58f1b (patch)
treeb5c217dcaaf5488da7958182bc59202b7389785a /webkit/glue/plugins
parent80044e61a25285e4ec1ff087c51eddccae09e06c (diff)
downloadchromium_src-3be438a82625d80192d3ecd49c3b6cfe16f58f1b.zip
chromium_src-3be438a82625d80192d3ecd49c3b6cfe16f58f1b.tar.gz
chromium_src-3be438a82625d80192d3ecd49c3b6cfe16f58f1b.tar.bz2
Filter certain drag events for Cocoa plugins to comply with the event spec
BUG=32743 TEST=Mouse drags starting outside a Cocoa plugin should not send events to the plugin (see bug for details). Review URL: http://codereview.chromium.org/862003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@41647 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/glue/plugins')
-rw-r--r--webkit/glue/plugins/webplugin_delegate_impl.h4
-rw-r--r--webkit/glue/plugins/webplugin_delegate_impl_mac.mm72
2 files changed, 76 insertions, 0 deletions
diff --git a/webkit/glue/plugins/webplugin_delegate_impl.h b/webkit/glue/plugins/webplugin_delegate_impl.h
index e4913f0..ac0168b 100644
--- a/webkit/glue/plugins/webplugin_delegate_impl.h
+++ b/webkit/glue/plugins/webplugin_delegate_impl.h
@@ -400,6 +400,10 @@ class WebPluginDelegateImpl : public webkit_glue::WebPluginDelegate {
// True if the plugin thinks it has keyboard focus
bool have_focus_;
+ // If non-zero, we are in the middle of a drag that started outside the
+ // plugin, and this corresponds to the WebInputEvent modifier flags for any
+ // buttons that were down when the mouse entered and are still down now.
+ int external_drag_buttons_;
// A function to call when we want to accept keyboard focus
void (*focus_notifier_)(WebPluginDelegateImpl* notifier);
diff --git a/webkit/glue/plugins/webplugin_delegate_impl_mac.mm b/webkit/glue/plugins/webplugin_delegate_impl_mac.mm
index 7ff1182..8b484b6 100644
--- a/webkit/glue/plugins/webplugin_delegate_impl_mac.mm
+++ b/webkit/glue/plugins/webplugin_delegate_impl_mac.mm
@@ -189,6 +189,7 @@ WebPluginDelegateImpl::WebPluginDelegateImpl(
renderer_(nil),
quirks_(0),
have_focus_(false),
+ external_drag_buttons_(0),
focus_notifier_(NULL),
containing_window_has_focus_(false),
initial_window_focus_(false),
@@ -1035,6 +1036,59 @@ static bool NPCocoaEventFromWebInputEvent(const WebInputEvent& event,
return false;
}
+// Returns the mask for just the button state in a WebInputEvent's modifiers.
+static int WebEventButtonModifierMask() {
+ return WebInputEvent::LeftButtonDown |
+ WebInputEvent::RightButtonDown |
+ WebInputEvent::MiddleButtonDown;
+}
+
+// Returns a new drag button state from applying |event| to the previous state.
+static int UpdatedDragStateFromEvent(int drag_buttons,
+ const WebInputEvent& event) {
+ switch (event.type) {
+ case WebInputEvent::MouseEnter:
+ return event.modifiers & WebEventButtonModifierMask();
+ case WebInputEvent::MouseUp: {
+ const WebMouseEvent* mouse_event =
+ static_cast<const WebMouseEvent*>(&event);
+ int new_buttons = drag_buttons;
+ if (mouse_event->button == WebMouseEvent::ButtonLeft)
+ new_buttons &= ~WebInputEvent::LeftButtonDown;
+ if (mouse_event->button == WebMouseEvent::ButtonMiddle)
+ new_buttons &= ~WebInputEvent::MiddleButtonDown;
+ if (mouse_event->button == WebMouseEvent::ButtonRight)
+ new_buttons &= ~WebInputEvent::RightButtonDown;
+ return new_buttons;
+ }
+ default:
+ return drag_buttons;
+ }
+}
+
+// Returns true if this is an event that looks like part of a drag with the
+// given button state.
+static bool EventIsRelatedToDrag(const WebInputEvent& event, int drag_buttons) {
+ const WebMouseEvent* mouse_event = static_cast<const WebMouseEvent*>(&event);
+ switch (event.type) {
+ case WebInputEvent::MouseUp:
+ // We only care about release of buttons that were part of the drag.
+ return ((mouse_event->button == WebMouseEvent::ButtonLeft &&
+ (drag_buttons & WebInputEvent::LeftButtonDown)) ||
+ (mouse_event->button == WebMouseEvent::ButtonMiddle &&
+ (drag_buttons & WebInputEvent::MiddleButtonDown)) ||
+ (mouse_event->button == WebMouseEvent::ButtonRight &&
+ (drag_buttons & WebInputEvent::RightButtonDown)));
+ case WebInputEvent::MouseMove:
+ case WebInputEvent::MouseEnter:
+ case WebInputEvent::MouseLeave:
+ return (event.modifiers & WebEventButtonModifierMask()) != 0;
+ default:
+ return false;
+ }
+ return false;
+}
+
bool WebPluginDelegateImpl::PlatformHandleInputEvent(
const WebInputEvent& event, WebCursorInfo* cursor_info) {
DCHECK(cursor_info != NULL);
@@ -1114,6 +1168,24 @@ bool WebPluginDelegateImpl::PlatformHandleInputEvent(
LOG(WARNING) << "NPCocoaEventFromWebInputEvent failed";
return false;
}
+
+ // Keep track of whether or not we are in a drag that started outside the
+ // plugin; if we are, filter out drag-related events (and convert the end
+ // of the external drag into an enter event) per the NPAPI Cocoa event
+ // model spec.
+ // If we eventually add a page-capture mode at the WebKit layer, mirroring
+ // the plugin-capture mode that handles drags starting inside the plugin
+ // and going outside, this can all be removed.
+ bool drag_related = EventIsRelatedToDrag(event, external_drag_buttons_);
+ external_drag_buttons_ = UpdatedDragStateFromEvent(external_drag_buttons_,
+ event);
+ if (drag_related) {
+ if (event.type == WebInputEvent::MouseUp && !external_drag_buttons_)
+ np_cocoa_event.type = NPCocoaEventMouseEntered;
+ else
+ return false;
+ }
+
NPAPI::ScopedCurrentPluginEvent event_scope(instance(), &np_cocoa_event);
ret = instance()->NPP_HandleEvent(&np_cocoa_event) != 0;
break;