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

Unified Diff: ui/views/bubble/bubble_delegate.cc

Issue 24469006: Fixing crash Report - Magic Signature: views::View::ConvertPointToScreen (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: A self check encountered a few things.. Created 7 years, 3 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 side-by-side diff with in-line comments
Download patch
Index: ui/views/bubble/bubble_delegate.cc
diff --git a/ui/views/bubble/bubble_delegate.cc b/ui/views/bubble/bubble_delegate.cc
index af08994d487f5905b3471e806cfb899664de10e0..b742b2266afaff98bc94182d8496520ea8551dd5 100644
--- a/ui/views/bubble/bubble_delegate.cc
+++ b/ui/views/bubble/bubble_delegate.cc
@@ -9,6 +9,7 @@
#include "ui/gfx/rect.h"
#include "ui/native_theme/native_theme.h"
#include "ui/views/bubble/bubble_frame_view.h"
+#include "ui/views/focus/view_storage.h"
#include "ui/views/widget/widget.h"
#include "ui/views/widget/widget_observer.h"
@@ -128,8 +129,10 @@ Widget* CreateBorderWidget(BubbleDelegateView* bubble) {
BubbleDelegateView::BubbleDelegateView()
: close_on_esc_(true),
close_on_deactivate_(true),
- anchor_view_(NULL),
+ has_anchor_view_(false),
+ last_known_anchor_view_rect_(gfx::Rect()),
msw 2013/09/27 18:20:31 Remove this and others, the default gfx::Rect ctor
Mr4D (OOO till 08-26) 2013/09/27 20:29:35 Done.
anchor_widget_(NULL),
+ anchor_rect_(gfx::Rect()),
move_with_anchor_(false),
arrow_(BubbleBorder::TOP_LEFT),
shadow_(BubbleBorder::SMALL_SHADOW),
@@ -151,8 +154,10 @@ BubbleDelegateView::BubbleDelegateView(
BubbleBorder::Arrow arrow)
: close_on_esc_(true),
close_on_deactivate_(true),
- anchor_view_(anchor_view),
+ has_anchor_view_(false),
+ last_known_anchor_view_rect_(gfx::Rect()),
anchor_widget_(NULL),
+ anchor_rect_(gfx::Rect()),
move_with_anchor_(false),
arrow_(arrow),
shadow_(BubbleBorder::SMALL_SHADOW),
@@ -165,23 +170,21 @@ BubbleDelegateView::BubbleDelegateView(
border_accepts_events_(true),
adjust_if_offscreen_(true),
parent_window_(NULL) {
+ SetAnchorView(anchor_view);
AddAccelerator(ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE));
UpdateColorsFromTheme(GetNativeTheme());
}
BubbleDelegateView::~BubbleDelegateView() {
- if (anchor_widget() != NULL)
- anchor_widget()->RemoveObserver(this);
- anchor_widget_ = NULL;
- anchor_view_ = NULL;
+ DetachFromAnchor();
}
// static
Widget* BubbleDelegateView::CreateBubble(BubbleDelegateView* bubble_delegate) {
bubble_delegate->Init();
// Determine the anchor widget from the anchor view at bubble creation time.
- bubble_delegate->anchor_widget_ = bubble_delegate->anchor_view() ?
- bubble_delegate->anchor_view()->GetWidget() : NULL;
+ bubble_delegate->anchor_widget_ = bubble_delegate->AnchorView() ?
+ bubble_delegate->AnchorView()->GetWidget() : NULL;
if (bubble_delegate->anchor_widget())
bubble_delegate->anchor_widget()->AddObserver(bubble_delegate);
@@ -231,11 +234,8 @@ NonClientFrameView* BubbleDelegateView::CreateNonClientFrameView(
}
void BubbleDelegateView::OnWidgetDestroying(Widget* widget) {
- if (anchor_widget() == widget) {
- anchor_widget_->RemoveObserver(this);
- anchor_view_ = NULL;
- anchor_widget_ = NULL;
- }
+ if (anchor_widget() == widget)
+ DetachFromAnchor();
}
void BubbleDelegateView::OnWidgetVisibilityChanging(Widget* widget,
@@ -267,11 +267,48 @@ void BubbleDelegateView::OnWidgetBoundsChanged(Widget* widget,
SizeToContents();
}
+View* BubbleDelegateView::AnchorView() const {
+ if (!has_anchor_view_)
+ return NULL;
+ return ViewStorage::GetInstance()->RetrieveView(anchor_view_storage_id_);
+}
+
+const gfx::Rect& BubbleDelegateView::AnchorRect() const {
+ return has_anchor_view_ ? last_known_anchor_view_rect_ : anchor_rect_;
+}
+
+void BubbleDelegateView::SetAnchorView(View* anchor_view) {
+ if (!anchor_view) {
+ if (has_anchor_view_) {
+ has_anchor_view_ = false;
+ last_known_anchor_view_rect_ = anchor_rect_;
+ ViewStorage::GetInstance()->RemoveView(anchor_view_storage_id_);
+ }
+ return;
+ }
+
+ if (!has_anchor_view_) {
+ anchor_view_storage_id_ = ViewStorage::GetInstance()->CreateStorageID();
msw 2013/09/27 18:20:31 This int needs ctor initialization; either initial
Mr4D (OOO till 08-26) 2013/09/27 20:29:35 According to the header file -1 is not an invalid
msw 2013/09/27 21:21:52 CreateStorageID always uses positive numbers, at l
+ has_anchor_view_ = true;
+ }
+
+ ViewStorage::GetInstance()->StoreView(anchor_view_storage_id_, anchor_view);
+}
+
+void BubbleDelegateView::SetAnchorRect(const gfx::Rect& rect) {
msw 2013/09/27 18:20:31 Reverted this to set_anchor_rect with my suggestio
Mr4D (OOO till 08-26) 2013/09/27 20:29:35 Done.
+ anchor_rect_ = rect;
+ last_known_anchor_view_rect_ = rect;
+}
+
gfx::Rect BubbleDelegateView::GetAnchorRect() {
- if (!anchor_view())
- return anchor_rect_;
- gfx::Rect anchor_bounds = anchor_view()->GetBoundsInScreen();
+ if (!AnchorView()) {
msw 2013/09/27 18:20:31 I think this function can remain largely the same;
Mr4D (OOO till 08-26) 2013/09/27 20:29:35 I did that this way since you *explicitly* told me
msw 2013/09/27 21:21:52 Sorry for not being clear enough yesterday, but th
+ // If the anchor view was going away, we have to return the last known good
+ // position.
+ return has_anchor_view_ ? last_known_anchor_view_rect_ : anchor_rect_;
+ }
+ gfx::Rect anchor_bounds = AnchorView()->GetBoundsInScreen();
anchor_bounds.Inset(anchor_view_insets_);
+ last_known_anchor_view_rect_ = anchor_bounds;
return anchor_bounds;
}
@@ -437,4 +474,11 @@ void BubbleDelegateView::HandleVisibilityChanged(Widget* widget,
}
}
+void BubbleDelegateView::DetachFromAnchor() {
+ if (anchor_widget_)
+ anchor_widget_->RemoveObserver(this);
+ SetAnchorView(NULL);
+ anchor_widget_ = NULL;
+}
+
} // namespace views

Powered by Google App Engine
This is Rietveld 408576698