OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/browser/renderer_host/render_widget_host_impl.h" | 5 #include "content/browser/renderer_host/render_widget_host_impl.h" |
6 | 6 |
7 #include <math.h> | 7 #include <math.h> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/auto_reset.h" | 10 #include "base/auto_reset.h" |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
140 view_being_painted_(false), | 140 view_being_painted_(false), |
141 ignore_input_events_(false), | 141 ignore_input_events_(false), |
142 text_direction_updated_(false), | 142 text_direction_updated_(false), |
143 text_direction_(WebKit::WebTextDirectionLeftToRight), | 143 text_direction_(WebKit::WebTextDirectionLeftToRight), |
144 text_direction_canceled_(false), | 144 text_direction_canceled_(false), |
145 suppress_next_char_events_(false), | 145 suppress_next_char_events_(false), |
146 pending_mouse_lock_request_(false), | 146 pending_mouse_lock_request_(false), |
147 allow_privileged_mouse_lock_(false), | 147 allow_privileged_mouse_lock_(false), |
148 has_touch_handler_(false), | 148 has_touch_handler_(false), |
149 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)), | 149 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)), |
| 150 tick_active_smooth_scroll_gestures_task_posted_(false), |
150 gesture_event_filter_(new GestureEventFilter(this)) { | 151 gesture_event_filter_(new GestureEventFilter(this)) { |
151 CHECK(delegate_); | 152 CHECK(delegate_); |
152 if (routing_id_ == MSG_ROUTING_NONE) { | 153 if (routing_id_ == MSG_ROUTING_NONE) { |
153 routing_id_ = process_->GetNextRoutingID(); | 154 routing_id_ = process_->GetNextRoutingID(); |
154 surface_id_ = GpuSurfaceTracker::Get()->AddSurfaceForRenderer( | 155 surface_id_ = GpuSurfaceTracker::Get()->AddSurfaceForRenderer( |
155 process_->GetID(), | 156 process_->GetID(), |
156 routing_id_); | 157 routing_id_); |
157 } else { | 158 } else { |
158 // TODO(piman): This is a O(N) lookup, where we could forward the | 159 // TODO(piman): This is a O(N) lookup, where we could forward the |
159 // information from the RenderWidgetHelper. The problem is that doing so | 160 // information from the RenderWidgetHelper. The problem is that doing so |
(...skipping 1425 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1585 } else if (WebInputEvent::isKeyboardEventType(type)) { | 1586 } else if (WebInputEvent::isKeyboardEventType(type)) { |
1586 ProcessKeyboardEventAck(type, processed); | 1587 ProcessKeyboardEventAck(type, processed); |
1587 } else if (type == WebInputEvent::MouseWheel) { | 1588 } else if (type == WebInputEvent::MouseWheel) { |
1588 ProcessWheelAck(processed); | 1589 ProcessWheelAck(processed); |
1589 } else if (WebInputEvent::isTouchEventType(type)) { | 1590 } else if (WebInputEvent::isTouchEventType(type)) { |
1590 ProcessTouchAck(event_type, processed); | 1591 ProcessTouchAck(event_type, processed); |
1591 } else if (WebInputEvent::isGestureEventType(type)) { | 1592 } else if (WebInputEvent::isGestureEventType(type)) { |
1592 ProcessGestureAck(processed, type); | 1593 ProcessGestureAck(processed, type); |
1593 } | 1594 } |
1594 | 1595 |
| 1596 // If an input ack is pending, then hold off ticking the gesture |
| 1597 // until we get an input ack. |
| 1598 if (in_process_event_types_.size() == 0 && |
| 1599 !active_smooth_scroll_gestures_.empty()) |
| 1600 TickActiveSmoothScrollGesture(); |
| 1601 |
1595 // This is used only for testing, and the other end does not use the | 1602 // This is used only for testing, and the other end does not use the |
1596 // source object. On linux, specifying | 1603 // source object. On linux, specifying |
1597 // Source<RenderWidgetHost> results in a very strange | 1604 // Source<RenderWidgetHost> results in a very strange |
1598 // runtime error in the epilogue of the enclosing | 1605 // runtime error in the epilogue of the enclosing |
1599 // (OnMsgInputEventAck) method, but not on other platforms; using | 1606 // (OnMsgInputEventAck) method, but not on other platforms; using |
1600 // 'void' instead is just as safe (since NotificationSource | 1607 // 'void' instead is just as safe (since NotificationSource |
1601 // is not actually typesafe) and avoids this error. | 1608 // is not actually typesafe) and avoids this error. |
1602 NotificationService::current()->Notify( | 1609 NotificationService::current()->Notify( |
1603 NOTIFICATION_RENDER_WIDGET_HOST_DID_RECEIVE_INPUT_EVENT_ACK, | 1610 NOTIFICATION_RENDER_WIDGET_HOST_DID_RECEIVE_INPUT_EVENT_ACK, |
1604 Source<void>(this), | 1611 Source<void>(this), |
1605 Details<int>(&type)); | 1612 Details<int>(&type)); |
1606 } | 1613 } |
1607 | 1614 |
1608 void RenderWidgetHostImpl::OnMsgBeginSmoothScroll( | 1615 void RenderWidgetHostImpl::OnMsgBeginSmoothScroll( |
1609 int gesture_id, bool scroll_down, bool scroll_far, int mouse_event_x, | 1616 int gesture_id, bool scroll_down, bool scroll_far, int mouse_event_x, |
1610 int mouse_event_y) { | 1617 int mouse_event_y) { |
1611 if (!view_) | 1618 if (!view_) |
1612 return; | 1619 return; |
1613 active_smooth_scroll_gestures_.insert( | 1620 active_smooth_scroll_gestures_.insert( |
1614 std::make_pair(gesture_id, | 1621 std::make_pair(gesture_id, |
1615 view_->CreateSmoothScrollGesture( | 1622 view_->CreateSmoothScrollGesture( |
1616 scroll_down, scroll_far, mouse_event_x, | 1623 scroll_down, scroll_far, mouse_event_x, |
1617 mouse_event_y))); | 1624 mouse_event_y))); |
| 1625 |
| 1626 // If an input ack is pending, then hold off ticking the gesture |
| 1627 // until we get an input ack. |
| 1628 if (!in_process_event_types_.empty()) |
| 1629 return; |
| 1630 if (tick_active_smooth_scroll_gestures_task_posted_) |
| 1631 return; |
1618 TickActiveSmoothScrollGesture(); | 1632 TickActiveSmoothScrollGesture(); |
1619 } | 1633 } |
1620 | 1634 |
1621 void RenderWidgetHostImpl::TickActiveSmoothScrollGesture() { | 1635 void RenderWidgetHostImpl::TickActiveSmoothScrollGesture() { |
1622 if (active_smooth_scroll_gestures_.size() == 0) | 1636 TRACE_EVENT0("input", "RenderWidgetHostImpl::TickActiveSmoothScrollGesture"); |
| 1637 tick_active_smooth_scroll_gestures_task_posted_ = false; |
| 1638 if (active_smooth_scroll_gestures_.empty()) { |
| 1639 TRACE_EVENT_INSTANT0("input", "EarlyOut_NoActiveScrollGesture"); |
1623 return; | 1640 return; |
| 1641 } |
1624 | 1642 |
1625 TimeTicks now = TimeTicks::HighResNow(); | 1643 base::TimeTicks now = TimeTicks::HighResNow(); |
| 1644 base::TimeDelta preferred_interval = |
| 1645 base::TimeDelta::FromMilliseconds(kSyntheticScrollMessageIntervalMs); |
| 1646 base::TimeDelta time_until_next_ideal_interval = |
| 1647 (last_smooth_scroll_gestures_tick_time_ + preferred_interval) - |
| 1648 now; |
| 1649 if (time_until_next_ideal_interval.InMilliseconds() > 0) { |
| 1650 TRACE_EVENT_INSTANT1( |
| 1651 "input", "EarlyOut_TickedTooRecently", |
| 1652 "delay", time_until_next_ideal_interval.InMilliseconds()); |
| 1653 // Post a task. |
| 1654 tick_active_smooth_scroll_gestures_task_posted_ = true; |
| 1655 MessageLoop::current()->PostDelayedTask( |
| 1656 FROM_HERE, |
| 1657 base::Bind(&RenderWidgetHostImpl::TickActiveSmoothScrollGesture, |
| 1658 weak_factory_.GetWeakPtr()), |
| 1659 time_until_next_ideal_interval); |
| 1660 return; |
| 1661 } |
1626 | 1662 |
1627 // Post the next tick right away so it is regular. | 1663 last_smooth_scroll_gestures_tick_time_ = now; |
1628 MessageLoop::current()->PostDelayedTask( | |
1629 FROM_HERE, | |
1630 base::Bind(&RenderWidgetHostImpl::TickActiveSmoothScrollGesture, | |
1631 weak_factory_.GetWeakPtr()), | |
1632 base::TimeDelta::FromMilliseconds(kSyntheticScrollMessageIntervalMs)); | |
1633 | 1664 |
1634 // Separate ticking of gestures from sending their completion messages. | 1665 // Separate ticking of gestures from sending their completion messages. |
1635 std::vector<int> ids_that_are_done; | 1666 std::vector<int> ids_that_are_done; |
1636 for (SmoothScrollGestureMap::iterator it = | 1667 for (SmoothScrollGestureMap::iterator it = |
1637 active_smooth_scroll_gestures_.begin(); | 1668 active_smooth_scroll_gestures_.begin(); |
1638 it != active_smooth_scroll_gestures_.end(); | 1669 it != active_smooth_scroll_gestures_.end(); |
1639 ++it) { | 1670 ++it) { |
1640 | 1671 |
1641 bool active = it->second->ForwardInputEvents(now, this); | 1672 bool active = it->second->ForwardInputEvents(now, this); |
1642 if (!active) | 1673 if (!active) |
1643 ids_that_are_done.push_back(it->first); | 1674 ids_that_are_done.push_back(it->first); |
1644 } | 1675 } |
1645 | 1676 |
1646 // Delete completed gestures and send their completion event. | 1677 // Delete completed gestures and send their completion event. |
1647 for(size_t i = 0; i < ids_that_are_done.size(); i++) { | 1678 for(size_t i = 0; i < ids_that_are_done.size(); i++) { |
1648 int id = ids_that_are_done[i]; | 1679 int id = ids_that_are_done[i]; |
1649 SmoothScrollGestureMap::iterator it = | 1680 SmoothScrollGestureMap::iterator it = |
1650 active_smooth_scroll_gestures_.find(id); | 1681 active_smooth_scroll_gestures_.find(id); |
1651 DCHECK(it != active_smooth_scroll_gestures_.end()); | 1682 DCHECK(it != active_smooth_scroll_gestures_.end()); |
1652 active_smooth_scroll_gestures_.erase(it); | 1683 active_smooth_scroll_gestures_.erase(it); |
1653 | 1684 |
1654 Send(new ViewMsg_SmoothScrollCompleted(routing_id_, id)); | 1685 Send(new ViewMsg_SmoothScrollCompleted(routing_id_, id)); |
1655 } | 1686 } |
| 1687 |
| 1688 // No need to post the next tick if an input is in flight. |
| 1689 if (!in_process_event_types_.empty()) |
| 1690 return; |
| 1691 |
| 1692 TRACE_EVENT_INSTANT1("input", "PostTickTask", |
| 1693 "delay", preferred_interval.InMilliseconds()); |
| 1694 tick_active_smooth_scroll_gestures_task_posted_ = true; |
| 1695 MessageLoop::current()->PostDelayedTask( |
| 1696 FROM_HERE, |
| 1697 base::Bind(&RenderWidgetHostImpl::TickActiveSmoothScrollGesture, |
| 1698 weak_factory_.GetWeakPtr()), |
| 1699 preferred_interval); |
1656 } | 1700 } |
1657 | 1701 |
1658 void RenderWidgetHostImpl::OnMsgSelectRangeAck() { | 1702 void RenderWidgetHostImpl::OnMsgSelectRangeAck() { |
1659 select_range_pending_ = false; | 1703 select_range_pending_ = false; |
1660 if (next_selection_range_.get()) { | 1704 if (next_selection_range_.get()) { |
1661 scoped_ptr<SelectionRange> next(next_selection_range_.Pass()); | 1705 scoped_ptr<SelectionRange> next(next_selection_range_.Pass()); |
1662 SelectRange(next->start, next->end); | 1706 SelectRange(next->start, next->end); |
1663 } | 1707 } |
1664 } | 1708 } |
1665 | 1709 |
(...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2075 return; | 2119 return; |
2076 | 2120 |
2077 OnRenderAutoResized(new_size); | 2121 OnRenderAutoResized(new_size); |
2078 } | 2122 } |
2079 | 2123 |
2080 void RenderWidgetHostImpl::DetachDelegate() { | 2124 void RenderWidgetHostImpl::DetachDelegate() { |
2081 delegate_ = NULL; | 2125 delegate_ = NULL; |
2082 } | 2126 } |
2083 | 2127 |
2084 } // namespace content | 2128 } // namespace content |
OLD | NEW |