Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/ui/views/tabs/tab_drag_controller.h" | 5 #include "chrome/browser/ui/views/tabs/tab_drag_controller.h" |
| 6 | 6 |
| 7 #include <math.h> | 7 #include <math.h> |
| 8 #include <set> | 8 #include <set> |
| 9 | 9 |
| 10 #include "base/auto_reset.h" | 10 #include "base/auto_reset.h" |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 78 // Distance from the next/previous stacked before before we consider the tab | 78 // Distance from the next/previous stacked before before we consider the tab |
| 79 // close enough to trigger moving. | 79 // close enough to trigger moving. |
| 80 const int kStackedDistance = 36; | 80 const int kStackedDistance = 36; |
| 81 | 81 |
| 82 // A dragged window is forced to be a bit smaller than maximized bounds during a | 82 // A dragged window is forced to be a bit smaller than maximized bounds during a |
| 83 // drag. This prevents the dragged browser widget from getting maximized at | 83 // drag. This prevents the dragged browser widget from getting maximized at |
| 84 // creation and makes it easier to drag tabs out of a restored window that had | 84 // creation and makes it easier to drag tabs out of a restored window that had |
| 85 // maximized size. | 85 // maximized size. |
| 86 const int kMaximizedWindowInset = 10; // DIPs. | 86 const int kMaximizedWindowInset = 10; // DIPs. |
| 87 | 87 |
| 88 // Whether a new browser window created during a drag is destroyed immediately | |
| 89 // once it is associated with a new tab strip. If false, windows created during | |
| 90 // the drag are destroyed only when the drag ends. | |
| 91 #if 0 && defined(OS_MACOSX) | |
| 92 const bool windows_destroy_during_drag = false; | |
| 93 #else | |
| 94 const bool windows_destroy_during_drag = true; | |
| 95 #endif | |
| 96 | |
| 88 #if defined(USE_ASH) | 97 #if defined(USE_ASH) |
| 89 void SetWindowPositionManaged(gfx::NativeWindow window, bool value) { | 98 void SetWindowPositionManaged(gfx::NativeWindow window, bool value) { |
| 90 ash::wm::GetWindowState(window)->set_window_position_managed(value); | 99 ash::wm::GetWindowState(window)->set_window_position_managed(value); |
| 91 } | 100 } |
| 92 | 101 |
| 93 // Returns true if |tab_strip| browser window is docked. | 102 // Returns true if |tab_strip| browser window is docked. |
| 94 bool IsDockedOrSnapped(const TabStrip* tab_strip) { | 103 bool IsDockedOrSnapped(const TabStrip* tab_strip) { |
| 95 DCHECK(tab_strip); | 104 DCHECK(tab_strip); |
| 96 ash::wm::WindowState* window_state = | 105 ash::wm::WindowState* window_state = |
| 97 ash::wm::GetWindowState(tab_strip->GetWidget()->GetNativeWindow()); | 106 ash::wm::GetWindowState(tab_strip->GetWidget()->GetNativeWindow()); |
| (...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 374 point_in_screen.x() - | 383 point_in_screen.x() - |
| 375 mouse_offset_.x(), 0); | 384 mouse_offset_.x(), 0); |
| 376 widget->SetVisibilityChangedAnimationsEnabled(false); | 385 widget->SetVisibilityChangedAnimationsEnabled(false); |
| 377 widget->Restore(); | 386 widget->Restore(); |
| 378 widget->SetBounds(new_bounds); | 387 widget->SetBounds(new_bounds); |
| 379 AdjustBrowserAndTabBoundsForDrag(last_tabstrip_width, | 388 AdjustBrowserAndTabBoundsForDrag(last_tabstrip_width, |
| 380 point_in_screen, | 389 point_in_screen, |
| 381 &drag_bounds); | 390 &drag_bounds); |
| 382 widget->SetVisibilityChangedAnimationsEnabled(true); | 391 widget->SetVisibilityChangedAnimationsEnabled(true); |
| 383 } | 392 } |
| 384 RunMoveLoop(GetWindowOffset(point_in_screen)); | 393 RunMoveLoop(GetWindowOffset(start_point_in_screen_)); |
|
themblsha
2016/03/03 17:56:51
Without this fix the first mouse move after pressi
| |
| 385 return; | 394 return; |
| 386 } | 395 } |
| 387 } | 396 } |
| 388 | 397 |
| 389 ContinueDragging(point_in_screen); | 398 ContinueDragging(point_in_screen); |
| 390 } | 399 } |
| 391 | 400 |
| 392 void TabDragController::EndDrag(EndDragReason reason) { | 401 void TabDragController::EndDrag(EndDragReason reason) { |
| 393 TRACE_EVENT0("views", "TabDragController::EndDrag"); | 402 TRACE_EVENT0("views", "TabDragController::EndDrag"); |
| 394 | 403 |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 516 return; | 525 return; |
| 517 old_focused_view->GetFocusManager()->SetFocusedView(old_focused_view); | 526 old_focused_view->GetFocusManager()->SetFocusedView(old_focused_view); |
| 518 } | 527 } |
| 519 | 528 |
| 520 bool TabDragController::CanStartDrag(const gfx::Point& point_in_screen) const { | 529 bool TabDragController::CanStartDrag(const gfx::Point& point_in_screen) const { |
| 521 // Determine if the mouse has moved beyond a minimum elasticity distance in | 530 // Determine if the mouse has moved beyond a minimum elasticity distance in |
| 522 // any direction from the starting point. | 531 // any direction from the starting point. |
| 523 static const int kMinimumDragDistance = 10; | 532 static const int kMinimumDragDistance = 10; |
| 524 int x_offset = abs(point_in_screen.x() - start_point_in_screen_.x()); | 533 int x_offset = abs(point_in_screen.x() - start_point_in_screen_.x()); |
| 525 int y_offset = abs(point_in_screen.y() - start_point_in_screen_.y()); | 534 int y_offset = abs(point_in_screen.y() - start_point_in_screen_.y()); |
| 526 return sqrt(pow(static_cast<float>(x_offset), 2) + | 535 bool result = sqrt(pow(static_cast<float>(x_offset), 2) + |
| 527 pow(static_cast<float>(y_offset), 2)) > kMinimumDragDistance; | 536 pow(static_cast<float>(y_offset), 2)) > kMinimumDragDistance; |
| 537 return result; | |
| 528 } | 538 } |
| 529 | 539 |
| 530 void TabDragController::ContinueDragging(const gfx::Point& point_in_screen) { | 540 void TabDragController::ContinueDragging(const gfx::Point& point_in_screen) { |
| 531 TRACE_EVENT1("views", "TabDragController::ContinueDragging", | 541 TRACE_EVENT1("views", "TabDragController::ContinueDragging", |
| 532 "point_in_screen", point_in_screen.ToString()); | 542 "point_in_screen", point_in_screen.ToString()); |
| 533 | 543 |
| 534 DCHECK(attached_tabstrip_); | 544 DCHECK(attached_tabstrip_); |
| 535 | 545 |
| 536 TabStrip* target_tabstrip = detach_behavior_ == DETACHABLE ? | 546 TabStrip* target_tabstrip = detach_behavior_ == DETACHABLE ? |
| 537 GetTargetTabStripForPoint(point_in_screen) : source_tabstrip_; | 547 GetTargetTabStripForPoint(point_in_screen) : source_tabstrip_; |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 600 // observer so we don't get notified and process the event. | 610 // observer so we don't get notified and process the event. |
| 601 #if defined(USE_ASH) | 611 #if defined(USE_ASH) |
| 602 move_loop_widget_->RemoveObserver(this); | 612 move_loop_widget_->RemoveObserver(this); |
| 603 move_loop_widget_ = nullptr; | 613 move_loop_widget_ = nullptr; |
| 604 #endif // USE_ASH | 614 #endif // USE_ASH |
| 605 views::Widget* browser_widget = GetAttachedBrowserWidget(); | 615 views::Widget* browser_widget = GetAttachedBrowserWidget(); |
| 606 // Need to release the drag controller before starting the move loop as it's | 616 // Need to release the drag controller before starting the move loop as it's |
| 607 // going to trigger capture lost, which cancels drag. | 617 // going to trigger capture lost, which cancels drag. |
| 608 attached_tabstrip_->ReleaseDragController(); | 618 attached_tabstrip_->ReleaseDragController(); |
| 609 target_tabstrip->OwnDragController(this); | 619 target_tabstrip->OwnDragController(this); |
| 620 if (!windows_destroy_during_drag) { | |
| 621 Detach(DONT_RELEASE_CAPTURE); | |
| 622 Attach(target_tabstrip, point_in_screen); | |
| 623 // Move the tabs into position. | |
| 624 // MoveAttached(point_in_screen); // assumes !is_dragging_window_ | |
| 625 return DRAG_BROWSER_RESULT_CONTINUE; | |
| 626 } | |
| 627 | |
| 610 // Disable animations so that we don't see a close animation on aero. | 628 // Disable animations so that we don't see a close animation on aero. |
| 611 browser_widget->SetVisibilityChangedAnimationsEnabled(false); | 629 browser_widget->SetVisibilityChangedAnimationsEnabled(false); |
| 612 if (can_release_capture_) | 630 if (can_release_capture_) |
| 613 browser_widget->ReleaseCapture(); | 631 browser_widget->ReleaseCapture(); |
| 614 else | 632 else |
| 615 target_tabstrip->GetWidget()->SetCapture(attached_tabstrip_); | 633 target_tabstrip->GetWidget()->SetCapture(attached_tabstrip_); |
| 616 | 634 |
| 617 // The window is going away. Since the drag is still on going we don't want | 635 // The window is going away. Since the drag is still on going we don't want |
| 618 // that to effect the position of any windows. | 636 // that to effect the position of any windows. |
| 619 SetWindowPositionManaged(browser_widget->GetNativeWindow(), false); | 637 SetWindowPositionManaged(browser_widget->GetNativeWindow(), false); |
| (...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 882 "point_in_screen", point_in_screen.ToString()); | 900 "point_in_screen", point_in_screen.ToString()); |
| 883 | 901 |
| 884 DCHECK(!attached_tabstrip_); // We should already have detached by the time | 902 DCHECK(!attached_tabstrip_); // We should already have detached by the time |
| 885 // we get here. | 903 // we get here. |
| 886 | 904 |
| 887 attached_tabstrip_ = attached_tabstrip; | 905 attached_tabstrip_ = attached_tabstrip; |
| 888 | 906 |
| 889 std::vector<Tab*> tabs = | 907 std::vector<Tab*> tabs = |
| 890 GetTabsMatchingDraggedContents(attached_tabstrip_); | 908 GetTabsMatchingDraggedContents(attached_tabstrip_); |
| 891 | 909 |
| 910 bool acquire_capture = true; | |
| 911 | |
| 892 if (tabs.empty()) { | 912 if (tabs.empty()) { |
| 893 // Transitioning from detached to attached to a new tabstrip. Add tabs to | 913 // Transitioning from detached to attached to a new tabstrip. Add tabs to |
| 894 // the new model. | 914 // the new model. |
| 895 | 915 |
| 896 selection_model_before_attach_.Copy(attached_tabstrip->GetSelectionModel()); | 916 selection_model_before_attach_.Copy(attached_tabstrip->GetSelectionModel()); |
| 897 | 917 |
| 898 // Inserting counts as a move. We don't want the tabs to jitter when the | 918 // Inserting counts as a move. We don't want the tabs to jitter when the |
| 899 // user moves the tab immediately after attaching it. | 919 // user moves the tab immediately after attaching it. |
| 900 last_move_screen_loc_ = point_in_screen.x(); | 920 last_move_screen_loc_ = point_in_screen.x(); |
| 901 | 921 |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 921 DCHECK_EQ(1u, drag_data_.size()); | 941 DCHECK_EQ(1u, drag_data_.size()); |
| 922 add_types |= TabStripModel::ADD_ACTIVE; | 942 add_types |= TabStripModel::ADD_ACTIVE; |
| 923 } | 943 } |
| 924 if (drag_data_[i].pinned) | 944 if (drag_data_[i].pinned) |
| 925 add_types |= TabStripModel::ADD_PINNED; | 945 add_types |= TabStripModel::ADD_PINNED; |
| 926 GetModel(attached_tabstrip_)->InsertWebContentsAt( | 946 GetModel(attached_tabstrip_)->InsertWebContentsAt( |
| 927 index + i, drag_data_[i].contents, add_types); | 947 index + i, drag_data_[i].contents, add_types); |
| 928 } | 948 } |
| 929 | 949 |
| 930 tabs = GetTabsMatchingDraggedContents(attached_tabstrip_); | 950 tabs = GetTabsMatchingDraggedContents(attached_tabstrip_); |
| 951 | |
| 952 // If the windows are kept, there's no need to re-acquire capture. Instead, | |
| 953 // the TabDragController remains in a MoveLoop. | |
| 954 acquire_capture = windows_destroy_during_drag; | |
| 931 } | 955 } |
| 932 DCHECK_EQ(tabs.size(), drag_data_.size()); | 956 DCHECK_EQ(tabs.size(), drag_data_.size()); |
| 933 for (size_t i = 0; i < drag_data_.size(); ++i) | 957 for (size_t i = 0; i < drag_data_.size(); ++i) |
| 934 drag_data_[i].attached_tab = tabs[i]; | 958 drag_data_[i].attached_tab = tabs[i]; |
| 935 | 959 |
| 936 attached_tabstrip_->StartedDraggingTabs(tabs); | 960 attached_tabstrip_->StartedDraggingTabs(tabs); |
| 937 | 961 |
| 938 ResetSelection(GetModel(attached_tabstrip_)); | 962 ResetSelection(GetModel(attached_tabstrip_)); |
| 939 | 963 |
| 940 // The size of the dragged tab may have changed. Adjust the x offset so that | 964 // The size of the dragged tab may have changed. Adjust the x offset so that |
| 941 // ratio of mouse_offset_ to original width is maintained. | 965 // ratio of mouse_offset_ to original width is maintained. |
| 942 std::vector<Tab*> tabs_to_source(tabs); | 966 std::vector<Tab*> tabs_to_source(tabs); |
| 943 tabs_to_source.erase(tabs_to_source.begin() + source_tab_index_ + 1, | 967 tabs_to_source.erase(tabs_to_source.begin() + source_tab_index_ + 1, |
| 944 tabs_to_source.end()); | 968 tabs_to_source.end()); |
| 945 int new_x = attached_tabstrip_->GetSizeNeededForTabs(tabs_to_source) - | 969 int new_x = attached_tabstrip_->GetSizeNeededForTabs(tabs_to_source) - |
| 946 tabs[source_tab_index_]->width() + | 970 tabs[source_tab_index_]->width() + |
| 947 static_cast<int>(offset_to_width_ratio_ * | 971 static_cast<int>(offset_to_width_ratio_ * |
| 948 tabs[source_tab_index_]->width()); | 972 tabs[source_tab_index_]->width()); |
| 949 mouse_offset_.set_x(new_x); | 973 mouse_offset_.set_x(new_x); |
| 950 | 974 |
| 951 // Transfer ownership of us to the new tabstrip as well as making sure the | 975 // Transfer ownership of us to the new tabstrip as well as making sure the |
| 952 // window has capture. This is important so that if activation changes the | 976 // window has capture. This is important so that if activation changes the |
| 953 // drag isn't prematurely canceled. | 977 // drag isn't prematurely canceled. |
| 954 attached_tabstrip_->GetWidget()->SetCapture(attached_tabstrip_); | 978 if (acquire_capture) |
| 979 attached_tabstrip_->GetWidget()->SetCapture(attached_tabstrip_); | |
| 955 attached_tabstrip_->OwnDragController(this); | 980 attached_tabstrip_->OwnDragController(this); |
| 956 } | 981 } |
| 957 | 982 |
| 958 void TabDragController::Detach(ReleaseCapture release_capture) { | 983 void TabDragController::Detach(ReleaseCapture release_capture) { |
| 959 TRACE_EVENT1("views", "TabDragController::Detach", | 984 TRACE_EVENT1("views", "TabDragController::Detach", |
| 960 "release_capture", release_capture); | 985 "release_capture", release_capture); |
| 961 | 986 |
| 962 attach_index_ = -1; | 987 attach_index_ = -1; |
| 963 | 988 |
| 964 // When the user detaches we assume they want to reorder. | 989 // When the user detaches we assume they want to reorder. |
| (...skipping 832 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1797 // window which was used for dragging is not hidden once all of its tabs are | 1822 // window which was used for dragging is not hidden once all of its tabs are |
| 1798 // attached to another browser window in DragBrowserToNewTabStrip(). | 1823 // attached to another browser window in DragBrowserToNewTabStrip(). |
| 1799 // TODO(pkotwicz): Fix this properly (crbug.com/358482) | 1824 // TODO(pkotwicz): Fix this properly (crbug.com/358482) |
| 1800 for (auto* browser : *BrowserList::GetInstance()) { | 1825 for (auto* browser : *BrowserList::GetInstance()) { |
| 1801 if (browser->tab_strip_model()->empty()) | 1826 if (browser->tab_strip_model()->empty()) |
| 1802 exclude.insert(browser->window()->GetNativeWindow()); | 1827 exclude.insert(browser->window()->GetNativeWindow()); |
| 1803 } | 1828 } |
| 1804 #endif | 1829 #endif |
| 1805 return GetLocalProcessWindowAtPoint(screen_point, exclude); | 1830 return GetLocalProcessWindowAtPoint(screen_point, exclude); |
| 1806 } | 1831 } |
| OLD | NEW |