| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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 <math.h> | 5 #include <math.h> |
| 6 #include <set> | 6 #include <set> |
| 7 | 7 |
| 8 #include "chrome/browser/views/tabs/dragged_tab_controller.h" | 8 #include "chrome/browser/views/tabs/dragged_tab_controller.h" |
| 9 | 9 |
| 10 #include "chrome/browser/browser_window.h" | 10 #include "chrome/browser/browser_window.h" |
| (...skipping 381 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 392 | 392 |
| 393 void DraggedTabController::NavigationStateChanged(const TabContents* source, | 393 void DraggedTabController::NavigationStateChanged(const TabContents* source, |
| 394 unsigned changed_flags) { | 394 unsigned changed_flags) { |
| 395 if (view_.get()) | 395 if (view_.get()) |
| 396 view_->Update(); | 396 view_->Update(); |
| 397 } | 397 } |
| 398 | 398 |
| 399 void DraggedTabController::ReplaceContents(TabContents* source, | 399 void DraggedTabController::ReplaceContents(TabContents* source, |
| 400 TabContents* new_contents) { | 400 TabContents* new_contents) { |
| 401 DCHECK(dragged_contents_ == source); | 401 DCHECK(dragged_contents_ == source); |
| 402 source->set_delegate(NULL); | |
| 403 new_contents->set_delegate(this); | |
| 404 | 402 |
| 405 // If we're attached to a TabStrip, we need to tell the TabStrip that this | 403 // If we're attached to a TabStrip, we need to tell the TabStrip that this |
| 406 // TabContents was replaced. | 404 // TabContents was replaced. |
| 407 if (attached_tabstrip_ && attached_tabstrip_->model() && dragged_contents_) { | 405 if (attached_tabstrip_ && dragged_contents_) { |
| 408 int index = | 406 if (original_delegate_) { |
| 409 attached_tabstrip_->model()->GetIndexOfTabContents(dragged_contents_); | 407 original_delegate_->ReplaceContents(source, new_contents); |
| 410 if (index != TabStripModel::kNoTab) | 408 // ReplaceContents on the original delegate is going to reset the delegate |
| 411 attached_tabstrip_->model()->ReplaceTabContentsAt(index, new_contents); | 409 // for us. We need to unset original_delegate_ here so that |
| 410 // ChangeDraggedContents doesn't attempt to restore the delegate to the |
| 411 // wrong value. |
| 412 original_delegate_ = NULL; |
| 413 } else if (attached_tabstrip_->model()) { |
| 414 int index = |
| 415 attached_tabstrip_->model()->GetIndexOfTabContents(dragged_contents_); |
| 416 if (index != TabStripModel::kNoTab) |
| 417 attached_tabstrip_->model()->ReplaceTabContentsAt(index, new_contents); |
| 418 } |
| 412 } | 419 } |
| 413 | 420 |
| 414 // Update our internal state. | 421 // Update our internal state. |
| 415 ChangeDraggedContents(new_contents); | 422 ChangeDraggedContents(new_contents); |
| 416 | 423 |
| 417 if (view_.get()) | 424 if (view_.get()) |
| 418 view_->Update(); | 425 view_->Update(); |
| 419 } | 426 } |
| 420 | 427 |
| 421 void DraggedTabController::AddNewContents(TabContents* source, | 428 void DraggedTabController::AddNewContents(TabContents* source, |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 550 dock_controllers_.back()->UpdateInEnabledArea(dock_info_.in_enable_area()); | 557 dock_controllers_.back()->UpdateInEnabledArea(dock_info_.in_enable_area()); |
| 551 } | 558 } |
| 552 } | 559 } |
| 553 | 560 |
| 554 | 561 |
| 555 void DraggedTabController::ChangeDraggedContents(TabContents* new_contents) { | 562 void DraggedTabController::ChangeDraggedContents(TabContents* new_contents) { |
| 556 if (dragged_contents_) { | 563 if (dragged_contents_) { |
| 557 NotificationService::current()->RemoveObserver(this, | 564 NotificationService::current()->RemoveObserver(this, |
| 558 NOTIFY_TAB_CONTENTS_DESTROYED, | 565 NOTIFY_TAB_CONTENTS_DESTROYED, |
| 559 Source<TabContents>(dragged_contents_)); | 566 Source<TabContents>(dragged_contents_)); |
| 567 if (original_delegate_) |
| 568 dragged_contents_->set_delegate(original_delegate_); |
| 560 } | 569 } |
| 570 original_delegate_ = NULL; |
| 561 dragged_contents_ = new_contents; | 571 dragged_contents_ = new_contents; |
| 562 if (dragged_contents_) { | 572 if (dragged_contents_) { |
| 563 NotificationService::current()->AddObserver(this, | 573 NotificationService::current()->AddObserver(this, |
| 564 NOTIFY_TAB_CONTENTS_DESTROYED, | 574 NOTIFY_TAB_CONTENTS_DESTROYED, |
| 565 Source<TabContents>(dragged_contents_)); | 575 Source<TabContents>(dragged_contents_)); |
| 576 |
| 577 // We need to be the delegate so we receive messages about stuff, |
| 578 // otherwise our dragged_contents() may be replaced and subsequently |
| 579 // collected/destroyed while the drag is in process, leading to |
| 580 // nasty crashes. |
| 581 original_delegate_ = dragged_contents_->delegate(); |
| 582 dragged_contents_->set_delegate(this); |
| 566 } | 583 } |
| 567 } | 584 } |
| 568 | 585 |
| 569 void DraggedTabController::SaveFocus() { | 586 void DraggedTabController::SaveFocus() { |
| 570 if (!old_focused_view_) { | 587 if (!old_focused_view_) { |
| 571 old_focused_view_ = source_tab_->GetRootView()->GetFocusedView(); | 588 old_focused_view_ = source_tab_->GetRootView()->GetFocusedView(); |
| 572 source_tab_->GetRootView()->FocusView(source_tab_); | 589 source_tab_->GetRootView()->FocusView(source_tab_); |
| 573 } | 590 } |
| 574 } | 591 } |
| 575 | 592 |
| (...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 813 // TabContents. | 830 // TabContents. |
| 814 if (!photobooth_.get()) | 831 if (!photobooth_.get()) |
| 815 photobooth_.reset(new HWNDPhotobooth(dragged_contents_->GetContainerHWND()))
; | 832 photobooth_.reset(new HWNDPhotobooth(dragged_contents_->GetContainerHWND()))
; |
| 816 | 833 |
| 817 // Update the View. This NULL check is necessary apparently in some | 834 // Update the View. This NULL check is necessary apparently in some |
| 818 // conditions during automation where the view_ is destroyed inside a | 835 // conditions during automation where the view_ is destroyed inside a |
| 819 // function call preceding this point but after it is created. | 836 // function call preceding this point but after it is created. |
| 820 if (view_.get()) | 837 if (view_.get()) |
| 821 view_->Detach(photobooth_.get()); | 838 view_->Detach(photobooth_.get()); |
| 822 | 839 |
| 823 // We need to be the delegate so we receive messages about stuff, | 840 // Detaching resets the delegate, but we still want to be the delegate. |
| 824 // otherwise our dragged_contents() may be replaced and subsequently | |
| 825 // collected/destroyed while the drag is in process, leading to | |
| 826 // nasty crashes. | |
| 827 original_delegate_ = dragged_contents_->delegate(); | |
| 828 dragged_contents_->set_delegate(this); | 841 dragged_contents_->set_delegate(this); |
| 829 | 842 |
| 830 attached_tabstrip_ = NULL; | 843 attached_tabstrip_ = NULL; |
| 831 } | 844 } |
| 832 | 845 |
| 833 int DraggedTabController::GetInsertionIndexForDraggedBounds( | 846 int DraggedTabController::GetInsertionIndexForDraggedBounds( |
| 834 const gfx::Rect& dragged_bounds) const { | 847 const gfx::Rect& dragged_bounds) const { |
| 835 int right_tab_x = 0; | 848 int right_tab_x = 0; |
| 836 | 849 |
| 837 // If the UI layout of the tab strip is right-to-left, we need to mirror the | 850 // If the UI layout of the tab strip is right-to-left, we need to mirror the |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 915 } | 928 } |
| 916 | 929 |
| 917 | 930 |
| 918 Tab* DraggedTabController::GetTabMatchingDraggedContents( | 931 Tab* DraggedTabController::GetTabMatchingDraggedContents( |
| 919 TabStrip* tabstrip) const { | 932 TabStrip* tabstrip) const { |
| 920 int index = tabstrip->model()->GetIndexOfTabContents(dragged_contents_); | 933 int index = tabstrip->model()->GetIndexOfTabContents(dragged_contents_); |
| 921 return index == TabStripModel::kNoTab ? NULL : tabstrip->GetTabAt(index); | 934 return index == TabStripModel::kNoTab ? NULL : tabstrip->GetTabAt(index); |
| 922 } | 935 } |
| 923 | 936 |
| 924 bool DraggedTabController::EndDragImpl(EndDragType type) { | 937 bool DraggedTabController::EndDragImpl(EndDragType type) { |
| 938 // WARNING: this may be invoked multiple times. In particular, if deletion |
| 939 // occurs after a delay (as it does when the tab is released in the original |
| 940 // tab strip) and the navigation controller/tab contents is deleted before |
| 941 // the animation finishes, this is invoked twice. The second time through |
| 942 // type == TAB_DESTROYED. |
| 943 |
| 925 bring_to_front_timer_.Stop(); | 944 bring_to_front_timer_.Stop(); |
| 926 | 945 |
| 927 // Hide the current dock controllers. | 946 // Hide the current dock controllers. |
| 928 for (size_t i = 0; i < dock_controllers_.size(); ++i) { | 947 for (size_t i = 0; i < dock_controllers_.size(); ++i) { |
| 929 // Be sure and clear the controller first, that way if Hide ends up | 948 // Be sure and clear the controller first, that way if Hide ends up |
| 930 // deleting the controller it won't call us back. | 949 // deleting the controller it won't call us back. |
| 931 dock_controllers_[i]->clear_controller(); | 950 dock_controllers_[i]->clear_controller(); |
| 932 dock_controllers_[i]->Hide(); | 951 dock_controllers_[i]->Hide(); |
| 933 } | 952 } |
| 934 dock_controllers_.clear(); | 953 dock_controllers_.clear(); |
| 935 dock_windows_.clear(); | 954 dock_windows_.clear(); |
| 936 | 955 |
| 937 bool destroy_now = true; | 956 bool destroy_now = true; |
| 938 if (type != TAB_DESTROYED) { | 957 if (type != TAB_DESTROYED) { |
| 939 // We only finish up the drag if we were actually dragging. If we never | 958 // We only finish up the drag if we were actually dragging. If we never |
| 940 // constructed a view, the user just clicked and released and didn't move th
e | 959 // constructed a view, the user just clicked and released and didn't move th
e |
| 941 // mouse enough to trigger a drag. | 960 // mouse enough to trigger a drag. |
| 942 if (view_.get()) { | 961 if (view_.get()) { |
| 943 RestoreFocus(); | 962 RestoreFocus(); |
| 944 if (type == CANCELED) { | 963 if (type == CANCELED) { |
| 945 RevertDrag(); | 964 RevertDrag(); |
| 946 } else { | 965 } else { |
| 947 destroy_now = CompleteDrag(); | 966 destroy_now = CompleteDrag(); |
| 948 } | 967 } |
| 949 } | 968 } |
| 969 if (dragged_contents_ && dragged_contents_->delegate() == this) |
| 970 dragged_contents_->set_delegate(original_delegate_); |
| 950 } else { | 971 } else { |
| 951 // If we get here it means the NavigationController is going down. Don't | 972 // If we get here it means the NavigationController is going down. Don't |
| 952 // attempt to do any cleanup other than resetting the delegate (if we're | 973 // attempt to do any cleanup other than resetting the delegate (if we're |
| 953 // still the delegate). | 974 // still the delegate). |
| 954 if (dragged_contents_ && dragged_contents_->delegate() == this) | 975 if (dragged_contents_ && dragged_contents_->delegate() == this) |
| 955 dragged_contents_->set_delegate(NULL); | 976 dragged_contents_->set_delegate(NULL); |
| 956 dragged_contents_ = NULL; | 977 dragged_contents_ = NULL; |
| 957 attached_tabstrip_ = NULL; | |
| 958 } | 978 } |
| 979 |
| 980 // The delegate of the dragged contents should have been reset. Unset the |
| 981 // original delegate so that we don't attempt to reset the delegate when |
| 982 // deleted. |
| 983 DCHECK(!dragged_contents_ || dragged_contents_->delegate() != this); |
| 984 original_delegate_ = NULL; |
| 985 |
| 959 // If we're not destroyed now, we'll be destroyed asynchronously later. | 986 // If we're not destroyed now, we'll be destroyed asynchronously later. |
| 960 if (destroy_now) | 987 if (destroy_now) |
| 961 source_tabstrip_->DestroyDragController(); | 988 source_tabstrip_->DestroyDragController(); |
| 962 | 989 |
| 963 return destroy_now; | 990 return destroy_now; |
| 964 } | 991 } |
| 965 | 992 |
| 966 void DraggedTabController::RevertDrag() { | 993 void DraggedTabController::RevertDrag() { |
| 967 // We save this here because code below will modify |attached_tabstrip_|. | 994 // We save this here because code below will modify |attached_tabstrip_|. |
| 968 bool restore_frame = attached_tabstrip_ != source_tabstrip_; | 995 bool restore_frame = attached_tabstrip_ != source_tabstrip_; |
| (...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1193 // Move the window to the front. | 1220 // Move the window to the front. |
| 1194 SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, | 1221 SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, |
| 1195 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); | 1222 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); |
| 1196 | 1223 |
| 1197 // The previous call made the window appear on top of the dragged window, | 1224 // The previous call made the window appear on top of the dragged window, |
| 1198 // move the dragged window to the front. | 1225 // move the dragged window to the front. |
| 1199 SetWindowPos(view_->GetWidget()->GetHWND(), HWND_TOP, 0, 0, 0, 0, | 1226 SetWindowPos(view_->GetWidget()->GetHWND(), HWND_TOP, 0, 0, 0, 0, |
| 1200 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); | 1227 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); |
| 1201 } | 1228 } |
| 1202 } | 1229 } |
| OLD | NEW |