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