| Index: content/browser/renderer_host/input/touch_selection_controller.cc
|
| diff --git a/content/browser/renderer_host/input/touch_selection_controller.cc b/content/browser/renderer_host/input/touch_selection_controller.cc
|
| index 8193fb180668397e589d451edf2f107e782af49a..d5380487e255bb339823fe0b39f112633f0d2ce6 100644
|
| --- a/content/browser/renderer_host/input/touch_selection_controller.cc
|
| +++ b/content/browser/renderer_host/input/touch_selection_controller.cc
|
| @@ -4,6 +4,7 @@
|
|
|
| #include "content/browser/renderer_host/input/touch_selection_controller.h"
|
|
|
| +#include "base/auto_reset.h"
|
| #include "base/logging.h"
|
| #include "third_party/WebKit/public/web/WebInputEvent.h"
|
|
|
| @@ -12,7 +13,7 @@ namespace content {
|
| TouchSelectionController::TouchSelectionController(
|
| TouchSelectionControllerClient* client)
|
| : client_(client),
|
| - last_input_event_type_(INPUT_EVENT_TYPE_NONE),
|
| + response_pending_input_event_(INPUT_EVENT_TYPE_NONE),
|
| start_orientation_(TOUCH_HANDLE_ORIENTATION_UNDEFINED),
|
| start_visible_(false),
|
| end_orientation_(TOUCH_HANDLE_ORIENTATION_UNDEFINED),
|
| @@ -38,8 +39,11 @@ void TouchSelectionController::OnSelectionBoundsChanged(
|
| const gfx::RectF& end_rect,
|
| TouchHandleOrientation end_orientation,
|
| bool end_visible) {
|
| - if (!activate_selection_automatically_ && !activate_insertion_automatically_)
|
| + if (!activate_selection_automatically_ &&
|
| + !activate_insertion_automatically_) {
|
| + DCHECK_EQ(INPUT_EVENT_TYPE_NONE, response_pending_input_event_);
|
| return;
|
| + }
|
|
|
| if (start_rect_ == start_rect && end_rect_ == end_rect &&
|
| start_orientation_ == start_orientation &&
|
| @@ -54,6 +58,14 @@ void TouchSelectionController::OnSelectionBoundsChanged(
|
| end_orientation_ = end_orientation;
|
| end_visible_ = end_visible;
|
|
|
| + // Ensure that |response_pending_input_event_| is cleared after the method
|
| + // completes, while also making its current value available for the duration
|
| + // of the call.
|
| + InputEventType causal_input_event = response_pending_input_event_;
|
| + response_pending_input_event_ = INPUT_EVENT_TYPE_NONE;
|
| + base::AutoReset<InputEventType> auto_reset_response_pending_input_event(
|
| + &response_pending_input_event_, causal_input_event);
|
| +
|
| const bool is_selection_dragging =
|
| is_selection_active_ && (start_selection_handle_->is_dragging() ||
|
| end_selection_handle_->is_dragging());
|
| @@ -117,14 +129,14 @@ bool TouchSelectionController::WillHandleTouchEvent(
|
| }
|
|
|
| void TouchSelectionController::OnLongPressEvent() {
|
| - last_input_event_type_ = LONG_PRESS;
|
| + response_pending_input_event_ = LONG_PRESS;
|
| ShowSelectionHandlesAutomatically();
|
| ShowInsertionHandleAutomatically();
|
| ResetCachedValuesIfInactive();
|
| }
|
|
|
| void TouchSelectionController::OnTapEvent() {
|
| - last_input_event_type_ = TAP;
|
| + response_pending_input_event_ = TAP;
|
| activate_selection_automatically_ = false;
|
| DeactivateSelection();
|
| ShowInsertionHandleAutomatically();
|
| @@ -132,7 +144,7 @@ void TouchSelectionController::OnTapEvent() {
|
| }
|
|
|
| void TouchSelectionController::HideAndDisallowShowingAutomatically() {
|
| - last_input_event_type_ = INPUT_EVENT_TYPE_NONE;
|
| + response_pending_input_event_ = INPUT_EVENT_TYPE_NONE;
|
| DeactivateInsertion();
|
| DeactivateSelection();
|
| activate_insertion_automatically_ = false;
|
| @@ -248,7 +260,7 @@ void TouchSelectionController::ShowSelectionHandlesAutomatically() {
|
| void TouchSelectionController::OnInsertionChanged() {
|
| DeactivateSelection();
|
|
|
| - if (last_input_event_type_ == TAP && selection_empty_) {
|
| + if (response_pending_input_event_ == TAP && selection_empty_) {
|
| HideAndDisallowShowingAutomatically();
|
| return;
|
| }
|
| @@ -324,8 +336,12 @@ void TouchSelectionController::ActivateSelection() {
|
| end_selection_handle_->SetOrientation(end_orientation_);
|
| }
|
|
|
| - if (!is_selection_active_) {
|
| + // As a long press received while a selection is already active may trigger
|
| + // an entirely new selection, notify the client but avoid sending an
|
| + // intervening SELECTION_CLEARED update to avoid unnecessary state changes.
|
| + if (!is_selection_active_ || response_pending_input_event_ == LONG_PRESS) {
|
| is_selection_active_ = true;
|
| + response_pending_input_event_ = INPUT_EVENT_TYPE_NONE;
|
| client_->OnSelectionEvent(SELECTION_SHOWN, GetStartPosition());
|
| }
|
| }
|
|
|