| 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_controller2.h" | 5 #include "chrome/browser/ui/views/tabs/tab_drag_controller2.h" |
| 6 | 6 |
| 7 #include <math.h> | 7 #include <math.h> |
| 8 #include <set> | 8 #include <set> |
| 9 | 9 |
| 10 #include "base/callback.h" | 10 #include "base/callback.h" |
| (...skipping 20 matching lines...) Expand all Loading... |
| 31 #include "third_party/skia/include/core/SkBitmap.h" | 31 #include "third_party/skia/include/core/SkBitmap.h" |
| 32 #include "ui/base/animation/animation.h" | 32 #include "ui/base/animation/animation.h" |
| 33 #include "ui/base/animation/animation_delegate.h" | 33 #include "ui/base/animation/animation_delegate.h" |
| 34 #include "ui/base/animation/slide_animation.h" | 34 #include "ui/base/animation/slide_animation.h" |
| 35 #include "ui/base/events.h" | 35 #include "ui/base/events.h" |
| 36 #include "ui/base/resource/resource_bundle.h" | 36 #include "ui/base/resource/resource_bundle.h" |
| 37 #include "ui/gfx/canvas.h" | 37 #include "ui/gfx/canvas.h" |
| 38 #include "ui/gfx/screen.h" | 38 #include "ui/gfx/screen.h" |
| 39 #include "ui/views/events/event.h" | 39 #include "ui/views/events/event.h" |
| 40 #include "ui/views/widget/root_view.h" | 40 #include "ui/views/widget/root_view.h" |
| 41 #include "ui/views/widget/widget.h" | |
| 42 | 41 |
| 43 #if defined(USE_ASH) | 42 #if defined(USE_ASH) |
| 44 #include "ash/wm/property_util.h" | 43 #include "ash/wm/property_util.h" |
| 45 #endif | 44 #endif |
| 46 | 45 |
| 47 using content::UserMetricsAction; | 46 using content::UserMetricsAction; |
| 48 using content::WebContents; | 47 using content::WebContents; |
| 49 | 48 |
| 50 static const int kHorizontalMoveThreshold = 16; // Pixels. | 49 static const int kHorizontalMoveThreshold = 16; // Pixels. |
| 51 | 50 |
| (...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 307 offset_to_width_ratio_(0), | 306 offset_to_width_ratio_(0), |
| 308 old_focused_view_(NULL), | 307 old_focused_view_(NULL), |
| 309 last_move_screen_loc_(0), | 308 last_move_screen_loc_(0), |
| 310 started_drag_(false), | 309 started_drag_(false), |
| 311 active_(true), | 310 active_(true), |
| 312 source_tab_index_(std::numeric_limits<size_t>::max()), | 311 source_tab_index_(std::numeric_limits<size_t>::max()), |
| 313 initial_move_(true), | 312 initial_move_(true), |
| 314 end_run_loop_behavior_(END_RUN_LOOP_STOP_DRAGGING), | 313 end_run_loop_behavior_(END_RUN_LOOP_STOP_DRAGGING), |
| 315 waiting_for_run_loop_to_exit_(false), | 314 waiting_for_run_loop_to_exit_(false), |
| 316 tab_strip_to_attach_to_after_exit_(NULL), | 315 tab_strip_to_attach_to_after_exit_(NULL), |
| 317 move_loop_browser_view_(NULL), | 316 move_loop_widget_(NULL), |
| 318 destroyed_(NULL) { | 317 destroyed_(NULL) { |
| 319 instance_ = this; | 318 instance_ = this; |
| 320 } | 319 } |
| 321 | 320 |
| 322 TabDragController2::~TabDragController2() { | 321 TabDragController2::~TabDragController2() { |
| 323 if (instance_ == this) | 322 if (instance_ == this) |
| 324 instance_ = NULL; | 323 instance_ = NULL; |
| 325 | 324 |
| 326 if (destroyed_) | 325 if (destroyed_) |
| 327 *destroyed_ = true; | 326 *destroyed_ = true; |
| 328 | 327 |
| 329 if (move_loop_browser_view_) { | 328 if (move_loop_widget_) { |
| 330 move_loop_browser_view_->set_move_observer(NULL); | 329 move_loop_widget_->RemoveObserver(this); |
| 331 SetTrackedByWorkspace( | 330 SetTrackedByWorkspace(move_loop_widget_->GetNativeView(), true); |
| 332 move_loop_browser_view_->GetWidget()->GetNativeView(), true); | |
| 333 } | 331 } |
| 334 | 332 |
| 335 if (source_tabstrip_) | 333 if (source_tabstrip_) |
| 336 GetModel(source_tabstrip_)->RemoveObserver(this); | 334 GetModel(source_tabstrip_)->RemoveObserver(this); |
| 337 | 335 |
| 338 MessageLoopForUI::current()->RemoveObserver(this); | 336 MessageLoopForUI::current()->RemoveObserver(this); |
| 339 } | 337 } |
| 340 | 338 |
| 341 void TabDragController2::Init( | 339 void TabDragController2::Init( |
| 342 TabStrip* source_tabstrip, | 340 TabStrip* source_tabstrip, |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 460 // to the way they were. This is the most reliable way to do this since no | 458 // to the way they were. This is the most reliable way to do this since no |
| 461 // single view or window reliably receives events throughout all the various | 459 // single view or window reliably receives events throughout all the various |
| 462 // kinds of tab dragging. | 460 // kinds of tab dragging. |
| 463 if (ui::EventTypeFromNative(event) == ui::ET_KEY_PRESSED && | 461 if (ui::EventTypeFromNative(event) == ui::ET_KEY_PRESSED && |
| 464 ui::KeyboardCodeFromNative(event) == ui::VKEY_ESCAPE) { | 462 ui::KeyboardCodeFromNative(event) == ui::VKEY_ESCAPE) { |
| 465 EndDrag(true); | 463 EndDrag(true); |
| 466 } | 464 } |
| 467 } | 465 } |
| 468 #endif | 466 #endif |
| 469 | 467 |
| 470 void TabDragController2::OnWidgetMoved() { | 468 void TabDragController2::OnWidgetMoved(views::Widget* widget) { |
| 471 Drag(); | 469 Drag(); |
| 472 } | 470 } |
| 473 | 471 |
| 474 void TabDragController2::TabStripEmpty() { | 472 void TabDragController2::TabStripEmpty() { |
| 475 GetModel(source_tabstrip_)->RemoveObserver(this); | 473 GetModel(source_tabstrip_)->RemoveObserver(this); |
| 476 // NULL out source_tabstrip_ so that we don't attempt to add back to in (in | 474 // NULL out source_tabstrip_ so that we don't attempt to add back to in (in |
| 477 // the case of a revert). | 475 // the case of a revert). |
| 478 source_tabstrip_ = NULL; | 476 source_tabstrip_ = NULL; |
| 479 } | 477 } |
| 480 | 478 |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 596 if (tab_strip_changed) { | 594 if (tab_strip_changed) { |
| 597 if (!target_tabstrip) { | 595 if (!target_tabstrip) { |
| 598 DetachIntoNewBrowserAndRunMoveLoop(screen_point); | 596 DetachIntoNewBrowserAndRunMoveLoop(screen_point); |
| 599 return; | 597 return; |
| 600 } | 598 } |
| 601 if (is_dragging_window_) { | 599 if (is_dragging_window_) { |
| 602 #if defined(USE_ASH) | 600 #if defined(USE_ASH) |
| 603 // ReleaseMouseCapture() is going to result in calling back to us (because | 601 // ReleaseMouseCapture() is going to result in calling back to us (because |
| 604 // it results in a move). That'll cause all sorts of problems. Reset the | 602 // it results in a move). That'll cause all sorts of problems. Reset the |
| 605 // observer so we don't get notified and process the event. | 603 // observer so we don't get notified and process the event. |
| 606 move_loop_browser_view_->set_move_observer(NULL); | 604 move_loop_widget_->RemoveObserver(this); |
| 607 move_loop_browser_view_ = NULL; | 605 move_loop_widget_ = NULL; |
| 608 #endif | 606 #endif |
| 609 BrowserView* browser_view = GetAttachedBrowserView(); | 607 views::Widget* browser_widget = GetAttachedBrowserWidget(); |
| 610 // Need to release the drag controller before starting the move loop as | 608 // Need to release the drag controller before starting the move loop as |
| 611 // it's going to trigger capture lost, which cancels drag. | 609 // it's going to trigger capture lost, which cancels drag. |
| 612 attached_tabstrip_->ReleaseDragController(); | 610 attached_tabstrip_->ReleaseDragController(); |
| 613 target_tabstrip->OwnDragController(this); | 611 target_tabstrip->OwnDragController(this); |
| 614 // 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. |
| 615 browser_view->GetWidget()->SetVisibilityChangedAnimationsEnabled(false); | 613 browser_widget->SetVisibilityChangedAnimationsEnabled(false); |
| 616 browser_view->GetWidget()->ReleaseMouseCapture(); | 614 browser_widget->ReleaseMouseCapture(); |
| 617 // EndMoveLoop is going to snap the window back to its original location. | 615 // EndMoveLoop is going to snap the window back to its original location. |
| 618 // Hide it so users don't see this. | 616 // Hide it so users don't see this. |
| 619 browser_view->GetWidget()->Hide(); | 617 browser_widget->Hide(); |
| 620 browser_view->GetWidget()->EndMoveLoop(); | 618 browser_widget->EndMoveLoop(); |
| 621 | 619 |
| 622 // Ideally we would always swap the tabs now, but on windows it seems that | 620 // Ideally we would always swap the tabs now, but on windows it seems that |
| 623 // running the move loop implicitly activates the window when done, | 621 // running the move loop implicitly activates the window when done, |
| 624 // leading to all sorts of flicker. So, on windows, instead we process | 622 // leading to all sorts of flicker. So, on windows, instead we process |
| 625 // the move after the loop completes. But on chromeos, we can do tab | 623 // the move after the loop completes. But on chromeos, we can do tab |
| 626 // swapping now to avoid the tab flashing issue(crbug.com/116329). | 624 // swapping now to avoid the tab flashing issue(crbug.com/116329). |
| 627 #if defined(USE_ASH) | 625 #if defined(USE_ASH) |
| 628 is_dragging_window_ = false; | 626 is_dragging_window_ = false; |
| 629 Detach(); | 627 Detach(); |
| 630 gfx::Point screen_point(GetCursorScreenPoint()); | 628 gfx::Point screen_point(GetCursorScreenPoint()); |
| (...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 975 drag_bounds); | 973 drag_bounds); |
| 976 | 974 |
| 977 browser->window()->Show(); | 975 browser->window()->Show(); |
| 978 browser->window()->Activate(); | 976 browser->window()->Activate(); |
| 979 dragged_browser_view->GetWidget()->SetVisibilityChangedAnimationsEnabled( | 977 dragged_browser_view->GetWidget()->SetVisibilityChangedAnimationsEnabled( |
| 980 true); | 978 true); |
| 981 RunMoveLoop(); | 979 RunMoveLoop(); |
| 982 } | 980 } |
| 983 | 981 |
| 984 void TabDragController2::RunMoveLoop() { | 982 void TabDragController2::RunMoveLoop() { |
| 985 move_loop_browser_view_ = GetAttachedBrowserView(); | 983 move_loop_widget_ = GetAttachedBrowserWidget(); |
| 986 DCHECK(move_loop_browser_view_); | 984 move_loop_widget_->AddObserver(this); |
| 987 move_loop_browser_view_->set_move_observer(this); | |
| 988 is_dragging_window_ = true; | 985 is_dragging_window_ = true; |
| 989 bool destroyed = false; | 986 bool destroyed = false; |
| 990 destroyed_ = &destroyed; | 987 destroyed_ = &destroyed; |
| 991 // Running the move loop release mouse capture on windows, which triggers | 988 // Running the move loop release mouse capture on windows, which triggers |
| 992 // destroying the drag loop. Release mouse capture ourself before this while | 989 // destroying the drag loop. Release mouse capture ourself before this while |
| 993 // the Dragcontroller isn't owned by the TabStrip. | 990 // the Dragcontroller isn't owned by the TabStrip. |
| 994 attached_tabstrip_->ReleaseDragController(); | 991 attached_tabstrip_->ReleaseDragController(); |
| 995 attached_tabstrip_->GetWidget()->ReleaseMouseCapture(); | 992 attached_tabstrip_->GetWidget()->ReleaseMouseCapture(); |
| 996 attached_tabstrip_->OwnDragController(this); | 993 attached_tabstrip_->OwnDragController(this); |
| 997 views::Widget::MoveLoopResult result = | 994 views::Widget::MoveLoopResult result = move_loop_widget_->RunMoveLoop(); |
| 998 move_loop_browser_view_->GetWidget()->RunMoveLoop(); | |
| 999 content::NotificationService::current()->Notify( | 995 content::NotificationService::current()->Notify( |
| 1000 chrome::NOTIFICATION_TAB_DRAG_LOOP_DONE, | 996 chrome::NOTIFICATION_TAB_DRAG_LOOP_DONE, |
| 1001 content::NotificationService::AllBrowserContextsAndSources(), | 997 content::NotificationService::AllBrowserContextsAndSources(), |
| 1002 content::NotificationService::NoDetails()); | 998 content::NotificationService::NoDetails()); |
| 1003 | 999 |
| 1004 if (destroyed) | 1000 if (destroyed) |
| 1005 return; | 1001 return; |
| 1006 destroyed_ = NULL; | 1002 destroyed_ = NULL; |
| 1007 // Under chromeos we immediately set the |move_loop_browser_view_| to NULL. | 1003 // Under chromeos we immediately set the |move_loop_widget_| to NULL. |
| 1008 if (move_loop_browser_view_) { | 1004 if (move_loop_widget_) { |
| 1009 move_loop_browser_view_->set_move_observer(NULL); | 1005 move_loop_widget_->RemoveObserver(this); |
| 1010 move_loop_browser_view_ = NULL; | 1006 move_loop_widget_ = NULL; |
| 1011 } | 1007 } |
| 1012 is_dragging_window_ = false; | 1008 is_dragging_window_ = false; |
| 1013 waiting_for_run_loop_to_exit_ = false; | 1009 waiting_for_run_loop_to_exit_ = false; |
| 1014 if (end_run_loop_behavior_ == END_RUN_LOOP_CONTINUE_DRAGGING) { | 1010 if (end_run_loop_behavior_ == END_RUN_LOOP_CONTINUE_DRAGGING) { |
| 1015 end_run_loop_behavior_ = END_RUN_LOOP_STOP_DRAGGING; | 1011 end_run_loop_behavior_ = END_RUN_LOOP_STOP_DRAGGING; |
| 1016 if (tab_strip_to_attach_to_after_exit_) { | 1012 if (tab_strip_to_attach_to_after_exit_) { |
| 1017 Detach(); | 1013 Detach(); |
| 1018 gfx::Point screen_point(GetCursorScreenPoint()); | 1014 gfx::Point screen_point(GetCursorScreenPoint()); |
| 1019 Attach(tab_strip_to_attach_to_after_exit_, screen_point); | 1015 Attach(tab_strip_to_attach_to_after_exit_, screen_point); |
| 1020 // Move the tabs into position. | 1016 // Move the tabs into position. |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1122 return tabs; | 1118 return tabs; |
| 1123 } | 1119 } |
| 1124 | 1120 |
| 1125 void TabDragController2::EndDragImpl(EndDragType type) { | 1121 void TabDragController2::EndDragImpl(EndDragType type) { |
| 1126 DCHECK(active_); | 1122 DCHECK(active_); |
| 1127 active_ = false; | 1123 active_ = false; |
| 1128 | 1124 |
| 1129 bring_to_front_timer_.Stop(); | 1125 bring_to_front_timer_.Stop(); |
| 1130 | 1126 |
| 1131 if (is_dragging_window_) { | 1127 if (is_dragging_window_) { |
| 1132 if (type == NORMAL || (type == TAB_DESTROYED && drag_data_.size() > 1)) { | 1128 if (type == NORMAL || (type == TAB_DESTROYED && drag_data_.size() > 1)) |
| 1133 SetTrackedByWorkspace( | 1129 SetTrackedByWorkspace(GetAttachedBrowserWidget()->GetNativeView(), true); |
| 1134 GetAttachedBrowserView()->GetWidget()->GetNativeView(), true); | |
| 1135 } | |
| 1136 | 1130 |
| 1137 // End the nested drag loop. | 1131 // End the nested drag loop. |
| 1138 GetAttachedBrowserView()->GetWidget()->EndMoveLoop(); | 1132 GetAttachedBrowserWidget()->EndMoveLoop(); |
| 1139 waiting_for_run_loop_to_exit_ = true; | 1133 waiting_for_run_loop_to_exit_ = true; |
| 1140 } | 1134 } |
| 1141 | 1135 |
| 1142 // Hide the current dock controllers. | 1136 // Hide the current dock controllers. |
| 1143 for (size_t i = 0; i < dock_controllers_.size(); ++i) { | 1137 for (size_t i = 0; i < dock_controllers_.size(); ++i) { |
| 1144 // Be sure and clear the controller first, that way if Hide ends up | 1138 // Be sure and clear the controller first, that way if Hide ends up |
| 1145 // deleting the controller it won't call us back. | 1139 // deleting the controller it won't call us back. |
| 1146 dock_controllers_[i]->clear_controller(); | 1140 dock_controllers_[i]->clear_controller(); |
| 1147 dock_controllers_[i]->Hide(); | 1141 dock_controllers_[i]->Hide(); |
| 1148 } | 1142 } |
| (...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1377 } | 1371 } |
| 1378 } | 1372 } |
| 1379 } | 1373 } |
| 1380 | 1374 |
| 1381 // static | 1375 // static |
| 1382 TabStripModel* TabDragController2::GetModel(TabStrip* tabstrip) { | 1376 TabStripModel* TabDragController2::GetModel(TabStrip* tabstrip) { |
| 1383 return static_cast<BrowserTabStripController*>(tabstrip->controller())-> | 1377 return static_cast<BrowserTabStripController*>(tabstrip->controller())-> |
| 1384 model(); | 1378 model(); |
| 1385 } | 1379 } |
| 1386 | 1380 |
| 1387 BrowserView* TabDragController2::GetAttachedBrowserView() { | 1381 views::Widget* TabDragController2::GetAttachedBrowserWidget() { |
| 1388 return BrowserView::GetBrowserViewForNativeWindow( | 1382 return BrowserView::GetBrowserViewForNativeWindow( |
| 1389 attached_tabstrip_->GetWidget()->GetNativeView()); | 1383 attached_tabstrip_->GetWidget()->GetNativeView())->GetWidget(); |
| 1390 } | 1384 } |
| 1391 | 1385 |
| 1392 bool TabDragController2::AreTabsConsecutive() { | 1386 bool TabDragController2::AreTabsConsecutive() { |
| 1393 for (size_t i = 1; i < drag_data_.size(); ++i) { | 1387 for (size_t i = 1; i < drag_data_.size(); ++i) { |
| 1394 if (drag_data_[i - 1].source_model_index + 1 != | 1388 if (drag_data_[i - 1].source_model_index + 1 != |
| 1395 drag_data_[i].source_model_index) { | 1389 drag_data_[i].source_model_index) { |
| 1396 return false; | 1390 return false; |
| 1397 } | 1391 } |
| 1398 } | 1392 } |
| 1399 return true; | 1393 return true; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1433 browser->window()->SetBounds(new_bounds); | 1427 browser->window()->SetBounds(new_bounds); |
| 1434 return browser; | 1428 return browser; |
| 1435 } | 1429 } |
| 1436 | 1430 |
| 1437 void TabDragController2::SetTrackedByWorkspace(gfx::NativeWindow window, | 1431 void TabDragController2::SetTrackedByWorkspace(gfx::NativeWindow window, |
| 1438 bool value) { | 1432 bool value) { |
| 1439 #if defined(USE_ASH) | 1433 #if defined(USE_ASH) |
| 1440 ash::SetTrackedByWorkspace(window, value); | 1434 ash::SetTrackedByWorkspace(window, value); |
| 1441 #endif | 1435 #endif |
| 1442 } | 1436 } |
| OLD | NEW |