Commit a3fb797a authored by Connie Wan's avatar Connie Wan Committed by Commit Bot

Fix issues with group drag revert

See bug for details on the issues.

Issue #1: When dragging multiple tabs to the left, reverting doesn't return them to the correct position. Was happening even without groups.
- Fixed by adjusting the target index of revert to account for unreverted tabs.

Issue #2: Intermittent crashes.
- Seems to be fixed by crrev.com/c/2020908

Issue #3: Header is not returned to the initial view position.
- Fixed by adding a call to MoveTabGroup(), which is only needed when dragging within the same tabstrip (otherwise, a new group is being created and positioned correctly).

Issue #4: Selection is not restored correctly.
- Fixed by actively setting the index of group headers to kNoTab, so that checks in RestoreInitialSelection() correctly ignore group headers.

Note: The change at line 657 is to work with line 1656, which is assuming that source_model_index is explicitly set to kNoTab.

Bug: 1047761
Change-Id: I18af6a66d4e7788ed90c9be1f27556fc0018c6c3
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2036362
Commit-Queue: Connie Wan <connily@chromium.org>
Reviewed-by: default avatarCharlene Yan <cyan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#738296}
parent 3347b634
...@@ -654,8 +654,8 @@ void TabDragController::InitDragData(TabSlotView* view, ...@@ -654,8 +654,8 @@ void TabDragController::InitDragData(TabSlotView* view,
TabDragData* drag_data) { TabDragData* drag_data) {
TRACE_EVENT0("views", "TabDragController::InitDragData"); TRACE_EVENT0("views", "TabDragController::InitDragData");
const int source_model_index = source_context_->GetIndexOf(view); const int source_model_index = source_context_->GetIndexOf(view);
drag_data->source_model_index = source_model_index;
if (source_model_index != TabStripModel::kNoTab) { if (source_model_index != TabStripModel::kNoTab) {
drag_data->source_model_index = source_model_index;
drag_data->contents = source_context_->GetTabStripModel()->GetWebContentsAt( drag_data->contents = source_context_->GetTabStripModel()->GetWebContentsAt(
drag_data->source_model_index); drag_data->source_model_index);
drag_data->pinned = source_context_->IsTabPinned(static_cast<Tab*>(view)); drag_data->pinned = source_context_->IsTabPinned(static_cast<Tab*>(view));
...@@ -1605,6 +1605,8 @@ void TabDragController::RevertDrag() { ...@@ -1605,6 +1605,8 @@ void TabDragController::RevertDrag() {
source_context_->StoppedDragging(views, initial_tab_positions_, source_context_->StoppedDragging(views, initial_tab_positions_,
move_behavior_ == MOVE_VISIBLE_TABS, move_behavior_ == MOVE_VISIBLE_TABS,
false); false);
if (header_drag_)
source_context_->GetTabStripModel()->MoveTabGroup(group_.value());
} else { } else {
attached_context_->DraggedTabsDetached(); attached_context_->DraggedTabsDetached();
} }
...@@ -1676,6 +1678,7 @@ void TabDragController::RevertDragAt(size_t drag_index) { ...@@ -1676,6 +1678,7 @@ void TabDragController::RevertDragAt(size_t drag_index) {
base::AutoReset<bool> setter(&is_mutating_, true); base::AutoReset<bool> setter(&is_mutating_, true);
TabDragData* data = &(drag_data_[drag_index]); TabDragData* data = &(drag_data_[drag_index]);
int target_index = data->source_model_index;
if (attached_context_) { if (attached_context_) {
int index = attached_context_->GetTabStripModel()->GetIndexOfWebContents( int index = attached_context_->GetTabStripModel()->GetIndexOfWebContents(
data->contents); data->contents);
...@@ -1687,24 +1690,35 @@ void TabDragController::RevertDragAt(size_t drag_index) { ...@@ -1687,24 +1690,35 @@ void TabDragController::RevertDragAt(size_t drag_index) {
// TODO(beng): (Cleanup) seems like we should use Attach() for this // TODO(beng): (Cleanup) seems like we should use Attach() for this
// somehow. // somehow.
source_context_->GetTabStripModel()->InsertWebContentsAt( source_context_->GetTabStripModel()->InsertWebContentsAt(
data->source_model_index, std::move(detached_web_contents), target_index, std::move(detached_web_contents),
(data->pinned ? TabStripModel::ADD_PINNED : 0)); (data->pinned ? TabStripModel::ADD_PINNED : 0));
} else { } else {
// The Tab was moved within the TabDragContext where the drag // The Tab was moved within the TabDragContext where the drag
// was initiated. Move it back to the starting location. // was initiated. Move it back to the starting location.
// If the target index is to the right, then other unreverted tabs are
// occupying indices between this tab and the target index. Those
// unreverted tabs will later be reverted to the right of the target
// index, so we skip those indices.
if (target_index > index) {
for (size_t i = drag_index + 1; i < drag_data_.size(); ++i) {
if (drag_data_[i].contents)
++target_index;
}
}
source_context_->GetTabStripModel()->MoveWebContentsAt( source_context_->GetTabStripModel()->MoveWebContentsAt(
index, data->source_model_index, false); index, target_index, false);
} }
} else { } else {
// The Tab was detached from the TabDragContext where the drag // The Tab was detached from the TabDragContext where the drag
// began, and has not been attached to any other TabDragContext. // began, and has not been attached to any other TabDragContext.
// We need to put it back into the source TabDragContext. // We need to put it back into the source TabDragContext.
source_context_->GetTabStripModel()->InsertWebContentsAt( source_context_->GetTabStripModel()->InsertWebContentsAt(
data->source_model_index, std::move(data->owned_contents), target_index, std::move(data->owned_contents),
(data->pinned ? TabStripModel::ADD_PINNED : 0)); (data->pinned ? TabStripModel::ADD_PINNED : 0));
} }
source_context_->GetTabStripModel()->UpdateGroupForDragRevert( source_context_->GetTabStripModel()->UpdateGroupForDragRevert(
data->source_model_index, target_index,
data->tab_group_data.has_value() data->tab_group_data.has_value()
? base::Optional<tab_groups::TabGroupId>{data->tab_group_data.value() ? base::Optional<tab_groups::TabGroupId>{data->tab_group_data.value()
.group_id} .group_id}
......
...@@ -1895,7 +1895,7 @@ void PressEscapeWhileDetachedStep2(const BrowserList* browser_list) { ...@@ -1895,7 +1895,7 @@ void PressEscapeWhileDetachedStep2(const BrowserList* browser_list) {
// Detaches a tab and while detached presses escape to revert the drag. // Detaches a tab and while detached presses escape to revert the drag.
IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest, IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest,
PressEscapeWhileDetached) { RevertDragWhileDetached) {
AddTabsAndResetBrowser(browser(), 1); AddTabsAndResetBrowser(browser(), 1);
TabStrip* tab_strip = GetTabStripForBrowser(browser()); TabStrip* tab_strip = GetTabStripForBrowser(browser());
...@@ -2096,20 +2096,20 @@ IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTestWithTabGroupsEnabled, ...@@ -2096,20 +2096,20 @@ IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTestWithTabGroupsEnabled,
EXPECT_EQ(tab_strip2->GetGroupColorId(groups2[0]), group_color); EXPECT_EQ(tab_strip2->GetGroupColorId(groups2[0]), group_color);
} }
// Drags a tab group by the header to a new position and presses escape to // Drags a tab group by the header to a new position toward the right and
// revert the drag. // presses escape to revert the drag.
IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTestWithTabGroupsEnabled, IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTestWithTabGroupsEnabled,
PressEscapeDuringHeaderDrag) { RevertHeaderDragRight) {
TabStrip* tab_strip = GetTabStripForBrowser(browser()); TabStrip* tab_strip = GetTabStripForBrowser(browser());
TabStripModel* model = browser()->tab_strip_model(); TabStripModel* model = browser()->tab_strip_model();
AddTabsAndResetBrowser(browser(), 1); AddTabsAndResetBrowser(browser(), 3);
tab_groups::TabGroupId group = model->AddToNewGroup({0}); tab_groups::TabGroupId group = model->AddToNewGroup({0, 1});
StopAnimating(tab_strip); StopAnimating(tab_strip);
TabGroupHeader* group_header = tab_strip->group_header(group); TabGroupHeader* group_header = tab_strip->group_header(group);
EXPECT_FALSE(group_header->dragging()); EXPECT_FALSE(group_header->dragging());
ASSERT_TRUE(PressInput(GetCenterInScreenCoordinates(group_header))); ASSERT_TRUE(PressInput(GetCenterInScreenCoordinates(group_header)));
ASSERT_TRUE(DragInputTo(GetCenterInScreenCoordinates(tab_strip->tab_at(1)))); ASSERT_TRUE(DragInputTo(GetCenterInScreenCoordinates(tab_strip->tab_at(2))));
ASSERT_TRUE(group_header->dragging()); ASSERT_TRUE(group_header->dragging());
ASSERT_TRUE(ui_test_utils::SendKeyPressToWindowSync( ASSERT_TRUE(ui_test_utils::SendKeyPressToWindowSync(
...@@ -2118,12 +2118,42 @@ IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTestWithTabGroupsEnabled, ...@@ -2118,12 +2118,42 @@ IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTestWithTabGroupsEnabled,
EXPECT_EQ(1u, browser_list->size()); EXPECT_EQ(1u, browser_list->size());
EXPECT_FALSE(group_header->dragging()); EXPECT_FALSE(group_header->dragging());
EXPECT_EQ("0 1", IDString(browser()->tab_strip_model())); EXPECT_EQ("0 1 2 3", IDString(browser()->tab_strip_model()));
std::vector<tab_groups::TabGroupId> groups = std::vector<tab_groups::TabGroupId> groups =
model->group_model()->ListTabGroups(); model->group_model()->ListTabGroups();
EXPECT_EQ(1u, groups.size()); EXPECT_EQ(1u, groups.size());
EXPECT_THAT(model->group_model()->GetTabGroup(groups[0])->ListTabs(), EXPECT_THAT(model->group_model()->GetTabGroup(groups[0])->ListTabs(),
testing::ElementsAre(0)); testing::ElementsAre(0, 1));
}
// Drags a tab group by the header to a new position toward the left and presses
// escape to revert the drag.
IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTestWithTabGroupsEnabled,
RevertHeaderDragLeft) {
TabStrip* tab_strip = GetTabStripForBrowser(browser());
TabStripModel* model = browser()->tab_strip_model();
AddTabsAndResetBrowser(browser(), 3);
tab_groups::TabGroupId group = model->AddToNewGroup({2, 3});
StopAnimating(tab_strip);
TabGroupHeader* group_header = tab_strip->group_header(group);
EXPECT_FALSE(group_header->dragging());
ASSERT_TRUE(PressInput(GetCenterInScreenCoordinates(group_header)));
ASSERT_TRUE(DragInputTo(GetCenterInScreenCoordinates(tab_strip->tab_at(0))));
ASSERT_TRUE(group_header->dragging());
ASSERT_TRUE(ui_test_utils::SendKeyPressToWindowSync(
browser()->window()->GetNativeWindow(), ui::VKEY_ESCAPE, false, false,
false, false));
EXPECT_EQ(1u, browser_list->size());
EXPECT_FALSE(group_header->dragging());
EXPECT_EQ("0 1 2 3", IDString(browser()->tab_strip_model()));
std::vector<tab_groups::TabGroupId> groups =
model->group_model()->ListTabGroups();
EXPECT_EQ(1u, groups.size());
EXPECT_THAT(model->group_model()->GetTabGroup(groups[0])->ListTabs(),
testing::ElementsAre(2, 3));
} }
namespace { namespace {
...@@ -2156,7 +2186,7 @@ void PressEscapeWhileDetachedHeaderStep2( ...@@ -2156,7 +2186,7 @@ void PressEscapeWhileDetachedHeaderStep2(
// Drags a tab group by the header and while detached presses escape to revert // Drags a tab group by the header and while detached presses escape to revert
// the drag. // the drag.
IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTestWithTabGroupsEnabled, IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTestWithTabGroupsEnabled,
PressEscapeDuringHeaderDragWhileDetached) { RevertHeaderDragWhileDetached) {
TabStrip* tab_strip = GetTabStripForBrowser(browser()); TabStrip* tab_strip = GetTabStripForBrowser(browser());
TabStripModel* model = browser()->tab_strip_model(); TabStripModel* model = browser()->tab_strip_model();
AddTabsAndResetBrowser(browser(), 1); AddTabsAndResetBrowser(browser(), 1);
......
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