#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"
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),
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 &&
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());
}
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();
}
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;
void TouchSelectionController::OnInsertionChanged() {
DeactivateSelection();
- if (last_input_event_type_ == TAP && selection_empty_) {
+ if (response_pending_input_event_ == TAP && selection_empty_) {
HideAndDisallowShowingAutomatically();
return;
}
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());
}
}