Index: chrome/browser/views/browser_bubble.cc |
=================================================================== |
--- chrome/browser/views/browser_bubble.cc (revision 17478) |
+++ chrome/browser/views/browser_bubble.cc (working copy) |
@@ -5,6 +5,7 @@ |
#include "chrome/browser/views/browser_bubble.h" |
#include "app/l10n_util.h" |
+#include "chrome/browser/views/frame/browser_view.h" |
#include "views/widget/root_view.h" |
BrowserBubble::BrowserBubble(views::View* view, views::Widget* frame, |
@@ -12,16 +13,49 @@ |
: frame_(frame), |
view_(view), |
visible_(false), |
- delegate_(NULL) { |
+ delegate_(NULL), |
+ attached_(false) { |
+ frame_native_view_ = frame_->GetNativeView(); |
gfx::Size size = view->GetPreferredSize(); |
bounds_.SetRect(origin.x(), origin.y(), size.width(), size.height()); |
InitPopup(); |
} |
BrowserBubble::~BrowserBubble() { |
- DestroyPopup(); |
+ DCHECK(!attached_); |
+ popup_->CloseNow(); |
+ // Don't call DetachFromBrowser from here. It needs to talk to the |
+ // BrowserView to deregister itself, and if BrowserBubble is owned |
+ // by a child of BrowserView, then it's possible that this stack frame |
+ // is a descendant of BrowserView's destructor, which leads to problems. |
+ // In that case, Detach doesn't need to get called anyway since BrowserView |
+ // will do the necessary cleanup. |
} |
+void BrowserBubble::DetachFromBrowser() { |
+ DCHECK(attached_); |
+ if (!attached_) |
+ return; |
+ attached_ = false; |
+ BrowserView* browser_view = |
+ BrowserView::GetBrowserViewForNativeWindow(frame_native_view_); |
+ if (browser_view) |
+ browser_view->DetachBrowserBubble(this); |
+} |
+ |
+void BrowserBubble::AttachToBrowser() { |
+ DCHECK(!attached_); |
+ if (attached_) |
+ return; |
+ BrowserView* browser_view = |
+ BrowserView::GetBrowserViewForNativeWindow(frame_native_view_); |
+ DCHECK(browser_view); |
+ if (browser_view) { |
+ browser_view->AttachBrowserBubble(this); |
+ attached_ = true; |
+ } |
+} |
+ |
void BrowserBubble::BrowserWindowMoved() { |
if (delegate_) |
delegate_->BubbleBrowserWindowMoved(this); |
@@ -48,6 +82,10 @@ |
Reposition(); |
} |
+void BrowserBubble::MoveTo(int x, int y) { |
+ SetBounds(x, y, bounds_.width(), bounds_.height()); |
+} |
+ |
void BrowserBubble::Reposition() { |
gfx::Point top_left; |
views::View::ConvertPointToScreen(frame_->GetRootView(), &top_left); |
@@ -56,3 +94,9 @@ |
bounds_.width(), |
bounds_.height()); |
} |
+ |
+void BrowserBubble::ResizeToView() { |
+ gfx::Size size = view_->GetPreferredSize(); |
+ SetBounds(bounds_.x(), bounds_.y(), size.width(), size.height()); |
+} |
+ |