Index: chrome/browser/ui/views/frame/contents_container.cc |
diff --git a/chrome/browser/ui/views/frame/contents_container.cc b/chrome/browser/ui/views/frame/contents_container.cc |
index 0e24ac7a33155707490cea923dbd6f833f86697c..ccf0abd0597b961d9b50ed0d810523adfecb9391 100644 |
--- a/chrome/browser/ui/views/frame/contents_container.cc |
+++ b/chrome/browser/ui/views/frame/contents_container.cc |
@@ -5,6 +5,7 @@ |
#include "chrome/browser/views/frame/contents_container.h" |
#include "app/slide_animation.h" |
+#include "base/logging.h" |
#include "third_party/skia/include/core/SkColor.h" |
#include "views/background.h" |
#include "views/widget/root_view.h" |
@@ -14,11 +15,35 @@ |
static const int kMinOpacity = 0; |
static const int kMaxOpacity = 192; |
+// View used to track when the overlay widget is destroyed. If the |
+// ContentsContainer is still valid when the destructor is invoked this invokes |
+// |OverlayViewDestroyed| on the ContentsContainer. |
+class ContentsContainer::OverlayContentView : public views::View { |
+ public: |
+ explicit OverlayContentView(ContentsContainer* container) |
+ : container_(container) { |
+ } |
+ ~OverlayContentView() { |
+ if (container_) |
+ container_->OverlayViewDestroyed(); |
+ } |
+ |
+ void Detach() { |
+ container_ = NULL; |
+ } |
+ |
+ private: |
+ ContentsContainer* container_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(OverlayContentView); |
+}; |
+ |
ContentsContainer::ContentsContainer(views::View* active) |
: active_(active), |
preview_(NULL), |
preview_tab_contents_(NULL), |
active_overlay_(NULL), |
+ overlay_view_(NULL), |
active_top_margin_(0) { |
AddChildView(active_); |
} |
@@ -26,6 +51,8 @@ ContentsContainer::ContentsContainer(views::View* active) |
ContentsContainer::~ContentsContainer() { |
// We don't need to explicitly delete active_overlay_ as it'll be deleted by |
// virtue of being a child window. |
+ if (overlay_view_) |
+ overlay_view_->Detach(); |
} |
void ContentsContainer::MakePreviewContentsActiveContents() { |
@@ -82,26 +109,21 @@ void ContentsContainer::FadeActiveContents() { |
overlay_animation_->SetSlideDuration(300); |
overlay_animation_->Show(); |
- active_overlay_ = views::Widget::CreatePopupWidget(views::Widget::Transparent, |
- views::Widget::NotAcceptEvents, |
- views::Widget::DeleteOnDestroy, |
- views::Widget::MirrorOriginInRTL); |
- active_overlay_->SetOpacity(0); |
- gfx::Point screen_origin; |
- views::View::ConvertPointToScreen(active_, &screen_origin); |
- gfx::Rect overlay_bounds(screen_origin, active_->size()); |
- active_overlay_->Init(active_->GetWidget()->GetNativeView(), overlay_bounds); |
- views::View* content_view = new views::View(); |
- content_view->set_background( |
- views::Background::CreateSolidBackground(SK_ColorWHITE)); |
- active_overlay_->SetContentsView(content_view); |
- active_overlay_->Show(); |
- active_overlay_->MoveAbove(active_->GetWidget()); |
+ CreateOverlay(kMinOpacity); |
+} |
+ |
+void ContentsContainer::ShowFade() { |
+ if (active_overlay_ || !Animation::ShouldRenderRichAnimation()) |
+ return; |
+ |
+ CreateOverlay(kMaxOpacity); |
} |
void ContentsContainer::RemoveFade() { |
overlay_animation_.reset(); |
if (active_overlay_) { |
+ overlay_view_->Detach(); |
+ overlay_view_ = NULL; |
active_overlay_->Close(); |
active_overlay_ = NULL; |
} |
@@ -126,3 +148,27 @@ void ContentsContainer::Layout() { |
// still need a layout. |
views::View::Layout(); |
} |
+ |
+void ContentsContainer::CreateOverlay(int initial_opacity) { |
+ DCHECK(!active_overlay_); |
+ active_overlay_ = views::Widget::CreatePopupWidget(views::Widget::Transparent, |
+ views::Widget::NotAcceptEvents, |
+ views::Widget::DeleteOnDestroy, |
+ views::Widget::MirrorOriginInRTL); |
+ active_overlay_->SetOpacity(initial_opacity); |
+ gfx::Point screen_origin; |
+ views::View::ConvertPointToScreen(active_, &screen_origin); |
+ gfx::Rect overlay_bounds(screen_origin, active_->size()); |
+ active_overlay_->Init(active_->GetWidget()->GetNativeView(), overlay_bounds); |
+ overlay_view_ = new OverlayContentView(this); |
+ overlay_view_->set_background( |
+ views::Background::CreateSolidBackground(SK_ColorWHITE)); |
+ active_overlay_->SetContentsView(overlay_view_); |
+ active_overlay_->Show(); |
+ active_overlay_->MoveAbove(active_->GetWidget()); |
+} |
+ |
+void ContentsContainer::OverlayViewDestroyed() { |
+ active_overlay_ = NULL; |
+ overlay_view_ = NULL; |
+} |