Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(245)

Side by Side Diff: chrome/browser/views/tabs/dragged_tab_controller.cc

Issue 19026: Fixes tab contents crash. This changes a number of things in dragged... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698