Commit 0f5d5bb2 authored by sky@chromium.org's avatar sky@chromium.org

Fixes possible crash in tab dragging

Crash would occur in resetting selection model. It was possible to
attempt to reset the selection model with an active index of -1, which
TabStripModel does not like.

BUG=338285
TEST=see bug
R=ben@chromium.org

Review URL: https://codereview.chromium.org/149393009

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@247868 0039d316-1c4b-4281-b951-d872f2087c98
parent 8b291589
......@@ -1429,20 +1429,7 @@ void TabDragController::Detach(ReleaseCapture release_capture) {
attached_model->SetSelectionFromModel(selection_model_before_attach_);
} else if (attached_tabstrip_ == source_tabstrip_ &&
!initial_selection_model_.empty()) {
// First time detaching from the source tabstrip. Reset selection model to
// initial_selection_model_. Before resetting though we have to remove all
// the tabs from initial_selection_model_ as it was created with the tabs
// still there.
ui::ListSelectionModel selection_model;
selection_model.Copy(initial_selection_model_);
for (DragData::const_reverse_iterator i(drag_data_.rbegin());
i != drag_data_.rend(); ++i) {
selection_model.DecrementFrom(i->source_model_index);
}
// We may have cleared out the selection model. Only reset it if it
// contains something.
if (!selection_model.empty())
attached_model->SetSelectionFromModel(selection_model);
RestoreInitialSelection();
}
}
......@@ -1881,6 +1868,31 @@ void TabDragController::ResetSelection(TabStripModel* model) {
model->SetSelectionFromModel(selection_model);
}
void TabDragController::RestoreInitialSelection() {
// First time detaching from the source tabstrip. Reset selection model to
// initial_selection_model_. Before resetting though we have to remove all
// the tabs from initial_selection_model_ as it was created with the tabs
// still there.
ui::ListSelectionModel selection_model;
selection_model.Copy(initial_selection_model_);
for (DragData::const_reverse_iterator i(drag_data_.rbegin());
i != drag_data_.rend(); ++i) {
selection_model.DecrementFrom(i->source_model_index);
}
// We may have cleared out the selection model. Only reset it if it
// contains something.
if (selection_model.empty())
return;
// The anchor/active may have been among the tabs that were dragged out. Force
// the anchor/active to be valid.
if (selection_model.anchor() == ui::ListSelectionModel::kUnselectedIndex)
selection_model.set_anchor(selection_model.selected_indices()[0]);
if (selection_model.active() == ui::ListSelectionModel::kUnselectedIndex)
selection_model.set_active(selection_model.selected_indices()[0]);
GetModel(source_tabstrip_)->SetSelectionFromModel(selection_model);
}
void TabDragController::RevertDragAt(size_t drag_index) {
DCHECK(started_drag_);
DCHECK(source_tabstrip_);
......
......@@ -411,6 +411,9 @@ class TabDragController : public content::WebContentsDelegate,
// under us).
void ResetSelection(TabStripModel* model);
// Restores |initial_selection_model_| to the |source_tabstrip_|.
void RestoreInitialSelection();
// Finishes a succesful drag operation.
void CompleteDrag();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment