summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorsky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-01-30 07:18:39 +0000
committersky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-01-30 07:18:39 +0000
commit0f5d5bb23c132494114444fae1539e05ec4a3523 (patch)
treea51fe5e5f949da4df15ab18b4704664e0bff0a8d /chrome
parent8b291589c73e1f4d146af6100ee7fbb56d384acb (diff)
downloadchromium_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.cc40
-rw-r--r--chrome/browser/ui/views/tabs/tab_drag_controller.h3
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();