| Index: chrome/browser/ui/views/tabs/tab_drag_controller.cc
|
| diff --git a/chrome/browser/ui/views/tabs/tab_drag_controller.cc b/chrome/browser/ui/views/tabs/tab_drag_controller.cc
|
| index b6660f35767649d7ca8b4b79932e202553a63ebb..cc196d2ed3c626da773d284aeb8892cd57662d8e 100644
|
| --- a/chrome/browser/ui/views/tabs/tab_drag_controller.cc
|
| +++ b/chrome/browser/ui/views/tabs/tab_drag_controller.cc
|
| @@ -210,11 +210,14 @@ void SetWindowPositionManaged(gfx::NativeWindow window, bool value) {
|
| }
|
|
|
| // Returns true if |tab_strip| browser window is docked.
|
| -bool IsDocked(const TabStrip* tab_strip) {
|
| +bool IsDockedOrSnapped(const TabStrip* tab_strip) {
|
| #if defined(USE_ASH)
|
| DCHECK(tab_strip);
|
| - return ash::wm::GetWindowState(
|
| - tab_strip->GetWidget()->GetNativeWindow())->IsDocked();
|
| + ash::wm::WindowState* window_state =
|
| + ash::wm::GetWindowState(tab_strip->GetWidget()->GetNativeWindow());
|
| + return window_state->IsDocked() ||
|
| + window_state->window_show_type() == ash::wm::SHOW_TYPE_LEFT_SNAPPED ||
|
| + window_state->window_show_type() == ash::wm::SHOW_TYPE_RIGHT_SNAPPED;
|
| #endif
|
| return false;
|
| }
|
| @@ -546,6 +549,31 @@ void TabDragController::Drag(const gfx::Point& point_in_screen) {
|
| Attach(source_tabstrip_, gfx::Point());
|
| if (detach_into_browser_ && static_cast<int>(drag_data_.size()) ==
|
| GetModel(source_tabstrip_)->count()) {
|
| +#if defined(USE_ASH)
|
| + if (host_desktop_type_ == chrome::HOST_DESKTOP_TYPE_ASH &&
|
| + (was_source_maximized_ || was_source_fullscreen_)) {
|
| + // When all tabs in a maximized browser are dragged the browser gets
|
| + // restored during the drag and maximized back when the drag ends.
|
| + views::Widget* widget = GetAttachedBrowserWidget();
|
| + const int last_tabstrip_width = attached_tabstrip_->tab_area_width();
|
| + std::vector<gfx::Rect> drag_bounds = CalculateBoundsForDraggedTabs();
|
| + OffsetX(GetAttachedDragPoint(point_in_screen).x(), &drag_bounds);
|
| + gfx::Rect new_bounds(CalculateDraggedBrowserBounds(source_tabstrip_,
|
| + point_in_screen,
|
| + &drag_bounds));
|
| + new_bounds.Offset(-widget->GetRestoredBounds().x() +
|
| + point_in_screen.x() -
|
| + mouse_offset_.x(), 0);
|
| + widget->SetVisibilityChangedAnimationsEnabled(false);
|
| + widget->Restore();
|
| + widget->SetBounds(new_bounds);
|
| + AdjustBrowserAndTabBoundsForDrag(last_tabstrip_width,
|
| + point_in_screen,
|
| + &drag_bounds);
|
| + widget->SetVisibilityChangedAnimationsEnabled(true);
|
| + is_dragging_new_browser_ = true;
|
| + }
|
| +#endif
|
| RunMoveLoop(GetWindowOffset(point_in_screen));
|
| return;
|
| }
|
| @@ -1476,39 +1504,9 @@ void TabDragController::DetachIntoNewBrowserAndRunMoveLoop(
|
| #endif
|
| dragged_widget->SetVisibilityChangedAnimationsEnabled(false);
|
| Attach(dragged_browser_view->tabstrip(), gfx::Point());
|
| - attached_tabstrip_->InvalidateLayout();
|
| - dragged_widget->non_client_view()->Layout();
|
| - const int dragged_tabstrip_width = attached_tabstrip_->tab_area_width();
|
| -
|
| - // If the new tabstrip is smaller than the old resize the tabs.
|
| - if (dragged_tabstrip_width < last_tabstrip_width) {
|
| - const float leading_ratio =
|
| - drag_bounds.front().x() / static_cast<float>(last_tabstrip_width);
|
| - drag_bounds = CalculateBoundsForDraggedTabs();
|
| -
|
| - if (drag_bounds.back().right() < dragged_tabstrip_width) {
|
| - const int delta_x =
|
| - std::min(static_cast<int>(leading_ratio * dragged_tabstrip_width),
|
| - dragged_tabstrip_width -
|
| - (drag_bounds.back().right() -
|
| - drag_bounds.front().x()));
|
| - OffsetX(delta_x, &drag_bounds);
|
| - }
|
| -
|
| - // Reposition the restored window such that the tab that was dragged remains
|
| - // under the mouse cursor.
|
| - gfx::Point offset(
|
| - static_cast<int>(drag_bounds[source_tab_index_].width() *
|
| - offset_to_width_ratio_) +
|
| - drag_bounds[source_tab_index_].x(), 0);
|
| - views::View::ConvertPointToWidget(attached_tabstrip_, &offset);
|
| - gfx::Rect new_bounds = browser->window()->GetBounds();
|
| - new_bounds.set_x(point_in_screen.x() - offset.x());
|
| - browser->window()->SetBounds(new_bounds);
|
| - }
|
| -
|
| - attached_tabstrip_->SetTabBoundsForDrag(drag_bounds);
|
| -
|
| + AdjustBrowserAndTabBoundsForDrag(last_tabstrip_width,
|
| + point_in_screen,
|
| + &drag_bounds);
|
| WindowPositionManagedUpdater updater;
|
| dragged_widget->AddObserver(&updater);
|
| browser->window()->Show();
|
| @@ -1935,14 +1933,14 @@ void TabDragController::CompleteDrag() {
|
|
|
| if (attached_tabstrip_) {
|
| if (is_dragging_new_browser_) {
|
| - if (IsDocked(attached_tabstrip_)) {
|
| + if (IsDockedOrSnapped(attached_tabstrip_)) {
|
| DCHECK_EQ(host_desktop_type_, chrome::HOST_DESKTOP_TYPE_ASH);
|
| was_source_maximized_ = false;
|
| was_source_fullscreen_ = false;
|
| }
|
| // If source window was maximized - maximize the new window as well.
|
| - if (was_source_maximized_)
|
| - attached_tabstrip_->GetWidget()->Maximize();
|
| + if (was_source_maximized_ || was_source_fullscreen_)
|
| + GetAttachedBrowserWidget()->Maximize();
|
| #if defined(USE_ASH)
|
| if (was_source_fullscreen_ &&
|
| host_desktop_type_ == chrome::HOST_DESKTOP_TYPE_ASH) {
|
| @@ -1951,14 +1949,6 @@ void TabDragController::CompleteDrag() {
|
| ash::accelerators::ToggleFullscreen();
|
| }
|
| #endif
|
| - } else {
|
| - // When dragging results in maximized or fullscreen browser window getting
|
| - // docked, restore it.
|
| - if ((was_source_fullscreen_ || was_source_maximized_) &&
|
| - (IsDocked(attached_tabstrip_))) {
|
| - DCHECK_EQ(host_desktop_type_, chrome::HOST_DESKTOP_TYPE_ASH);
|
| - attached_tabstrip_->GetWidget()->Restore();
|
| - }
|
| }
|
| attached_tabstrip_->StoppedDraggingTabs(
|
| GetTabsMatchingDraggedContents(attached_tabstrip_),
|
| @@ -2248,10 +2238,9 @@ bool TabDragController::AreTabsConsecutive() {
|
| return true;
|
| }
|
|
|
| -Browser* TabDragController::CreateBrowserForDrag(
|
| +gfx::Rect TabDragController::CalculateDraggedBrowserBounds(
|
| TabStrip* source,
|
| const gfx::Point& point_in_screen,
|
| - gfx::Vector2d* drag_offset,
|
| std::vector<gfx::Rect>* drag_bounds) {
|
| gfx::Point center(0, source->height() / 2);
|
| views::View::ConvertPointToWidget(source, ¢er);
|
| @@ -2265,7 +2254,7 @@ Browser* TabDragController::CreateBrowserForDrag(
|
| new_bounds.set_width(
|
| std::max(max_size.width() / 2, new_bounds.width()));
|
| new_bounds.set_height(
|
| - std::max(max_size.height() / 2, new_bounds.width()));
|
| + std::max(max_size.height() / 2, new_bounds.height()));
|
| }
|
| new_bounds.set_y(point_in_screen.y() - center.y());
|
| switch (GetDetachPosition(point_in_screen)) {
|
| @@ -2290,7 +2279,54 @@ Browser* TabDragController::CreateBrowserForDrag(
|
| // strip.
|
| if (source->GetWidget()->IsMaximized())
|
| new_bounds.Offset(0, -source->button_v_offset());
|
| + return new_bounds;
|
| +}
|
| +
|
| +void TabDragController::AdjustBrowserAndTabBoundsForDrag(
|
| + int last_tabstrip_width,
|
| + const gfx::Point& point_in_screen,
|
| + std::vector<gfx::Rect>* drag_bounds) {
|
| + attached_tabstrip_->InvalidateLayout();
|
| + attached_tabstrip_->DoLayout();
|
| + const int dragged_tabstrip_width = attached_tabstrip_->tab_area_width();
|
| +
|
| + // If the new tabstrip is smaller than the old resize the tabs.
|
| + if (dragged_tabstrip_width < last_tabstrip_width) {
|
| + const float leading_ratio =
|
| + drag_bounds->front().x() / static_cast<float>(last_tabstrip_width);
|
| + *drag_bounds = CalculateBoundsForDraggedTabs();
|
| +
|
| + if (drag_bounds->back().right() < dragged_tabstrip_width) {
|
| + const int delta_x =
|
| + std::min(static_cast<int>(leading_ratio * dragged_tabstrip_width),
|
| + dragged_tabstrip_width -
|
| + (drag_bounds->back().right() -
|
| + drag_bounds->front().x()));
|
| + OffsetX(delta_x, drag_bounds);
|
| + }
|
| +
|
| + // Reposition the restored window such that the tab that was dragged remains
|
| + // under the mouse cursor.
|
| + gfx::Point offset(
|
| + static_cast<int>((*drag_bounds)[source_tab_index_].width() *
|
| + offset_to_width_ratio_) +
|
| + (*drag_bounds)[source_tab_index_].x(), 0);
|
| + views::View::ConvertPointToWidget(attached_tabstrip_, &offset);
|
| + gfx::Rect bounds = GetAttachedBrowserWidget()->GetWindowBoundsInScreen();
|
| + bounds.set_x(point_in_screen.x() - offset.x());
|
| + GetAttachedBrowserWidget()->SetBounds(bounds);
|
| + }
|
| + attached_tabstrip_->SetTabBoundsForDrag(*drag_bounds);
|
| +}
|
|
|
| +Browser* TabDragController::CreateBrowserForDrag(
|
| + TabStrip* source,
|
| + const gfx::Point& point_in_screen,
|
| + gfx::Vector2d* drag_offset,
|
| + std::vector<gfx::Rect>* drag_bounds) {
|
| + gfx::Rect new_bounds(CalculateDraggedBrowserBounds(source,
|
| + point_in_screen,
|
| + drag_bounds));
|
| *drag_offset = point_in_screen - new_bounds.origin();
|
|
|
| Profile* profile =
|
|
|