summaryrefslogtreecommitdiffstats
path: root/ui/views/bubble
diff options
context:
space:
mode:
authormsw@chromium.org <msw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-04-23 19:33:26 +0000
committermsw@chromium.org <msw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-04-23 19:33:26 +0000
commitaa4d9e4710dca9f41f2fcea256b996421b10912f (patch)
tree13c509800a7ef9d53a0d3c69f0d5375583ccc87a /ui/views/bubble
parentd8542e8f5aa58387ba148606d55f7b8e078a60f5 (diff)
downloadchromium_src-aa4d9e4710dca9f41f2fcea256b996421b10912f.zip
chromium_src-aa4d9e4710dca9f41f2fcea256b996421b10912f.tar.gz
chromium_src-aa4d9e4710dca9f41f2fcea256b996421b10912f.tar.bz2
Re-reland Propagate OnNativeWidgetMove to delegate/observers, etc.
Continuation of reverted CL http://codereview.chromium.org/10025039 Relanding this patch exposed a new issues on cros: 1) KioskModeTest.EnableKioskModeTest fails (did unrelated cleanup). 2) Some bubbles crash OnWidgetMove (make |move_with_anchor_| opt-in). 3) Some bubbles crash OnWidgetClosing (cache |anchor_widget_|). 2nd patch description: Continuation of reverted CL http://codereview.chromium.org/10021029 The original CL was reverted due to a naming conflict between: WidgetDelegate::OnWidgetMove and Widget::Observer::OnWidgetMove. I renamed the new Observer method to OnWidgetMoved. Original description: Propagate OnNativeWidgetMove to delegate/observers, etc. NativeWidget[Aura|Win] calls new Widget::OnNativeWidgetMove. Widgets alert delegates and new Widget::Observer::OnWidgetMove. TabDragController2: consume new observer method, simplify. Nix BrowserWindowMoveObserver; use Widget::Observer instead. Replace move_loop_browser_view_ with move_loop_widget. Replace GetAttachedBrowserView with GetAttachedBrowserWidget. BubbleDelegateView: consume new observer method. Make bubbles move with their anchor_view's Widgets. SchedulePaint on BubbleFrameView when mirroring its arrow. BUG=105151,116336,124310,124324,124352,chromium-os:29747 TEST=Bubbles can move with the browser window (inspecting extension popups, etc.); no Ash / --enable-tab-browser-dragging regressions. Review URL: http://codereview.chromium.org/10162017 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@133495 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui/views/bubble')
-rw-r--r--ui/views/bubble/bubble_delegate.cc56
-rw-r--r--ui/views/bubble/bubble_delegate.h22
-rw-r--r--ui/views/bubble/bubble_frame_view.cc7
3 files changed, 61 insertions, 24 deletions
diff --git a/ui/views/bubble/bubble_delegate.cc b/ui/views/bubble/bubble_delegate.cc
index 3942c92..f593a1b 100644
--- a/ui/views/bubble/bubble_delegate.cc
+++ b/ui/views/bubble/bubble_delegate.cc
@@ -20,7 +20,7 @@ namespace views {
namespace {
// Create a widget to host the bubble.
-Widget* CreateBubbleWidget(BubbleDelegateView* bubble, Widget* parent) {
+Widget* CreateBubbleWidget(BubbleDelegateView* bubble) {
Widget* bubble_widget = new Widget();
Widget::InitParams bubble_params(Widget::InitParams::TYPE_BUBBLE);
bubble_params.delegate = bubble;
@@ -28,7 +28,7 @@ Widget* CreateBubbleWidget(BubbleDelegateView* bubble, Widget* parent) {
if (bubble->parent_window())
bubble_params.parent = bubble->parent_window();
else
- bubble_params.parent_widget = parent;
+ bubble_params.parent_widget = bubble->anchor_widget();
if (bubble->use_focusless())
bubble_params.can_activate = false;
#if defined(OS_WIN) && !defined(USE_AURA)
@@ -81,12 +81,12 @@ class BubbleBorderDelegate : public WidgetDelegate,
};
// Create a widget to host the bubble's border.
-Widget* CreateBorderWidget(BubbleDelegateView* bubble, Widget* parent) {
+Widget* CreateBorderWidget(BubbleDelegateView* bubble) {
Widget* border_widget = new Widget();
Widget::InitParams border_params(Widget::InitParams::TYPE_BUBBLE);
border_params.delegate = new BubbleBorderDelegate(bubble, border_widget);
border_params.transparent = true;
- border_params.parent_widget = parent;
+ border_params.parent_widget = bubble->anchor_widget();
border_widget->Init(border_params);
return border_widget;
}
@@ -106,6 +106,8 @@ BubbleDelegateView::BubbleDelegateView()
: close_on_esc_(true),
close_on_deactivate_(true),
anchor_view_(NULL),
+ anchor_widget_(NULL),
+ move_with_anchor_(false),
arrow_location_(BubbleBorder::TOP_LEFT),
color_(kBackgroundColor),
margin_(kDefaultMargin),
@@ -123,6 +125,8 @@ BubbleDelegateView::BubbleDelegateView(
: close_on_esc_(true),
close_on_deactivate_(true),
anchor_view_(anchor_view),
+ anchor_widget_(NULL),
+ move_with_anchor_(false),
arrow_location_(arrow_location),
color_(kBackgroundColor),
margin_(kDefaultMargin),
@@ -139,14 +143,15 @@ BubbleDelegateView::~BubbleDelegateView() {}
// static
Widget* BubbleDelegateView::CreateBubble(BubbleDelegateView* bubble_delegate) {
bubble_delegate->Init();
- Widget* parent = bubble_delegate->anchor_view() ?
+ // 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;
- Widget* bubble_widget = CreateBubbleWidget(bubble_delegate, parent);
+ Widget* bubble_widget = CreateBubbleWidget(bubble_delegate);
#if defined(OS_WIN) && !defined(USE_AURA)
// First set the contents view to initialize view bounds for widget sizing.
bubble_widget->SetContentsView(bubble_delegate->GetContentsView());
- bubble_delegate->border_widget_ = CreateBorderWidget(bubble_delegate, parent);
+ bubble_delegate->border_widget_ = CreateBorderWidget(bubble_delegate);
#endif
bubble_delegate->SizeToContents();
@@ -171,19 +176,31 @@ NonClientFrameView* BubbleDelegateView::CreateNonClientFrameView(
return new BubbleFrameView(arrow_location(), color(), margin());
}
+void BubbleDelegateView::OnWidgetClosing(Widget* widget) {
+ if (anchor_widget() == widget) {
+ anchor_view_ = NULL;
+ anchor_widget_ = NULL;
+ }
+}
+
void BubbleDelegateView::OnWidgetVisibilityChanged(Widget* widget,
bool visible) {
- if (widget == GetWidget()) {
- if (visible) {
- if (border_widget_)
- border_widget_->Show();
- GetFocusManager()->SetFocusedView(GetInitiallyFocusedView());
- Widget* anchor_widget = anchor_view() ? anchor_view()->GetWidget() : NULL;
- if (anchor_widget && anchor_widget->GetTopLevelWidget())
- anchor_widget->GetTopLevelWidget()->DisableInactiveRendering();
- } else if (border_widget_) {
+ if (widget != GetWidget())
+ return;
+
+ if (visible) {
+ if (border_widget_)
+ border_widget_->Show();
+ if (anchor_widget())
+ anchor_widget()->AddObserver(this);
+ GetFocusManager()->SetFocusedView(GetInitiallyFocusedView());
+ if (anchor_widget() && anchor_widget()->GetTopLevelWidget())
+ anchor_widget()->GetTopLevelWidget()->DisableInactiveRendering();
+ } else {
+ if (border_widget_)
border_widget_->Hide();
- }
+ if (anchor_widget())
+ anchor_widget()->RemoveObserver(this);
}
}
@@ -193,6 +210,11 @@ void BubbleDelegateView::OnWidgetActivationChanged(Widget* widget,
GetWidget()->Close();
}
+void BubbleDelegateView::OnWidgetMoved(Widget* widget) {
+ if (move_with_anchor() && anchor_widget() == widget)
+ SizeToContents();
+}
+
gfx::Rect BubbleDelegateView::GetAnchorRect() {
return anchor_view() ? anchor_view()->GetScreenBounds() : gfx::Rect();
}
diff --git a/ui/views/bubble/bubble_delegate.h b/ui/views/bubble/bubble_delegate.h
index 75f6c16..a1976e6 100644
--- a/ui/views/bubble/bubble_delegate.h
+++ b/ui/views/bubble/bubble_delegate.h
@@ -47,23 +47,25 @@ class VIEWS_EXPORT BubbleDelegateView : public WidgetDelegateView,
views::Widget* widget) OVERRIDE;
// Widget::Observer overrides:
+ virtual void OnWidgetClosing(Widget* widget) OVERRIDE;
virtual void OnWidgetVisibilityChanged(Widget* widget, bool visible) OVERRIDE;
virtual void OnWidgetActivationChanged(Widget* widget, bool active) OVERRIDE;
+ virtual void OnWidgetMoved(Widget* widget) OVERRIDE;
bool close_on_esc() const { return close_on_esc_; }
void set_close_on_esc(bool close_on_esc) { close_on_esc_ = close_on_esc; }
bool close_on_deactivate() const { return close_on_deactivate_; }
void set_close_on_deactivate(bool close_on_deactivate) {
- close_on_deactivate_ = close_on_deactivate;
+ close_on_deactivate_ = close_on_deactivate;
}
View* anchor_view() const { return anchor_view_; }
- void set_anchor_view(View* anchor_view) { anchor_view_ = anchor_view; }
+ Widget* anchor_widget() const { return anchor_widget_; }
BubbleBorder::ArrowLocation arrow_location() const { return arrow_location_; }
void set_arrow_location(BubbleBorder::ArrowLocation arrow_location) {
- arrow_location_ = arrow_location;
+ arrow_location_ = arrow_location;
}
SkColor color() const { return color_; }
@@ -108,6 +110,14 @@ class VIEWS_EXPORT BubbleDelegateView : public WidgetDelegateView,
// Perform view initialization on the contents for bubble sizing.
virtual void Init();
+ // Set the anchor view, this must be done before calling CreateBubble or Show.
+ void set_anchor_view(View* anchor_view) { anchor_view_ = anchor_view; }
+
+ bool move_with_anchor() const { return move_with_anchor_; }
+ void set_move_with_anchor(bool move_with_anchor) {
+ move_with_anchor_ = move_with_anchor;
+ }
+
// Resizes and potentially moves the Bubble to best accommodate the
// contents preferred size.
void SizeToContents();
@@ -133,8 +143,12 @@ class VIEWS_EXPORT BubbleDelegateView : public WidgetDelegateView,
bool close_on_esc_;
bool close_on_deactivate_;
- // The view hosting this bubble; the arrow is anchored to this view.
+ // The view and widget to which this bubble is anchored.
View* anchor_view_;
+ Widget* anchor_widget_;
+
+ // If true, the bubble will re-anchor (and may resize) with |anchor_widget_|.
+ bool move_with_anchor_;
// The arrow's location on the bubble.
BubbleBorder::ArrowLocation arrow_location_;
diff --git a/ui/views/bubble/bubble_frame_view.cc b/ui/views/bubble/bubble_frame_view.cc
index ab2ae24..176c010 100644
--- a/ui/views/bubble/bubble_frame_view.cc
+++ b/ui/views/bubble/bubble_frame_view.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -117,9 +117,10 @@ void BubbleFrameView::MirrorArrowIfOffScreen(
bubble_border_->GetBounds(anchor_rect, client_size);
// Restore the original arrow if mirroring doesn't show more of the bubble.
if (GetOffScreenLength(monitor_rect, mirror_bounds, vertical) >=
- GetOffScreenLength(monitor_rect, window_bounds, vertical)) {
+ GetOffScreenLength(monitor_rect, window_bounds, vertical))
bubble_border_->set_arrow_location(arrow);
- }
+ else
+ SchedulePaint();
}
}