| Index: content/browser/renderer_host/render_widget_host_view_mac.mm
|
| diff --git a/content/browser/renderer_host/render_widget_host_view_mac.mm b/content/browser/renderer_host/render_widget_host_view_mac.mm
|
| index 86f5a774225371db85fd1cc8dbf5f64a44489c0e..a87576cea28eb693aa4979791e369aa00cb86506 100644
|
| --- a/content/browser/renderer_host/render_widget_host_view_mac.mm
|
| +++ b/content/browser/renderer_host/render_widget_host_view_mac.mm
|
| @@ -75,6 +75,7 @@
|
| #include "ui/gfx/geometry/point.h"
|
| #include "ui/gfx/geometry/rect_conversions.h"
|
| #include "ui/gfx/geometry/size_conversions.h"
|
| +#include "ui/gfx/geometry/vector2d_f.h"
|
| #include "ui/gfx/scoped_ns_graphics_context_save_gstate_mac.h"
|
| #include "ui/gfx/screen.h"
|
| #include "ui/gl/gl_switches.h"
|
| @@ -391,6 +392,90 @@ blink::WebScreenInfo GetWebScreenInfo(NSView* view) {
|
|
|
| namespace content {
|
|
|
| +class WheelEventRailFilterMac {
|
| + public:
|
| + WheelEventRailFilterMac() :
|
| + mode_(MODE_UNINITIALIZED) {
|
| + }
|
| +
|
| + ~WheelEventRailFilterMac() {
|
| + }
|
| +
|
| + WebMouseWheelEvent FilterWheelEvent(const WebMouseWheelEvent& event) {
|
| + // This number came from 0.5 feeling too big and 0.9 feeling too small.
|
| + const float kDecayConstant = 0.8f;
|
| + // Require a slightly-more-than-diagonal motion against the current
|
| + // scroll to break the rails.
|
| + const float kSinThetaToBreakRails = 0.8f;
|
| + // Require a consistently-unidirectional motion to reset the rails
|
| + // after they have been broken.
|
| + const float kSinThetaToResetRails = 0.02f;
|
| +
|
| + if (event.phase == blink::WebMouseWheelEvent::PhaseBegan) {
|
| + mode_ = MODE_UNINITIALIZED;
|
| + decayed_delta_ = gfx::Vector2dF();
|
| + }
|
| + if (event.deltaX == 0 && event.deltaY == 0)
|
| + return event;
|
| +
|
| + decayed_delta_.Scale(kDecayConstant);
|
| + decayed_delta_ += gfx::Vector2dF(fabsf(event.deltaX), fabsf(event.deltaY));
|
| +
|
| + float sin_theta_horizontal = decayed_delta_.y() / decayed_delta_.Length();
|
| + float sin_theta_vertical = decayed_delta_.x() / decayed_delta_.Length();
|
| +
|
| + switch (mode_) {
|
| + case MODE_UNINITIALIZED:
|
| + if (decayed_delta_.x() > decayed_delta_.y())
|
| + mode_ = MODE_HORIZONTAL;
|
| + else
|
| + mode_ = MODE_VERTICAL;
|
| + break;
|
| + case MODE_HORIZONTAL:
|
| + if (sin_theta_horizontal > kSinThetaToBreakRails)
|
| + mode_ = MODE_FREE;
|
| + break;
|
| + case MODE_VERTICAL:
|
| + if (sin_theta_vertical > kSinThetaToBreakRails)
|
| + mode_ = MODE_FREE;
|
| + break;
|
| + case MODE_FREE:
|
| + if (sin_theta_horizontal < kSinThetaToResetRails)
|
| + mode_ = MODE_HORIZONTAL;
|
| + if (sin_theta_vertical < kSinThetaToResetRails)
|
| + mode_ = MODE_VERTICAL;
|
| + break;
|
| + }
|
| +
|
| + WebMouseWheelEvent result = event;
|
| + switch (mode_) {
|
| + case MODE_HORIZONTAL:
|
| + printf("mode:Horiz\n");
|
| + result.deltaY = 0;
|
| + break;
|
| + case MODE_VERTICAL:
|
| + printf("mode:Vert\n");
|
| + result.deltaX = 0;
|
| + break;
|
| + default:
|
| + printf("Free\n");
|
| + break;
|
| + }
|
| + return result;
|
| + }
|
| +
|
| + private:
|
| + enum Mode {
|
| + MODE_UNINITIALIZED,
|
| + MODE_HORIZONTAL,
|
| + MODE_VERTICAL,
|
| + MODE_FREE,
|
| + };
|
| + Mode mode_;
|
| + gfx::Vector2dF decayed_delta_;
|
| + gfx::Vector2dF decayed_delta_other_;
|
| +};
|
| +
|
| ////////////////////////////////////////////////////////////////////////////////
|
| // DelegatedFrameHost, public:
|
|
|
| @@ -525,7 +610,8 @@ void RenderWidgetHostViewBase::GetDefaultScreenInfo(
|
|
|
| RenderWidgetHostViewMac::RenderWidgetHostViewMac(RenderWidgetHost* widget,
|
| bool is_guest_view_hack)
|
| - : render_widget_host_(RenderWidgetHostImpl::From(widget)),
|
| + : wheel_event_rail_filter_(new WheelEventRailFilterMac),
|
| + render_widget_host_(RenderWidgetHostImpl::From(widget)),
|
| text_input_type_(ui::TEXT_INPUT_TYPE_NONE),
|
| can_compose_inline_(true),
|
| browser_compositor_state_(BrowserCompositorDestroyed),
|
| @@ -2257,7 +2343,9 @@ void RenderWidgetHostViewMac::OnDisplayMetricsChanged(
|
| bool canRubberbandRight = true;
|
| const WebMouseWheelEvent webEvent = WebInputEventFactory::mouseWheelEvent(
|
| event, self, canRubberbandLeft, canRubberbandRight);
|
| - renderWidgetHostView_->render_widget_host_->ForwardWheelEvent(webEvent);
|
| + renderWidgetHostView_->render_widget_host_->ForwardWheelEvent(
|
| + renderWidgetHostView_->wheel_event_rail_filter_->FilterWheelEvent(
|
| + webEvent));
|
| }
|
|
|
| if (endWheelMonitor_) {
|
| @@ -2380,7 +2468,9 @@ void RenderWidgetHostViewMac::OnDisplayMetricsChanged(
|
| BOOL canRubberbandRight = [responderDelegate_ canRubberbandRight:self];
|
| const WebMouseWheelEvent webEvent = WebInputEventFactory::mouseWheelEvent(
|
| event, self, canRubberbandLeft, canRubberbandRight);
|
| - renderWidgetHostView_->render_widget_host_->ForwardWheelEvent(webEvent);
|
| + renderWidgetHostView_->render_widget_host_->ForwardWheelEvent(
|
| + renderWidgetHostView_->wheel_event_rail_filter_->FilterWheelEvent(
|
| + webEvent));
|
| }
|
| }
|
|
|
|
|