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 |