| Index: chrome/browser/renderer_host/render_widget_host.cc
|
| diff --git a/chrome/browser/renderer_host/render_widget_host.cc b/chrome/browser/renderer_host/render_widget_host.cc
|
| index 479851633abb18edf4aca69502d82336539e0107..8c5ff4b36a08688fb13e31de02453fca0a24f671 100644
|
| --- a/chrome/browser/renderer_host/render_widget_host.cc
|
| +++ b/chrome/browser/renderer_host/render_widget_host.cc
|
| @@ -66,6 +66,7 @@ RenderWidgetHost::RenderWidgetHost(RenderProcessHost* process,
|
| repaint_ack_pending_(false),
|
| resize_ack_pending_(false),
|
| mouse_move_pending_(false),
|
| + mouse_wheel_pending_(false),
|
| needs_repainting_on_restore_(false),
|
| is_unresponsive_(false),
|
| in_get_backing_store_(false),
|
| @@ -376,6 +377,31 @@ void RenderWidgetHost::ForwardWheelEvent(
|
| if (process_->ignore_input_events())
|
| return;
|
|
|
| + // 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).
|
| + if (mouse_wheel_pending_) {
|
| + if (coalesced_mouse_wheel_events_.empty() ||
|
| + coalesced_mouse_wheel_events_.back().modifiers
|
| + != wheel_event.modifiers ||
|
| + coalesced_mouse_wheel_events_.back().scrollByPage
|
| + != wheel_event.scrollByPage) {
|
| + coalesced_mouse_wheel_events_.push_back(wheel_event);
|
| + } else {
|
| + coalesced_mouse_wheel_events_.back().deltaX += wheel_event.deltaX;
|
| + coalesced_mouse_wheel_events_.back().deltaY += wheel_event.deltaY;
|
| + DCHECK_GE(wheel_event.timeStampSeconds,
|
| + coalesced_mouse_wheel_events_.back().timeStampSeconds);
|
| + coalesced_mouse_wheel_events_.back().timeStampSeconds =
|
| + wheel_event.timeStampSeconds;
|
| + }
|
| + return;
|
| + }
|
| + mouse_wheel_pending_ = true;
|
| +
|
| + HISTOGRAM_COUNTS_100("MPArch.RWH_WheelQueueSize",
|
| + coalesced_mouse_wheel_events_.size());
|
| ForwardInputEvent(wheel_event, sizeof(WebMouseWheelEvent), false);
|
| }
|
|
|
| @@ -456,6 +482,10 @@ void RenderWidgetHost::ForwardInputEvent(const WebInputEvent& input_event,
|
| // Any input event cancels a pending mouse move event.
|
| next_mouse_move_.reset();
|
|
|
| + // Any non-wheel input event cancels pending wheel events.
|
| + if (input_event.type != WebInputEvent::MouseWheel)
|
| + coalesced_mouse_wheel_events_.clear();
|
| +
|
| StartHangMonitorTimeout(TimeDelta::FromMilliseconds(kHungRendererDelayMs));
|
| }
|
|
|
| @@ -477,9 +507,12 @@ void RenderWidgetHost::RendererExited() {
|
| // from a crashed renderer.
|
| renderer_initialized_ = false;
|
|
|
| - // Must reset these to ensure that mouse move events work with a new renderer.
|
| + // Must reset these to ensure that mouse move/wheel events work with a new
|
| + // renderer.
|
| mouse_move_pending_ = false;
|
| next_mouse_move_.reset();
|
| + mouse_wheel_pending_ = false;
|
| + coalesced_mouse_wheel_events_.clear();
|
|
|
| // Must reset these to ensure that keyboard events work with a new renderer.
|
| key_queue_.clear();
|
| @@ -742,6 +775,16 @@ void RenderWidgetHost::OnMsgInputEventAck(const IPC::Message& message) {
|
| DCHECK(next_mouse_move_->type == WebInputEvent::MouseMove);
|
| ForwardMouseEvent(*next_mouse_move_);
|
| }
|
| + } else if (type == WebInputEvent::MouseWheel) {
|
| + mouse_wheel_pending_ = false;
|
| +
|
| + // Now send the next (coalesced) mouse wheel event.
|
| + if (!coalesced_mouse_wheel_events_.empty()) {
|
| + WebMouseWheelEvent next_wheel_event =
|
| + coalesced_mouse_wheel_events_.front();
|
| + coalesced_mouse_wheel_events_.pop_front();
|
| + ForwardWheelEvent(next_wheel_event);
|
| + }
|
| } else if (WebInputEvent::isKeyboardEventType(type)) {
|
| bool processed = false;
|
| if (!message.ReadBool(&iter, &processed))
|
|
|