| 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 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 #if defined(USE_ASH) | 88 #if defined(USE_ASH) |
| 89 void SetWindowPositionManaged(gfx::NativeWindow window, bool value) { | |
| 90 ash::wm::GetWindowState(window)->set_window_position_managed(value); | |
| 91 } | |
| 92 | |
| 93 // Returns true if |tab_strip| browser window is docked. | 89 // Returns true if |tab_strip| browser window is docked. |
| 94 bool IsDockedOrSnapped(const TabStrip* tab_strip) { | 90 bool IsDockedOrSnapped(const TabStrip* tab_strip) { |
| 95 DCHECK(tab_strip); | 91 DCHECK(tab_strip); |
| 96 ash::wm::WindowState* window_state = | 92 ash::wm::WindowState* window_state = |
| 97 ash::wm::GetWindowState(tab_strip->GetWidget()->GetNativeWindow()); | 93 ash::wm::GetWindowState(tab_strip->GetWidget()->GetNativeWindow()); |
| 98 return window_state->IsDocked() || window_state->IsSnapped(); | 94 return window_state->IsDocked() || window_state->IsSnapped(); |
| 99 } | 95 } |
| 100 #else | 96 #else |
| 101 void SetWindowPositionManaged(gfx::NativeWindow window, bool value) { | |
| 102 } | |
| 103 | |
| 104 bool IsDockedOrSnapped(const TabStrip* tab_strip) { | 97 bool IsDockedOrSnapped(const TabStrip* tab_strip) { |
| 105 return false; | 98 return false; |
| 106 } | 99 } |
| 107 #endif | 100 #endif |
| 108 | 101 |
| 109 #if defined(USE_AURA) | 102 #if defined(USE_AURA) |
| 110 gfx::NativeWindow GetModalTransient(gfx::NativeWindow window) { | 103 gfx::NativeWindow GetModalTransient(gfx::NativeWindow window) { |
| 111 return wm::GetModalTransient(window); | 104 return wm::GetModalTransient(window); |
| 112 } | 105 } |
| 113 #else | 106 #else |
| (...skipping 16 matching lines...) Expand all Loading... |
| 130 | 123 |
| 131 // Adds |x_offset| to all the rectangles in |rects|. | 124 // Adds |x_offset| to all the rectangles in |rects|. |
| 132 void OffsetX(int x_offset, std::vector<gfx::Rect>* rects) { | 125 void OffsetX(int x_offset, std::vector<gfx::Rect>* rects) { |
| 133 if (x_offset == 0) | 126 if (x_offset == 0) |
| 134 return; | 127 return; |
| 135 | 128 |
| 136 for (size_t i = 0; i < rects->size(); ++i) | 129 for (size_t i = 0; i < rects->size(); ++i) |
| 137 (*rects)[i].set_x((*rects)[i].x() + x_offset); | 130 (*rects)[i].set_x((*rects)[i].x() + x_offset); |
| 138 } | 131 } |
| 139 | 132 |
| 140 // WidgetObserver implementation that resets the window position managed | |
| 141 // property on Show. | |
| 142 // We're forced to do this here since BrowserFrameAsh resets the 'window | |
| 143 // position managed' property during a show and we need the property set to | |
| 144 // false before WorkspaceLayoutManager sees the visibility change. | |
| 145 class WindowPositionManagedUpdater : public views::WidgetObserver { | |
| 146 public: | |
| 147 void OnWidgetVisibilityChanged(views::Widget* widget, bool visible) override { | |
| 148 SetWindowPositionManaged(widget->GetNativeWindow(), false); | |
| 149 } | |
| 150 }; | |
| 151 | |
| 152 // EscapeTracker installs an event monitor and runs a callback when it receives | 133 // EscapeTracker installs an event monitor and runs a callback when it receives |
| 153 // the escape key. | 134 // the escape key. |
| 154 class EscapeTracker : public ui::EventHandler { | 135 class EscapeTracker : public ui::EventHandler { |
| 155 public: | 136 public: |
| 156 explicit EscapeTracker(const base::Closure& callback) | 137 explicit EscapeTracker(const base::Closure& callback) |
| 157 : escape_callback_(callback), | 138 : escape_callback_(callback), |
| 158 event_monitor_(views::EventMonitor::CreateApplicationMonitor(this)) { | 139 event_monitor_(views::EventMonitor::CreateApplicationMonitor(this)) { |
| 159 } | 140 } |
| 160 | 141 |
| 161 private: | 142 private: |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 229 | 210 |
| 230 TabDragController::~TabDragController() { | 211 TabDragController::~TabDragController() { |
| 231 views::ViewStorage::GetInstance()->RemoveView(old_focused_view_id_); | 212 views::ViewStorage::GetInstance()->RemoveView(old_focused_view_id_); |
| 232 | 213 |
| 233 if (instance_ == this) | 214 if (instance_ == this) |
| 234 instance_ = NULL; | 215 instance_ = NULL; |
| 235 | 216 |
| 236 if (move_loop_widget_) { | 217 if (move_loop_widget_) { |
| 237 if (added_observer_to_move_loop_widget_) | 218 if (added_observer_to_move_loop_widget_) |
| 238 move_loop_widget_->RemoveObserver(this); | 219 move_loop_widget_->RemoveObserver(this); |
| 239 SetWindowPositionManaged(move_loop_widget_->GetNativeWindow(), true); | |
| 240 } | 220 } |
| 241 | 221 |
| 242 if (source_tabstrip_) | 222 if (source_tabstrip_) |
| 243 GetModel(source_tabstrip_)->RemoveObserver(this); | 223 GetModel(source_tabstrip_)->RemoveObserver(this); |
| 244 | 224 |
| 245 if (event_source_ == EVENT_SOURCE_TOUCH) { | 225 if (event_source_ == EVENT_SOURCE_TOUCH) { |
| 246 TabStrip* capture_tabstrip = attached_tabstrip_ ? | 226 TabStrip* capture_tabstrip = attached_tabstrip_ ? |
| 247 attached_tabstrip_ : source_tabstrip_; | 227 attached_tabstrip_ : source_tabstrip_; |
| 248 capture_tabstrip->GetWidget()->ReleaseCapture(); | 228 capture_tabstrip->GetWidget()->ReleaseCapture(); |
| 249 } | 229 } |
| (...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 609 // going to trigger capture lost, which cancels drag. | 589 // going to trigger capture lost, which cancels drag. |
| 610 attached_tabstrip_->ReleaseDragController(); | 590 attached_tabstrip_->ReleaseDragController(); |
| 611 target_tabstrip->OwnDragController(this); | 591 target_tabstrip->OwnDragController(this); |
| 612 // Disable animations so that we don't see a close animation on aero. | 592 // Disable animations so that we don't see a close animation on aero. |
| 613 browser_widget->SetVisibilityChangedAnimationsEnabled(false); | 593 browser_widget->SetVisibilityChangedAnimationsEnabled(false); |
| 614 if (can_release_capture_) | 594 if (can_release_capture_) |
| 615 browser_widget->ReleaseCapture(); | 595 browser_widget->ReleaseCapture(); |
| 616 else | 596 else |
| 617 target_tabstrip->GetWidget()->SetCapture(attached_tabstrip_); | 597 target_tabstrip->GetWidget()->SetCapture(attached_tabstrip_); |
| 618 | 598 |
| 619 // The window is going away. Since the drag is still on going we don't want | |
| 620 // that to effect the position of any windows. | |
| 621 SetWindowPositionManaged(browser_widget->GetNativeWindow(), false); | |
| 622 | |
| 623 #if !defined(OS_LINUX) || defined(OS_CHROMEOS) | 599 #if !defined(OS_LINUX) || defined(OS_CHROMEOS) |
| 624 // EndMoveLoop is going to snap the window back to its original location. | 600 // EndMoveLoop is going to snap the window back to its original location. |
| 625 // Hide it so users don't see this. Hiding a window in Linux aura causes | 601 // Hide it so users don't see this. Hiding a window in Linux aura causes |
| 626 // it to lose capture so skip it. | 602 // it to lose capture so skip it. |
| 627 browser_widget->Hide(); | 603 browser_widget->Hide(); |
| 628 #endif | 604 #endif |
| 629 browser_widget->EndMoveLoop(); | 605 browser_widget->EndMoveLoop(); |
| 630 | 606 |
| 631 // Ideally we would always swap the tabs now, but on non-ash Windows, it | 607 // Ideally we would always swap the tabs now, but on non-ash Windows, it |
| 632 // seems that running the move loop implicitly activates the window when | 608 // seems that running the move loop implicitly activates the window when |
| (...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1052 ui::GestureRecognizer::ShouldCancelTouches::DontCancel); | 1028 ui::GestureRecognizer::ShouldCancelTouches::DontCancel); |
| 1053 #endif | 1029 #endif |
| 1054 | 1030 |
| 1055 Detach(can_release_capture_ ? RELEASE_CAPTURE : DONT_RELEASE_CAPTURE); | 1031 Detach(can_release_capture_ ? RELEASE_CAPTURE : DONT_RELEASE_CAPTURE); |
| 1056 | 1032 |
| 1057 dragged_widget->SetVisibilityChangedAnimationsEnabled(false); | 1033 dragged_widget->SetVisibilityChangedAnimationsEnabled(false); |
| 1058 Attach(dragged_browser_view->tabstrip(), gfx::Point()); | 1034 Attach(dragged_browser_view->tabstrip(), gfx::Point()); |
| 1059 AdjustBrowserAndTabBoundsForDrag(last_tabstrip_width, | 1035 AdjustBrowserAndTabBoundsForDrag(last_tabstrip_width, |
| 1060 point_in_screen, | 1036 point_in_screen, |
| 1061 &drag_bounds); | 1037 &drag_bounds); |
| 1062 WindowPositionManagedUpdater updater; | |
| 1063 dragged_widget->AddObserver(&updater); | |
| 1064 browser->window()->Show(); | 1038 browser->window()->Show(); |
| 1065 dragged_widget->RemoveObserver(&updater); | |
| 1066 dragged_widget->SetVisibilityChangedAnimationsEnabled(true); | 1039 dragged_widget->SetVisibilityChangedAnimationsEnabled(true); |
| 1067 // Activate may trigger a focus loss, destroying us. | 1040 // Activate may trigger a focus loss, destroying us. |
| 1068 { | 1041 { |
| 1069 base::WeakPtr<TabDragController> ref(weak_factory_.GetWeakPtr()); | 1042 base::WeakPtr<TabDragController> ref(weak_factory_.GetWeakPtr()); |
| 1070 browser->window()->Activate(); | 1043 browser->window()->Activate(); |
| 1071 if (!ref) | 1044 if (!ref) |
| 1072 return; | 1045 return; |
| 1073 } | 1046 } |
| 1074 RunMoveLoop(drag_offset); | 1047 RunMoveLoop(drag_offset); |
| 1075 } | 1048 } |
| (...skipping 30 matching lines...) Expand all Loading... |
| 1106 drag_offset, move_loop_source, escape_behavior); | 1079 drag_offset, move_loop_source, escape_behavior); |
| 1107 content::NotificationService::current()->Notify( | 1080 content::NotificationService::current()->Notify( |
| 1108 chrome::NOTIFICATION_TAB_DRAG_LOOP_DONE, | 1081 chrome::NOTIFICATION_TAB_DRAG_LOOP_DONE, |
| 1109 content::NotificationService::AllBrowserContextsAndSources(), | 1082 content::NotificationService::AllBrowserContextsAndSources(), |
| 1110 content::NotificationService::NoDetails()); | 1083 content::NotificationService::NoDetails()); |
| 1111 | 1084 |
| 1112 if (!ref) | 1085 if (!ref) |
| 1113 return; | 1086 return; |
| 1114 if (move_loop_widget_) { | 1087 if (move_loop_widget_) { |
| 1115 move_loop_widget_->RemoveObserver(this); | 1088 move_loop_widget_->RemoveObserver(this); |
| 1116 move_loop_widget_ = NULL; | 1089 move_loop_widget_ = nullptr; |
| 1117 } | 1090 } |
| 1118 is_dragging_window_ = false; | 1091 is_dragging_window_ = false; |
| 1119 waiting_for_run_loop_to_exit_ = false; | 1092 waiting_for_run_loop_to_exit_ = false; |
| 1120 if (end_run_loop_behavior_ == END_RUN_LOOP_CONTINUE_DRAGGING) { | 1093 if (end_run_loop_behavior_ == END_RUN_LOOP_CONTINUE_DRAGGING) { |
| 1121 end_run_loop_behavior_ = END_RUN_LOOP_STOP_DRAGGING; | 1094 end_run_loop_behavior_ = END_RUN_LOOP_STOP_DRAGGING; |
| 1122 if (tab_strip_to_attach_to_after_exit_) { | 1095 if (tab_strip_to_attach_to_after_exit_) { |
| 1123 gfx::Point point_in_screen(GetCursorScreenPoint()); | 1096 gfx::Point point_in_screen(GetCursorScreenPoint()); |
| 1124 Detach(DONT_RELEASE_CAPTURE); | 1097 Detach(DONT_RELEASE_CAPTURE); |
| 1125 Attach(tab_strip_to_attach_to_after_exit_, point_in_screen); | 1098 Attach(tab_strip_to_attach_to_after_exit_, point_in_screen); |
| 1126 // Move the tabs into position. | 1099 // Move the tabs into position. |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1346 void TabDragController::EndDragImpl(EndDragType type) { | 1319 void TabDragController::EndDragImpl(EndDragType type) { |
| 1347 DCHECK(active_); | 1320 DCHECK(active_); |
| 1348 active_ = false; | 1321 active_ = false; |
| 1349 | 1322 |
| 1350 bring_to_front_timer_.Stop(); | 1323 bring_to_front_timer_.Stop(); |
| 1351 move_stacked_timer_.Stop(); | 1324 move_stacked_timer_.Stop(); |
| 1352 | 1325 |
| 1353 if (is_dragging_window_) { | 1326 if (is_dragging_window_) { |
| 1354 waiting_for_run_loop_to_exit_ = true; | 1327 waiting_for_run_loop_to_exit_ = true; |
| 1355 | 1328 |
| 1356 if (type == NORMAL || (type == TAB_DESTROYED && drag_data_.size() > 1)) { | |
| 1357 SetWindowPositionManaged(GetAttachedBrowserWidget()->GetNativeWindow(), | |
| 1358 true); | |
| 1359 } | |
| 1360 | |
| 1361 // End the nested drag loop. | 1329 // End the nested drag loop. |
| 1362 GetAttachedBrowserWidget()->EndMoveLoop(); | 1330 GetAttachedBrowserWidget()->EndMoveLoop(); |
| 1363 } | 1331 } |
| 1364 | 1332 |
| 1365 if (type != TAB_DESTROYED) { | 1333 if (type != TAB_DESTROYED) { |
| 1366 // We only finish up the drag if we were actually dragging. If start_drag_ | 1334 // We only finish up the drag if we were actually dragging. If start_drag_ |
| 1367 // is false, the user just clicked and released and didn't move the mouse | 1335 // is false, the user just clicked and released and didn't move the mouse |
| 1368 // enough to trigger a drag. | 1336 // enough to trigger a drag. |
| 1369 if (started_drag_) { | 1337 if (started_drag_) { |
| 1370 RestoreFocus(); | 1338 RestoreFocus(); |
| (...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1761 point_in_screen, | 1729 point_in_screen, |
| 1762 drag_bounds)); | 1730 drag_bounds)); |
| 1763 *drag_offset = point_in_screen - new_bounds.origin(); | 1731 *drag_offset = point_in_screen - new_bounds.origin(); |
| 1764 | 1732 |
| 1765 Profile* profile = | 1733 Profile* profile = |
| 1766 Profile::FromBrowserContext(drag_data_[0].contents->GetBrowserContext()); | 1734 Profile::FromBrowserContext(drag_data_[0].contents->GetBrowserContext()); |
| 1767 Browser::CreateParams create_params(Browser::TYPE_TABBED, profile); | 1735 Browser::CreateParams create_params(Browser::TYPE_TABBED, profile); |
| 1768 create_params.initial_bounds = new_bounds; | 1736 create_params.initial_bounds = new_bounds; |
| 1769 Browser* browser = new Browser(create_params); | 1737 Browser* browser = new Browser(create_params); |
| 1770 is_dragging_new_browser_ = true; | 1738 is_dragging_new_browser_ = true; |
| 1771 SetWindowPositionManaged(browser->window()->GetNativeWindow(), false); | |
| 1772 // If the window is created maximized then the bounds we supplied are ignored. | 1739 // If the window is created maximized then the bounds we supplied are ignored. |
| 1773 // We need to reset them again so they are honored. | 1740 // We need to reset them again so they are honored. |
| 1774 browser->window()->SetBounds(new_bounds); | 1741 browser->window()->SetBounds(new_bounds); |
| 1775 | 1742 |
| 1776 return browser; | 1743 return browser; |
| 1777 } | 1744 } |
| 1778 | 1745 |
| 1779 gfx::Point TabDragController::GetCursorScreenPoint() { | 1746 gfx::Point TabDragController::GetCursorScreenPoint() { |
| 1780 #if defined(USE_ASH) | 1747 #if defined(USE_ASH) |
| 1781 if (event_source_ == EVENT_SOURCE_TOUCH && | 1748 if (event_source_ == EVENT_SOURCE_TOUCH && |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1827 // TODO(pkotwicz): Fix this properly (crbug.com/358482) | 1794 // TODO(pkotwicz): Fix this properly (crbug.com/358482) |
| 1828 for (auto* browser : *BrowserList::GetInstance()) { | 1795 for (auto* browser : *BrowserList::GetInstance()) { |
| 1829 if (browser->tab_strip_model()->empty()) | 1796 if (browser->tab_strip_model()->empty()) |
| 1830 exclude.insert(browser->window()->GetNativeWindow()); | 1797 exclude.insert(browser->window()->GetNativeWindow()); |
| 1831 } | 1798 } |
| 1832 #endif | 1799 #endif |
| 1833 base::WeakPtr<TabDragController> ref(weak_factory_.GetWeakPtr()); | 1800 base::WeakPtr<TabDragController> ref(weak_factory_.GetWeakPtr()); |
| 1834 *window = window_finder_->GetLocalProcessWindowAtPoint(screen_point, exclude); | 1801 *window = window_finder_->GetLocalProcessWindowAtPoint(screen_point, exclude); |
| 1835 return ref ? Liveness::ALIVE : Liveness::DELETED; | 1802 return ref ? Liveness::ALIVE : Liveness::DELETED; |
| 1836 } | 1803 } |
| OLD | NEW |