Commit e52866fa authored by sky@chromium.org's avatar sky@chromium.org

Fixes couple of bugs in the TabStrip that could cause tabs to dance

around. Both only occurred when the active tab width differs from
inactive tab width (lots-o-tabs).
. ResizeLayoutTabs() had an optimization that avoided doing anything
  if the width of the first tab hasn't changed. Problems is if the
  first tab is active and inactive tabs have a smaller width than
  active tabs than the width won't have changed but we still need to
  layout. I removed the optimization.
. If selecting a tab triggers a bounds change the coordinates used by
  tab dragging would be wrong (because they extract them from the
  event, which is in the original coordinates).
. Needed to tweak rtl code.

BUG=140747
TEST=see bug, but make sure no weird behavior with tab selection/dragging on
windows/chrome-os.
R=ben@chromium.org


Review URL: https://chromiumcodereview.appspot.com/11821036

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@175991 0039d316-1c4b-4281-b951-d872f2087c98
parent 03f64898
...@@ -867,6 +867,11 @@ bool Tab::OnMousePressed(const ui::MouseEvent& event) { ...@@ -867,6 +867,11 @@ bool Tab::OnMousePressed(const ui::MouseEvent& event) {
(event.IsOnlyRightMouseButton() && event.flags() & ui::EF_FROM_TOUCH)) { (event.IsOnlyRightMouseButton() && event.flags() & ui::EF_FROM_TOUCH)) {
ui::ListSelectionModel original_selection; ui::ListSelectionModel original_selection;
original_selection.Copy(controller()->GetSelectionModel()); original_selection.Copy(controller()->GetSelectionModel());
// Changing the selection may cause our bounds to change. If that happens
// the location of the event may no longer be valid. Create a copy of the
// event in the parents coordinate, which won't change, and recreate an
// event after changing so the coordinates are correct.
ui::MouseEvent event_in_parent(event, static_cast<View*>(this), parent());
if (controller()->SupportsMultipleSelection()) { if (controller()->SupportsMultipleSelection()) {
if (event.IsShiftDown() && event.IsControlDown()) { if (event.IsShiftDown() && event.IsControlDown()) {
controller()->AddSelectionFromAnchorTo(this); controller()->AddSelectionFromAnchorTo(this);
...@@ -884,7 +889,9 @@ bool Tab::OnMousePressed(const ui::MouseEvent& event) { ...@@ -884,7 +889,9 @@ bool Tab::OnMousePressed(const ui::MouseEvent& event) {
} else if (!IsSelected()) { } else if (!IsSelected()) {
controller()->SelectTab(this); controller()->SelectTab(this);
} }
controller()->MaybeStartDrag(this, event, original_selection); ui::MouseEvent cloned_event(event_in_parent, parent(),
static_cast<View*>(this));
controller()->MaybeStartDrag(this, cloned_event, original_selection);
} }
return true; return true;
} }
...@@ -963,13 +970,18 @@ void Tab::OnGestureEvent(ui::GestureEvent* event) { ...@@ -963,13 +970,18 @@ void Tab::OnGestureEvent(ui::GestureEvent* event) {
if (event->details().touch_points() != 1) if (event->details().touch_points() != 1)
return; return;
// See comment in OnMousePressed() as to why we copy the event.
ui::GestureEvent event_in_parent(*event, static_cast<View*>(this),
parent());
ui::ListSelectionModel original_selection; ui::ListSelectionModel original_selection;
original_selection.Copy(controller()->GetSelectionModel()); original_selection.Copy(controller()->GetSelectionModel());
if (!IsSelected()) if (!IsSelected())
controller()->SelectTab(this); controller()->SelectTab(this);
gfx::Point loc(event->location()); gfx::Point loc(event->location());
views::View::ConvertPointToScreen(this, &loc); views::View::ConvertPointToScreen(this, &loc);
controller()->MaybeStartDrag(this, *event, original_selection); ui::GestureEvent cloned_event(event_in_parent, parent(),
static_cast<View*>(this));
controller()->MaybeStartDrag(this, cloned_event, original_selection);
break; break;
} }
......
...@@ -364,7 +364,6 @@ TabDragController::TabDragController() ...@@ -364,7 +364,6 @@ TabDragController::TabDragController()
attached_tabstrip_(NULL), attached_tabstrip_(NULL),
screen_(NULL), screen_(NULL),
host_desktop_type_(chrome::HOST_DESKTOP_TYPE_NATIVE), host_desktop_type_(chrome::HOST_DESKTOP_TYPE_NATIVE),
source_tab_offset_(0),
offset_to_width_ratio_(0), offset_to_width_ratio_(0),
old_focused_view_(NULL), old_focused_view_(NULL),
last_move_screen_loc_(0), last_move_screen_loc_(0),
...@@ -431,7 +430,6 @@ void TabDragController::Init( ...@@ -431,7 +430,6 @@ void TabDragController::Init(
source_tabstrip->GetWidget()->GetNativeView()); source_tabstrip->GetWidget()->GetNativeView());
host_desktop_type_ = chrome::GetHostDesktopTypeForNativeView( host_desktop_type_ = chrome::GetHostDesktopTypeForNativeView(
source_tabstrip->GetWidget()->GetNativeView()); source_tabstrip->GetWidget()->GetNativeView());
source_tab_offset_ = source_tab_offset;
start_point_in_screen_ = gfx::Point(source_tab_offset, mouse_offset.y()); start_point_in_screen_ = gfx::Point(source_tab_offset, mouse_offset.y());
views::View::ConvertPointToScreen(source_tab, &start_point_in_screen_); views::View::ConvertPointToScreen(source_tab, &start_point_in_screen_);
mouse_offset_ = mouse_offset; mouse_offset_ = mouse_offset;
...@@ -453,7 +451,8 @@ void TabDragController::Init( ...@@ -453,7 +451,8 @@ void TabDragController::Init(
MessageLoopForUI::current()->AddObserver(this); MessageLoopForUI::current()->AddObserver(this);
if (source_tab->width() > 0) { if (source_tab->width() > 0) {
offset_to_width_ratio_ = static_cast<float>(source_tab_offset_) / offset_to_width_ratio_ = static_cast<float>(
source_tab->GetMirroredXInView(source_tab_offset)) /
static_cast<float>(source_tab->width()); static_cast<float>(source_tab->width());
} }
InitWindowCreatePoint(); InitWindowCreatePoint();
......
...@@ -499,10 +499,7 @@ class TabDragController : public content::WebContentsDelegate, ...@@ -499,10 +499,7 @@ class TabDragController : public content::WebContentsDelegate,
// detached window is created at the right location. // detached window is created at the right location.
gfx::Point mouse_offset_; gfx::Point mouse_offset_;
// Offset of the mouse relative to the source tab. // Ratio of the x-coordinate of the |source_tab_offset| to the width of the
int source_tab_offset_;
// Ratio of the x-coordinate of the |source_tab_offset_| to the width of the
// tab. Not used for vertical tabs. // tab. Not used for vertical tabs.
float offset_to_width_ratio_; float offset_to_width_ratio_;
......
...@@ -1089,7 +1089,7 @@ void TabStrip::MaybeStartDrag( ...@@ -1089,7 +1089,7 @@ void TabStrip::MaybeStartDrag(
GetWidget()->SetCapture(this); GetWidget()->SetCapture(this);
drag_controller_.reset(new TabDragController); drag_controller_.reset(new TabDragController);
drag_controller_->Init( drag_controller_->Init(
this, tab, tabs, gfx::Point(x, y), tab->GetMirroredXInView(event.x()), this, tab, tabs, gfx::Point(x, y), event.x(),
selection_model, detach_behavior, move_behavior); selection_model, detach_behavior, move_behavior);
} }
...@@ -2125,16 +2125,11 @@ void TabStrip::ResizeLayoutTabs() { ...@@ -2125,16 +2125,11 @@ void TabStrip::ResizeLayoutTabs() {
// mini-tabs have the same width), so there is nothing to do. // mini-tabs have the same width), so there is nothing to do.
return; return;
} }
Tab* first_tab = tab_at(mini_tab_count); // Don't try and avoid layout based on tab sizes. If tabs are small enough
double unselected, selected; // then the width of the active tab may not change, but other widths may
GetDesiredTabWidths(tab_count(), mini_tab_count, &unselected, &selected); // have. This is particularly important if we've overflowed (all tabs are at
// TODO: this is always selected, should it be 'selected : unselected'? // the min).
int w = Round(first_tab->IsActive() ? selected : selected); StartResizeLayoutAnimation();
// We only want to run the animation if we're not already at the desired
// size.
if (abs(first_tab->width() - w) > 1)
StartResizeLayoutAnimation();
} }
void TabStrip::ResizeLayoutTabsFromTouch() { void TabStrip::ResizeLayoutTabsFromTouch() {
......
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