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 |