diff options
author | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-01-30 07:18:39 +0000 |
---|---|---|
committer | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-01-30 07:18:39 +0000 |
commit | 0f5d5bb23c132494114444fae1539e05ec4a3523 (patch) | |
tree | a51fe5e5f949da4df15ab18b4704664e0bff0a8d /chrome | |
parent | 8b291589c73e1f4d146af6100ee7fbb56d384acb (diff) | |
download | chromium_src-0f5d5bb23c132494114444fae1539e05ec4a3523.zip chromium_src-0f5d5bb23c132494114444fae1539e05ec4a3523.tar.gz chromium_src-0f5d5bb23c132494114444fae1539e05ec4a3523.tar.bz2 |
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
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/ui/views/tabs/tab_drag_controller.cc | 40 | ||||
-rw-r--r-- | chrome/browser/ui/views/tabs/tab_drag_controller.h | 3 |
2 files changed, 29 insertions, 14 deletions
diff --git a/chrome/browser/ui/views/tabs/tab_drag_controller.cc b/chrome/browser/ui/views/tabs/tab_drag_controller.cc index 6580791..f570ec6 100644 --- a/chrome/browser/ui/views/tabs/tab_drag_controller.cc +++ b/chrome/browser/ui/views/tabs/tab_drag_controller.cc @@ -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_); diff --git a/chrome/browser/ui/views/tabs/tab_drag_controller.h b/chrome/browser/ui/views/tabs/tab_drag_controller.h index d4a778c..8b06b24 100644 --- a/chrome/browser/ui/views/tabs/tab_drag_controller.h +++ b/chrome/browser/ui/views/tabs/tab_drag_controller.h @@ -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(); |