X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fcontent%2Fbrowser%2Frenderer_host%2Finput%2Finput_router_impl.cc;h=4f12318d88079bbeed1709666ec80a3e8500dcd2;hb=004985e17e624662a4c85c76a7654039dc83f028;hp=105051105bb1a7f5bff2551a063bec41ba313a65;hpb=2f108dbacb161091e42a3479f4e171339b7e7623;p=platform%2Fframework%2Fweb%2Fcrosswalk.git diff --git a/src/content/browser/renderer_host/input/input_router_impl.cc b/src/content/browser/renderer_host/input/input_router_impl.cc index 1050511..4f12318 100644 --- a/src/content/browser/renderer_host/input/input_router_impl.cc +++ b/src/content/browser/renderer_host/input/input_router_impl.cc @@ -4,6 +4,8 @@ #include "content/browser/renderer_host/input/input_router_impl.h" +#include + #include "base/auto_reset.h" #include "base/command_line.h" #include "base/metrics/histogram.h" @@ -13,14 +15,14 @@ #include "content/browser/renderer_host/input/input_router_client.h" #include "content/browser/renderer_host/input/touch_event_queue.h" #include "content/browser/renderer_host/input/touchpad_tap_suppression_controller.h" -#include "content/browser/renderer_host/input/web_touch_event_traits.h" #include "content/browser/renderer_host/overscroll_controller.h" #include "content/common/content_constants_internal.h" #include "content/common/edit_command.h" +#include "content/common/input/input_event_ack_state.h" #include "content/common/input/touch_action.h" +#include "content/common/input/web_touch_event_traits.h" #include "content/common/input_messages.h" #include "content/common/view_messages.h" -#include "content/port/common/input_event_ack_state.h" #include "content/public/browser/notification_service.h" #include "content/public/browser/notification_types.h" #include "content/public/browser/user_metrics.h" @@ -29,13 +31,6 @@ #include "ui/events/event.h" #include "ui/events/keycodes/keyboard_codes.h" -#if defined(OS_ANDROID) -#include "ui/gfx/android/view_configuration.h" -#include "ui/gfx/screen.h" -#else -#include "ui/events/gestures/gesture_configuration.h" -#endif - using base::Time; using base::TimeDelta; using base::TimeTicks; @@ -48,75 +43,6 @@ using blink::WebMouseWheelEvent; namespace content { namespace { -// TODO(jdduke): Instead of relying on command line flags or conditional -// conditional compilation here, we should instead use an InputRouter::Settings -// construct, supplied and customized by the RenderWidgetHostView. See -// crbug.com/343917. -bool GetTouchAckTimeoutDelay(base::TimeDelta* touch_ack_timeout_delay) { - CommandLine* parsed_command_line = CommandLine::ForCurrentProcess(); - if (!parsed_command_line->HasSwitch(switches::kTouchAckTimeoutDelayMs)) - return false; - - std::string timeout_string = parsed_command_line->GetSwitchValueASCII( - switches::kTouchAckTimeoutDelayMs); - size_t timeout_ms; - if (!base::StringToSizeT(timeout_string, &timeout_ms)) - return false; - - *touch_ack_timeout_delay = base::TimeDelta::FromMilliseconds(timeout_ms); - return true; -} - -#if defined(OS_ANDROID) -double GetTouchMoveSlopSuppressionLengthDips() { - const double touch_slop_length_pixels = - static_cast(gfx::ViewConfiguration::GetTouchSlopInPixels()); - const double device_scale_factor = - gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().device_scale_factor(); - return touch_slop_length_pixels / device_scale_factor; -} -#elif defined(USE_AURA) -double GetTouchMoveSlopSuppressionLengthDips() { - return ui::GestureConfiguration::max_touch_move_in_pixels_for_click(); -} -#else -double GetTouchMoveSlopSuppressionLengthDips() { - return 0; -} -#endif - -TouchEventQueue::TouchScrollingMode GetTouchScrollingMode() { - std::string modeString = CommandLine::ForCurrentProcess()-> - GetSwitchValueASCII(switches::kTouchScrollingMode); - if (modeString == switches::kTouchScrollingModeSyncTouchmove) - return TouchEventQueue::TOUCH_SCROLLING_MODE_SYNC_TOUCHMOVE; - if (modeString == switches::kTouchScrollingModeAbsorbTouchmove) - return TouchEventQueue::TOUCH_SCROLLING_MODE_ABSORB_TOUCHMOVE; - if (modeString == switches::kTouchScrollingModeTouchcancel) - return TouchEventQueue::TOUCH_SCROLLING_MODE_TOUCHCANCEL; - if (modeString != "") - LOG(ERROR) << "Invalid --touch-scrolling-mode option: " << modeString; - return TouchEventQueue::TOUCH_SCROLLING_MODE_DEFAULT; -} - -GestureEventWithLatencyInfo MakeGestureEvent(WebInputEvent::Type type, - double timestamp_seconds, - int x, - int y, - int modifiers, - const ui::LatencyInfo& latency) { - WebGestureEvent result; - - result.type = type; - result.x = x; - result.y = y; - result.sourceDevice = WebGestureEvent::Touchscreen; - result.timeStampSeconds = timestamp_seconds; - result.modifiers = modifiers; - - return GestureEventWithLatencyInfo(result, latency); -} - const char* GetEventAckName(InputEventAckState ack_result) { switch(ack_result) { case INPUT_EVENT_ACK_STATE_UNKNOWN: return "UNKNOWN"; @@ -131,10 +57,14 @@ const char* GetEventAckName(InputEventAckState ack_result) { } // namespace +InputRouterImpl::Config::Config() { +} + InputRouterImpl::InputRouterImpl(IPC::Sender* sender, InputRouterClient* client, InputAckHandler* ack_handler, - int routing_id) + int routing_id, + const Config& config) : sender_(sender), client_(client), ack_handler_(ack_handler), @@ -143,23 +73,23 @@ InputRouterImpl::InputRouterImpl(IPC::Sender* sender, move_caret_pending_(false), mouse_move_pending_(false), mouse_wheel_pending_(false), - touch_ack_timeout_supported_(false), current_view_flags_(0), current_ack_source_(ACK_SOURCE_NONE), - gesture_event_queue_(new GestureEventQueue(this, this)) { + flush_requested_(false), + touch_event_queue_(this, config.touch_config), + gesture_event_queue_(this, this, config.gesture_config) { DCHECK(sender); DCHECK(client); DCHECK(ack_handler); - touch_event_queue_.reset(new TouchEventQueue( - this, GetTouchScrollingMode(), GetTouchMoveSlopSuppressionLengthDips())); - touch_ack_timeout_supported_ = - GetTouchAckTimeoutDelay(&touch_ack_timeout_delay_); UpdateTouchAckTimeoutEnabled(); } InputRouterImpl::~InputRouterImpl() {} -void InputRouterImpl::Flush() {} +void InputRouterImpl::Flush() { + flush_requested_ = true; + SignalFlushedIfNecessary(); +} bool InputRouterImpl::SendInput(scoped_ptr message) { DCHECK(IPC_MESSAGE_ID_CLASS(message->type()) == InputMsgStart); @@ -179,20 +109,12 @@ bool InputRouterImpl::SendInput(scoped_ptr message) { void InputRouterImpl::SendMouseEvent( const MouseEventWithLatencyInfo& mouse_event) { - // Order is important here; we need to convert all MouseEvents before they - // propagate further, e.g., to the tap suppression controller. - if (CommandLine::ForCurrentProcess()->HasSwitch( - switches::kSimulateTouchScreenWithMouse)) { - SimulateTouchGestureWithMouse(mouse_event); - return; - } - if (mouse_event.event.type == WebInputEvent::MouseDown && - gesture_event_queue_->GetTouchpadTapSuppressionController()-> + gesture_event_queue_.GetTouchpadTapSuppressionController()-> ShouldDeferMouseDown(mouse_event)) return; if (mouse_event.event.type == WebInputEvent::MouseUp && - gesture_event_queue_->GetTouchpadTapSuppressionController()-> + gesture_event_queue_.GetTouchpadTapSuppressionController()-> ShouldSuppressMouseUp()) return; @@ -201,26 +123,39 @@ void InputRouterImpl::SendMouseEvent( void InputRouterImpl::SendWheelEvent( const MouseWheelEventWithLatencyInfo& wheel_event) { - // If there's already a mouse wheel event waiting to be sent to the renderer, - // add the new deltas to that event. Not doing so (e.g., by dropping the old - // event, as for mouse moves) results in very slow scrolling on the Mac (on - // which many, very small wheel events are sent). + SendWheelEvent(QueuedWheelEvent(wheel_event, false)); +} + +void InputRouterImpl::SendWheelEvent(const QueuedWheelEvent& wheel_event) { if (mouse_wheel_pending_) { + // If there's already a mouse wheel event waiting to be sent to the + // renderer, add the new deltas to that event. Not doing so (e.g., by + // dropping the old event, as for mouse moves) results in very slow + // scrolling on the Mac (on which many, very small wheel events are sent). + // Note that we can't coalesce wheel events for pinches because the GEQ + // expects one ACK for each (but it's fine to coalesce non-pinch wheels + // into a pinch one). Note that the GestureEventQueue ensures we only + // ever have a single pinch event queued here. if (coalesced_mouse_wheel_events_.empty() || - !coalesced_mouse_wheel_events_.back().CanCoalesceWith(wheel_event)) { + wheel_event.synthesized_from_pinch || + !coalesced_mouse_wheel_events_.back().event.CanCoalesceWith( + wheel_event.event)) { coalesced_mouse_wheel_events_.push_back(wheel_event); } else { - coalesced_mouse_wheel_events_.back().CoalesceWith(wheel_event); + coalesced_mouse_wheel_events_.back().event.CoalesceWith( + wheel_event.event); } return; } + mouse_wheel_pending_ = true; current_wheel_event_ = wheel_event; HISTOGRAM_COUNTS_100("Renderer.WheelQueueSize", coalesced_mouse_wheel_events_.size()); - FilterAndSendWebInputEvent(wheel_event.event, wheel_event.latency, false); + FilterAndSendWebInputEvent( + wheel_event.event.event, wheel_event.event.latency, false); } void InputRouterImpl::SendKeyboardEvent(const NativeWebKeyboardEvent& key_event, @@ -232,7 +167,7 @@ void InputRouterImpl::SendKeyboardEvent(const NativeWebKeyboardEvent& key_event, key_queue_.push_back(key_event); HISTOGRAM_COUNTS_100("Renderer.KeyboardQueueSize", key_queue_.size()); - gesture_event_queue_->FlingHasBeenHalted(); + gesture_event_queue_.FlingHasBeenHalted(); // Only forward the non-native portions of our event. FilterAndSendWebInputEvent(key_event, latency_info, is_keyboard_shortcut); @@ -242,25 +177,27 @@ void InputRouterImpl::SendGestureEvent( const GestureEventWithLatencyInfo& original_gesture_event) { event_stream_validator_.OnEvent(original_gesture_event.event); GestureEventWithLatencyInfo gesture_event(original_gesture_event); + if (touch_action_filter_.FilterGestureEvent(&gesture_event.event)) return; - touch_event_queue_->OnGestureScrollEvent(gesture_event); + if (gesture_event.event.sourceDevice == WebGestureEvent::Touchscreen) + touch_event_queue_.OnGestureScrollEvent(gesture_event); if (!IsInOverscrollGesture() && - !gesture_event_queue_->ShouldForward(gesture_event)) { + !gesture_event_queue_.ShouldForward(gesture_event)) { OverscrollController* controller = client_->GetOverscrollController(); if (controller) controller->DiscardingGestureEvent(gesture_event.event); return; } - FilterAndSendWebInputEvent(gesture_event.event, gesture_event.latency, false); + SendGestureEventImmediately(gesture_event); } void InputRouterImpl::SendTouchEvent( const TouchEventWithLatencyInfo& touch_event) { - touch_event_queue_->QueueEvent(touch_event); + touch_event_queue_.QueueEvent(touch_event); } // Forwards MouseEvent without passing it through @@ -301,6 +238,12 @@ void InputRouterImpl::SendTouchEventImmediately( void InputRouterImpl::SendGestureEventImmediately( const GestureEventWithLatencyInfo& gesture_event) { + if (gesture_event.event.type == WebInputEvent::GesturePinchUpdate && + gesture_event.event.sourceDevice == WebGestureEvent::Touchpad) { + SendSyntheticWheelEventForPinch(gesture_event); + return; + } + FilterAndSendWebInputEvent(gesture_event.event, gesture_event.latency, false); } @@ -311,8 +254,9 @@ const NativeWebKeyboardEvent* InputRouterImpl::GetLastKeyboardEvent() const { } bool InputRouterImpl::ShouldForwardTouchEvent() const { - // Always send a touch event if the renderer has a touch-event handler. - return touch_event_queue_->has_handlers(); + // Always send a touch event if the renderer has a touch-event handler or + // there are pending touch events. + return touch_event_queue_.has_handlers() || !touch_event_queue_.empty(); } void InputRouterImpl::OnViewUpdated(int view_flags) { @@ -357,7 +301,7 @@ void InputRouterImpl::OnTouchEventAck(const TouchEventWithLatencyInfo& event, void InputRouterImpl::OnGestureEventAck( const GestureEventWithLatencyInfo& event, InputEventAckState ack_result) { - touch_event_queue_->OnGestureEventAck(event, ack_result); + touch_event_queue_.OnGestureEventAck(event, ack_result); ProcessAckForOverscroll(event.event, ack_result); ack_handler_->OnGestureEventAck(event, ack_result); } @@ -397,19 +341,6 @@ void InputRouterImpl::FilterAndSendWebInputEvent( "type", WebInputEventTraits::GetName(input_event.type)); - // Transmit any pending wheel events on a non-wheel event. This ensures that - // final PhaseEnded wheel event is received, which is necessary to terminate - // rubber-banding, for example. - if (input_event.type != WebInputEvent::MouseWheel) { - WheelEventQueue mouse_wheel_events; - mouse_wheel_events.swap(coalesced_mouse_wheel_events_); - for (size_t i = 0; i < mouse_wheel_events.size(); ++i) { - OfferToHandlers(mouse_wheel_events[i].event, - mouse_wheel_events[i].latency, - false); - } - } - // Any input event cancels a pending mouse move event. next_mouse_move_.reset(); @@ -427,8 +358,16 @@ void InputRouterImpl::OfferToHandlers(const WebInputEvent& input_event, OfferToRenderer(input_event, latency_info, is_keyboard_shortcut); + // Touch events should always indicate in the event whether they are + // cancelable (respect ACK disposition) or not. + bool ignores_ack = WebInputEventTraits::IgnoresAckDisposition(input_event); + if (WebInputEvent::isTouchEventType(input_event.type)) { + DCHECK(!ignores_ack == + static_cast(input_event).cancelable); + } + // If we don't care about the ack disposition, send the ack immediately. - if (WebInputEventTraits::IgnoresAckDisposition(input_event.type)) { + if (ignores_ack) { ProcessInputEventAck(input_event.type, INPUT_EVENT_ACK_STATE_IGNORED, latency_info, @@ -453,7 +392,7 @@ bool InputRouterImpl::OfferToOverscrollController( const blink::WebGestureEvent& gesture_event = static_cast(input_event); // An ACK is expected for the event, so mark it as consumed. - consumed = !gesture_event_queue_->ShouldForward( + consumed = !gesture_event_queue_.ShouldForward( GestureEventWithLatencyInfo(gesture_event, latency_info)); } @@ -502,10 +441,10 @@ bool InputRouterImpl::OfferToRenderer(const WebInputEvent& input_event, bool is_keyboard_shortcut) { if (Send(new InputMsg_HandleInputEvent( routing_id(), &input_event, latency_info, is_keyboard_shortcut))) { - // Ack messages for ignored ack event types are not required, and might - // never be sent by the renderer. Consequently, such event types should not - // affect event timing or in-flight event count metrics. - if (!WebInputEventTraits::IgnoresAckDisposition(input_event.type)) { + // Ack messages for ignored ack event types should never be sent by the + // renderer. Consequently, such event types should not affect event time + // or in-flight event count metrics. + if (!WebInputEventTraits::IgnoresAckDisposition(input_event)) { input_event_start_time_ = TimeTicks::Now(); client_->IncrementInFlightEventCount(); } @@ -514,14 +453,46 @@ bool InputRouterImpl::OfferToRenderer(const WebInputEvent& input_event, return false; } +void InputRouterImpl::SendSyntheticWheelEventForPinch( + const GestureEventWithLatencyInfo& pinch_event) { + // We match typical trackpad behavior on Windows by sending fake wheel events + // with the ctrl modifier set when we see trackpad pinch gestures. Ideally + // we'd someday get a standard 'pinch' event and send that instead. + + WebMouseWheelEvent wheelEvent; + wheelEvent.type = WebInputEvent::MouseWheel; + wheelEvent.timeStampSeconds = pinch_event.event.timeStampSeconds; + wheelEvent.windowX = wheelEvent.x = pinch_event.event.x; + wheelEvent.windowY = wheelEvent.y = pinch_event.event.y; + wheelEvent.globalX = pinch_event.event.globalX; + wheelEvent.globalY = pinch_event.event.globalY; + wheelEvent.modifiers = + pinch_event.event.modifiers | WebInputEvent::ControlKey; + wheelEvent.deltaX = 0; + // The function to convert scales to deltaY values is designed to be + // compatible with websites existing use of wheel events, and with existing + // Windows trackpad behavior. In particular, we want: + // - deltas should accumulate via addition: f(s1*s2)==f(s1)+f(s2) + // - deltas should invert via negation: f(1/s) == -f(s) + // - zoom in should be positive: f(s) > 0 iff s > 1 + // - magnitude roughly matches wheels: f(2) > 25 && f(2) < 100 + // - a formula that's relatively easy to use from JavaScript + // Note that 'wheel' event deltaY values have their sign inverted. So to + // convert a wheel deltaY back to a scale use Math.exp(-deltaY/100). + DCHECK_GT(pinch_event.event.data.pinchUpdate.scale, 0); + wheelEvent.deltaY = 100.0f * log(pinch_event.event.data.pinchUpdate.scale); + wheelEvent.hasPreciseScrollingDeltas = true; + wheelEvent.wheelTicksX = 0; + wheelEvent.wheelTicksY = + pinch_event.event.data.pinchUpdate.scale > 1 ? 1 : -1; + + SendWheelEvent(QueuedWheelEvent( + MouseWheelEventWithLatencyInfo(wheelEvent, pinch_event.latency), true)); +} + void InputRouterImpl::OnInputEventAck(WebInputEvent::Type event_type, InputEventAckState ack_result, const ui::LatencyInfo& latency_info) { - // A synthetic ack will already have been sent for this event, and it should - // not affect event timing or in-flight count metrics. - if (WebInputEventTraits::IgnoresAckDisposition(event_type)) - return; - client_->DecrementInFlightEventCount(); // Log the time delta for processing an input event. @@ -561,13 +532,13 @@ void InputRouterImpl::OnHasTouchEventHandlers(bool has_handlers) { TRACE_EVENT1("input", "InputRouterImpl::OnHasTouchEventHandlers", "has_handlers", has_handlers); - touch_event_queue_->OnHasTouchEventHandlers(has_handlers); + touch_event_queue_.OnHasTouchEventHandlers(has_handlers); client_->OnHasTouchEventHandlers(has_handlers); } void InputRouterImpl::OnSetTouchAction(TouchAction touch_action) { // Synthetic touchstart events should get filtered out in RenderWidget. - DCHECK(touch_event_queue_->IsPendingAckTouchStart()); + DCHECK(touch_event_queue_.IsPendingAckTouchStart()); TRACE_EVENT1("input", "InputRouterImpl::OnSetTouchAction", "action", touch_action); @@ -609,6 +580,8 @@ void InputRouterImpl::ProcessInputEventAck( } else if (event_type != WebInputEvent::Undefined) { ack_handler_->OnUnexpectedEventAck(InputAckHandler::BAD_ACK_MESSAGE); } + + SignalFlushedIfNecessary(); } void InputRouterImpl::ProcessKeyboardAck(blink::WebInputEvent::Type type, @@ -649,20 +622,32 @@ void InputRouterImpl::ProcessMouseAck(blink::WebInputEvent::Type type, void InputRouterImpl::ProcessWheelAck(InputEventAckState ack_result, const ui::LatencyInfo& latency) { - ProcessAckForOverscroll(current_wheel_event_.event, ack_result); - // TODO(miletus): Add renderer side latency to each uncoalesced mouse // wheel event and add terminal component to each of them. - current_wheel_event_.latency.AddNewLatencyFrom(latency); - // Process the unhandled wheel event here before calling SendWheelEvent() - // since it will mutate current_wheel_event_. - ack_handler_->OnWheelEventAck(current_wheel_event_, ack_result); + current_wheel_event_.event.latency.AddNewLatencyFrom(latency); + + if (current_wheel_event_.synthesized_from_pinch) { + // Ack the GesturePinchUpdate event that generated this wheel event. + ProcessInputEventAck(WebInputEvent::GesturePinchUpdate, + ack_result, + current_wheel_event_.event.latency, + current_ack_source_); + } else { + // Process the unhandled wheel event here before calling SendWheelEvent() + // since it will mutate current_wheel_event_. + ProcessAckForOverscroll(current_wheel_event_.event.event, ack_result); + ack_handler_->OnWheelEventAck(current_wheel_event_.event, ack_result); + } + + // Mark the wheel event complete only after the ACKs have been handled above. + // For example, ACKing the GesturePinchUpdate could cause another + // GesturePinchUpdate to be sent, which should queue a wheel event rather than + // send it immediately. mouse_wheel_pending_ = false; - // Now send the next (coalesced) mouse wheel event. + // Send the next (coalesced or synthetic) mouse wheel event. if (!coalesced_mouse_wheel_events_.empty()) { - MouseWheelEventWithLatencyInfo next_wheel_event = - coalesced_mouse_wheel_events_.front(); + QueuedWheelEvent next_wheel_event = coalesced_mouse_wheel_events_.front(); coalesced_mouse_wheel_events_.pop_front(); SendWheelEvent(next_wheel_event); } @@ -674,19 +659,19 @@ void InputRouterImpl::ProcessGestureAck(WebInputEvent::Type type, // If |ack_result| originated from the overscroll controller, only // feed |gesture_event_queue_| the ack if it was expecting one. if (current_ack_source_ == OVERSCROLL_CONTROLLER && - !gesture_event_queue_->HasQueuedGestureEvents()) { + !gesture_event_queue_.ExpectingGestureAck()) { return; } // |gesture_event_queue_| will forward to OnGestureEventAck when appropriate. - gesture_event_queue_->ProcessGestureAck(ack_result, type, latency); + gesture_event_queue_.ProcessGestureAck(ack_result, type, latency); } void InputRouterImpl::ProcessTouchAck( InputEventAckState ack_result, const ui::LatencyInfo& latency) { // |touch_event_queue_| will forward to OnTouchEventAck when appropriate. - touch_event_queue_->ProcessTouchAck(ack_result, latency); + touch_event_queue_.ProcessTouchAck(ack_result, latency); } void InputRouterImpl::ProcessAckForOverscroll(const WebInputEvent& event, @@ -704,92 +689,7 @@ void InputRouterImpl::ProcessAckForOverscroll(const WebInputEvent& event, event, (INPUT_EVENT_ACK_STATE_CONSUMED == ack_result)); } -void InputRouterImpl::SimulateTouchGestureWithMouse( - const MouseEventWithLatencyInfo& event) { - const WebMouseEvent& mouse_event = event.event; - int x = mouse_event.x, y = mouse_event.y; - float dx = mouse_event.movementX, dy = mouse_event.movementY; - static int startX = 0, startY = 0; - - switch (mouse_event.button) { - case WebMouseEvent::ButtonLeft: - if (mouse_event.type == WebInputEvent::MouseDown) { - startX = x; - startY = y; - SendGestureEvent(MakeGestureEvent( - WebInputEvent::GestureScrollBegin, mouse_event.timeStampSeconds, - x, y, 0, event.latency)); - } - if (dx != 0 || dy != 0) { - GestureEventWithLatencyInfo gesture_event = MakeGestureEvent( - WebInputEvent::GestureScrollUpdate, mouse_event.timeStampSeconds, - x, y, 0, event.latency); - gesture_event.event.data.scrollUpdate.deltaX = dx; - gesture_event.event.data.scrollUpdate.deltaY = dy; - SendGestureEvent(gesture_event); - } - if (mouse_event.type == WebInputEvent::MouseUp) { - SendGestureEvent(MakeGestureEvent( - WebInputEvent::GestureScrollEnd, mouse_event.timeStampSeconds, - x, y, 0, event.latency)); - } - break; - case WebMouseEvent::ButtonMiddle: - if (mouse_event.type == WebInputEvent::MouseDown) { - startX = x; - startY = y; - SendGestureEvent(MakeGestureEvent( - WebInputEvent::GestureShowPress, mouse_event.timeStampSeconds, - x, y, 0, event.latency)); - SendGestureEvent(MakeGestureEvent( - WebInputEvent::GestureTapDown, mouse_event.timeStampSeconds, - x, y, 0, event.latency)); - } - if (mouse_event.type == WebInputEvent::MouseUp) { - SendGestureEvent(MakeGestureEvent( - WebInputEvent::GestureTap, mouse_event.timeStampSeconds, - x, y, 0, event.latency)); - } - break; - case WebMouseEvent::ButtonRight: - if (mouse_event.type == WebInputEvent::MouseDown) { - startX = x; - startY = y; - SendGestureEvent(MakeGestureEvent( - WebInputEvent::GestureScrollBegin, mouse_event.timeStampSeconds, - x, y, 0, event.latency)); - SendGestureEvent(MakeGestureEvent( - WebInputEvent::GesturePinchBegin, mouse_event.timeStampSeconds, - x, y, 0, event.latency)); - } - if (dx != 0 || dy != 0) { - dx = pow(dy < 0 ? 0.998f : 1.002f, fabs(dy)); - GestureEventWithLatencyInfo gesture_event = MakeGestureEvent( - WebInputEvent::GesturePinchUpdate, mouse_event.timeStampSeconds, - startX, startY, 0, event.latency); - gesture_event.event.data.pinchUpdate.scale = dx; - SendGestureEvent(gesture_event); - } - if (mouse_event.type == WebInputEvent::MouseUp) { - SendGestureEvent(MakeGestureEvent( - WebInputEvent::GesturePinchEnd, mouse_event.timeStampSeconds, - x, y, 0, event.latency)); - SendGestureEvent(MakeGestureEvent( - WebInputEvent::GestureScrollEnd, mouse_event.timeStampSeconds, - x, y, 0, event.latency)); - } - break; - case WebMouseEvent::ButtonNone: - break; - } -} - void InputRouterImpl::UpdateTouchAckTimeoutEnabled() { - if (!touch_ack_timeout_supported_) { - touch_event_queue_->SetAckTimeoutEnabled(false, base::TimeDelta()); - return; - } - // Mobile sites tend to be well-behaved with respect to touch handling, so // they have less need for the touch timeout fallback. const bool fixed_page_scale = (current_view_flags_ & FIXED_PAGE_SCALE) != 0; @@ -804,8 +704,28 @@ void InputRouterImpl::UpdateTouchAckTimeoutEnabled() { const bool touch_ack_timeout_enabled = !fixed_page_scale && !mobile_viewport && !touch_action_none; - touch_event_queue_->SetAckTimeoutEnabled(touch_ack_timeout_enabled, - touch_ack_timeout_delay_); + touch_event_queue_.SetAckTimeoutEnabled(touch_ack_timeout_enabled); +} + +void InputRouterImpl::SignalFlushedIfNecessary() { + if (!flush_requested_) + return; + + if (HasPendingEvents()) + return; + + flush_requested_ = false; + client_->DidFlush(); +} + +bool InputRouterImpl::HasPendingEvents() const { + return !touch_event_queue_.empty() || + !gesture_event_queue_.empty() || + !key_queue_.empty() || + mouse_move_pending_ || + mouse_wheel_pending_ || + select_range_pending_ || + move_caret_pending_; } bool InputRouterImpl::IsInOverscrollGesture() const { @@ -813,4 +733,17 @@ bool InputRouterImpl::IsInOverscrollGesture() const { return controller && controller->overscroll_mode() != OVERSCROLL_NONE; } +InputRouterImpl::QueuedWheelEvent::QueuedWheelEvent() + : synthesized_from_pinch(false) { +} + +InputRouterImpl::QueuedWheelEvent::QueuedWheelEvent( + const MouseWheelEventWithLatencyInfo& event, + bool synthesized_from_pinch) + : event(event), synthesized_from_pinch(synthesized_from_pinch) { +} + +InputRouterImpl::QueuedWheelEvent::~QueuedWheelEvent() { +} + } // namespace content