diff options
Diffstat (limited to 'webkit')
4 files changed, 88 insertions, 4 deletions
diff --git a/webkit/glue/plugins/plugin_web_event_converter_mac.h b/webkit/glue/plugins/plugin_web_event_converter_mac.h index ec5b86f..02f113a 100644 --- a/webkit/glue/plugins/plugin_web_event_converter_mac.h +++ b/webkit/glue/plugins/plugin_web_event_converter_mac.h @@ -25,6 +25,12 @@ class PluginWebEventConverter { // could not be converted. virtual bool InitWithEvent(const WebKit::WebInputEvent& web_event); + // Sets a zoom level to apply to mouse coordinates. Must be called after + // InitWithEvent. + // TODO(stuartmorgan): Re-evaluate whether this is necessary when + // http://crbug.com/9996 is fixed. + virtual void SetZoomLevel(float zoom) = 0; + // Returns a pointer to a plugin event--suitable for passing to // NPP_HandleEvent--corresponding to the the web event this converter was // created with. The pointer is valid only as long as this object is. diff --git a/webkit/glue/plugins/plugin_web_event_converter_mac.mm b/webkit/glue/plugins/plugin_web_event_converter_mac.mm index 030ed06..d8b5c05 100644 --- a/webkit/glue/plugins/plugin_web_event_converter_mac.mm +++ b/webkit/glue/plugins/plugin_web_event_converter_mac.mm @@ -49,6 +49,8 @@ class CarbonPluginWebEventConverter : public PluginWebEventConverter { virtual bool InitWithEvent(const WebInputEvent& web_event); + virtual void SetZoomLevel(float zooom); + virtual void* plugin_event() { return &carbon_event_; } protected: @@ -75,6 +77,12 @@ bool CarbonPluginWebEventConverter::InitWithEvent( return PluginWebEventConverter::InitWithEvent(web_event); } +void CarbonPluginWebEventConverter::SetZoomLevel(float zoom) { + // Nothing to do here; because the event is built using the WebMouseEvent's + // global coordinates, and the dummy window is in the right place, zoom has + // no effect. +} + bool CarbonPluginWebEventConverter::ConvertKeyboardEvent( const WebKeyboardEvent& key_event) { // TODO: Figure out how to handle Unicode input to plugins, if that's @@ -177,6 +185,8 @@ public: virtual bool InitWithEvent(const WebInputEvent& web_event); + virtual void SetZoomLevel(float zoom); + virtual void* plugin_event() { return &cocoa_event_; } protected: @@ -202,6 +212,24 @@ bool CocoaPluginWebEventConverter::InitWithEvent( return PluginWebEventConverter::InitWithEvent(web_event); } +void CocoaPluginWebEventConverter::SetZoomLevel(float zoom) { + // Make sure we are dealing with a mouse event. + if (!(cocoa_event_.type != NPCocoaEventMouseDown || + cocoa_event_.type != NPCocoaEventMouseUp || + cocoa_event_.type != NPCocoaEventMouseMoved || + cocoa_event_.type != NPCocoaEventMouseEntered || + cocoa_event_.type != NPCocoaEventMouseExited || + cocoa_event_.type != NPCocoaEventMouseDragged || + cocoa_event_.type != NPCocoaEventScrollWheel)) { + NOTREACHED(); + return; + } + cocoa_event_.data.mouse.pluginX = + round(cocoa_event_.data.mouse.pluginX * zoom); + cocoa_event_.data.mouse.pluginY = + round(cocoa_event_.data.mouse.pluginY * zoom); +} + bool CocoaPluginWebEventConverter::ConvertKeyboardEvent( const WebKeyboardEvent& key_event) { cocoa_event_.data.key.keyCode = key_event.nativeKeyCode; diff --git a/webkit/glue/plugins/webplugin_delegate_impl.h b/webkit/glue/plugins/webplugin_delegate_impl.h index 2582d9b..a66f282 100644 --- a/webkit/glue/plugins/webplugin_delegate_impl.h +++ b/webkit/glue/plugins/webplugin_delegate_impl.h @@ -387,6 +387,13 @@ class WebPluginDelegateImpl : public webkit_glue::WebPluginDelegate { // Updates everything that depends on the plugin's absolute screen location. void PluginScreenLocationChanged(); + // Returns the apparent zoom ratio for the given event, as inferred from our + // current knowledge about about where on screen the plugin is. + // This is a temporary workaround for <http://crbug.com/9996>; once that is + // fixed we should have correct event coordinates (or an explicit + // notification of zoom level). + float ApparentEventZoomLevel(const WebKit::WebMouseEvent& event); + // Informs the browser about the updated accelerated drawing surface. void UpdateAcceleratedSurface(); diff --git a/webkit/glue/plugins/webplugin_delegate_impl_mac.mm b/webkit/glue/plugins/webplugin_delegate_impl_mac.mm index a99c39e..1d0b138 100644 --- a/webkit/glue/plugins/webplugin_delegate_impl_mac.mm +++ b/webkit/glue/plugins/webplugin_delegate_impl_mac.mm @@ -995,6 +995,37 @@ static bool EventIsRelatedToDrag(const WebInputEvent& event, int drag_buttons) { return false; } +float WebPluginDelegateImpl::ApparentEventZoomLevel( + const WebMouseEvent& event) { + float real_window_x = event.globalX - content_area_origin_.x(); + float real_window_y = event.globalY - content_area_origin_.y(); + if ((real_window_x == 0 && real_window_y == 0) || + (event.windowX == 0 && event.windowY == 0)) + return 1.0; + // There are two ways the window coordinates could be mismatched: + // 1) The plugin is zoomed (the event coordinates are scaled for the zoom + // level, even though window_rect_ isn't: <http://crbug.com/9996>). + // 2) The tracking of where the window is has gotten out of sync with reality. + // To distinguish, see if a zoom would explain both the x and y offsets. + // If not, this isn't a zoom. + + // Figure out the apparent zoom ratio using the larger value, since it's less + // affected by rounding error, then see if the other value is consistent. + float apparent_zoom = 1.0; + float discrepancy = 0.0; + if (event.windowY > event.windowX) { + apparent_zoom = real_window_y / event.windowY; + discrepancy = fabsf(event.windowX * apparent_zoom - real_window_x); + } else { + apparent_zoom = real_window_x / event.windowX; + discrepancy = fabsf(event.windowY * apparent_zoom - real_window_y); + } + if (discrepancy > 2.5) + return 1.0; + + return apparent_zoom; +} + bool WebPluginDelegateImpl::PlatformHandleInputEvent( const WebInputEvent& event, WebCursorInfo* cursor_info) { DCHECK(cursor_info != NULL); @@ -1009,7 +1040,10 @@ bool WebPluginDelegateImpl::PlatformHandleInputEvent( } #endif - if (WebInputEvent::isMouseEventType(event.type)) { + float zoom_level = 1.0; + const float kEpsilon = 0.001; // Smaller than an actual zoom would ever be. + if (WebInputEvent::isMouseEventType(event.type) || + event.type == WebInputEvent::MouseWheel) { // Check our plugin location before we send the event to the plugin, just // in case we somehow missed a plugin frame change. const WebMouseEvent* mouse_event = @@ -1019,9 +1053,15 @@ bool WebPluginDelegateImpl::PlatformHandleInputEvent( mouse_event->globalY - mouse_event->y - window_rect_.y()); if (content_origin.x() != content_area_origin_.x() || content_origin.y() != content_area_origin_.y()) { - DLOG(WARNING) << "Stale plugin location: " << content_area_origin_ - << " instead of " << content_origin; - SetContentAreaOrigin(content_origin); + // If there's a mismatch, figure out if it's due to zooming, or a missed + // window/plugin move (see comment in ApparentEventZoomLevel). + zoom_level = ApparentEventZoomLevel(*mouse_event); + if (fabsf(zoom_level - 1.0) < kEpsilon) { + DLOG(WARNING) << "Stale plugin content area location: " + << content_area_origin_ << " instead of " + << content_origin; + SetContentAreaOrigin(content_origin); + } } current_windowless_cursor_.GetCursorInfo(cursor_info); @@ -1085,6 +1125,9 @@ bool WebPluginDelegateImpl::PlatformHandleInputEvent( if (!(event_converter.get() && event_converter->InitWithEvent(event))) return false; void* plugin_event = event_converter->plugin_event(); + + if (fabsf(zoom_level - 1.0) > kEpsilon) + event_converter->SetZoomLevel(zoom_level); if (instance()->event_model() == NPEventModelCocoa) { // We recieve events related to drags starting outside the plugin, but the |