diff options
-rw-r--r-- | ash/desktop_background/desktop_background_view.h | 3 | ||||
-rw-r--r-- | ash/launcher/launcher.cc | 4 | ||||
-rw-r--r-- | ash/shell/window_type_launcher.cc | 2 | ||||
-rw-r--r-- | chrome/browser/chromeos/login/webui_login_view.h | 2 | ||||
-rw-r--r-- | ui/oak/oak_window.cc | 1 | ||||
-rw-r--r-- | ui/views/test/child_modal_window.cc | 2 | ||||
-rw-r--r-- | ui/views/widget/widget_delegate.cc | 6 | ||||
-rw-r--r-- | ui/views/widget/widget_delegate.h | 4 | ||||
-rw-r--r-- | ui/views/widget/widget_unittest.cc | 24 | ||||
-rw-r--r-- | ui/views/window/dialog_delegate.cc | 9 | ||||
-rw-r--r-- | ui/views/window/dialog_delegate.h | 4 |
11 files changed, 52 insertions, 9 deletions
diff --git a/ash/desktop_background/desktop_background_view.h b/ash/desktop_background/desktop_background_view.h index 06d4dc4..8528e77 100644 --- a/ash/desktop_background/desktop_background_view.h +++ b/ash/desktop_background/desktop_background_view.h @@ -8,12 +8,11 @@ #include "ui/gfx/image/image_skia.h" #include "ui/views/context_menu_controller.h" #include "ui/views/view.h" -#include "ui/views/widget/widget_delegate.h" namespace ash { namespace internal { -class DesktopBackgroundView : public views::WidgetDelegateView, +class DesktopBackgroundView : public views::View, public views::ContextMenuController { public: DesktopBackgroundView(); diff --git a/ash/launcher/launcher.cc b/ash/launcher/launcher.cc index f07f8fd..09af40c 100644 --- a/ash/launcher/launcher.cc +++ b/ash/launcher/launcher.cc @@ -96,8 +96,8 @@ class Launcher::DelegateView : public views::WidgetDelegate, // Class used to slightly dim shelf items when maximized and visible. It also // makes sure the widget changes size to always be of the same size as the // shelf. -class Launcher::DimmerView : public views::WidgetDelegateView, - public aura::WindowObserver { +class Launcher::DimmerView : public views::View, + public aura::WindowObserver { public: explicit DimmerView(Launcher* launcher) : launcher_(launcher) { diff --git a/ash/shell/window_type_launcher.cc b/ash/shell/window_type_launcher.cc index e923a15..09843bc 100644 --- a/ash/shell/window_type_launcher.cc +++ b/ash/shell/window_type_launcher.cc @@ -160,6 +160,8 @@ class NonModalTransient : public views::WidgetDelegateView { virtual void DeleteDelegate() OVERRIDE { if (GetWidget() == non_modal_transient_) non_modal_transient_ = NULL; + + delete this; } private: diff --git a/chrome/browser/chromeos/login/webui_login_view.h b/chrome/browser/chromeos/login/webui_login_view.h index 8ef87ab1..669b061 100644 --- a/chrome/browser/chromeos/login/webui_login_view.h +++ b/chrome/browser/chromeos/login/webui_login_view.h @@ -31,7 +31,7 @@ namespace chromeos { // View used to render a WebUI supporting Widget. This widget is used for the // WebUI based start up and lock screens. It contains a WebView. -class WebUILoginView : public views::WidgetDelegateView, +class WebUILoginView : public views::View, public content::WebContentsDelegate, public content::NotificationObserver { public: diff --git a/ui/oak/oak_window.cc b/ui/oak/oak_window.cc index 832a7a9..7cf7dff 100644 --- a/ui/oak/oak_window.cc +++ b/ui/oak/oak_window.cc @@ -68,6 +68,7 @@ bool OakWindow::ShouldShowWindowIcon() const { void OakWindow::DeleteDelegate() { instance = NULL; + delete this; } //////////////////////////////////////////////////////////////////////////////// diff --git a/ui/views/test/child_modal_window.cc b/ui/views/test/child_modal_window.cc index ebf1ac2..04d5df5 100644 --- a/ui/views/test/child_modal_window.cc +++ b/ui/views/test/child_modal_window.cc @@ -173,6 +173,8 @@ void ChildModalParent::DeleteDelegate() { child_->Close(); child_ = NULL; } + + delete this; } void ChildModalParent::Layout() { diff --git a/ui/views/widget/widget_delegate.cc b/ui/views/widget/widget_delegate.cc index 7a42ec4..cb7b469d 100644 --- a/ui/views/widget/widget_delegate.cc +++ b/ui/views/widget/widget_delegate.cc @@ -160,11 +160,17 @@ bool WidgetDelegate::ShouldDescendIntoChildForEventHandling( // WidgetDelegateView: WidgetDelegateView::WidgetDelegateView() { + // A WidgetDelegate should be deleted on DeleteDelegate. + set_owned_by_client(); } WidgetDelegateView::~WidgetDelegateView() { } +void WidgetDelegateView::DeleteDelegate() { + delete this; +} + Widget* WidgetDelegateView::GetWidget() { return View::GetWidget(); } diff --git a/ui/views/widget/widget_delegate.h b/ui/views/widget/widget_delegate.h index 640ccbc..f7b5ffc 100644 --- a/ui/views/widget/widget_delegate.h +++ b/ui/views/widget/widget_delegate.h @@ -164,13 +164,15 @@ class VIEWS_EXPORT WidgetDelegate { // A WidgetDelegate implementation that is-a View. Used to override GetWidget() // to call View's GetWidget() for the common case where a WidgetDelegate -// implementation is-a View. +// implementation is-a View. Note that WidgetDelegateView is not owned by +// view's hierarchy and is expected to be deleted on DeleteDelegate call. class VIEWS_EXPORT WidgetDelegateView : public WidgetDelegate, public View { public: WidgetDelegateView(); virtual ~WidgetDelegateView(); // Overridden from WidgetDelegate: + virtual void DeleteDelegate() OVERRIDE; virtual Widget* GetWidget() OVERRIDE; virtual const Widget* GetWidget() const OVERRIDE; diff --git a/ui/views/widget/widget_unittest.cc b/ui/views/widget/widget_unittest.cc index f42b877..6e6ed07 100644 --- a/ui/views/widget/widget_unittest.cc +++ b/ui/views/widget/widget_unittest.cc @@ -827,6 +827,29 @@ TEST_F(WidgetOwnershipTest, EXPECT_TRUE(state.native_widget_deleted); } +// Widget owns its NativeWidget and has a WidgetDelegateView as its contents. +TEST_F(WidgetOwnershipTest, + Ownership_WidgetOwnsNativeWidgetWithWithWidgetDelegateView) { + OwnershipTestState state; + + WidgetDelegateView* delegate_view = new WidgetDelegateView; + + scoped_ptr<Widget> widget(new OwnershipTestWidget(&state)); + Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP); + params.native_widget = + new OwnershipTestNativeWidgetPlatform(widget.get(), &state); + params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; + params.delegate = delegate_view; + widget->Init(params); + widget->SetContentsView(delegate_view); + + // Now delete the Widget. There should be no crash or use-after-free. + widget.reset(); + + EXPECT_TRUE(state.widget_deleted); + EXPECT_TRUE(state.native_widget_deleted); +} + //////////////////////////////////////////////////////////////////////////////// // Widget observer tests. // @@ -903,7 +926,6 @@ class WidgetObserverTest : public WidgetTest, public WidgetObserver { const Widget* widget_bounds_changed() const { return widget_bounds_changed_; } private: - Widget* active_; Widget* widget_closed_; diff --git a/ui/views/window/dialog_delegate.cc b/ui/views/window/dialog_delegate.cc index 33a1b9a..711554d 100644 --- a/ui/views/window/dialog_delegate.cc +++ b/ui/views/window/dialog_delegate.cc @@ -151,7 +151,10 @@ ui::AccessibilityTypes::Role DialogDelegate::GetAccessibleWindowRole() const { //////////////////////////////////////////////////////////////////////////////// // DialogDelegateView: -DialogDelegateView::DialogDelegateView() {} +DialogDelegateView::DialogDelegateView() { + // A WidgetDelegate should be deleted on DeleteDelegate. + set_owned_by_client(); +} DialogDelegateView::~DialogDelegateView() {} @@ -162,6 +165,10 @@ Widget* DialogDelegateView::CreateDialogWidget(DialogDelegateView* dialog, return CreateDialogWidgetImpl(dialog, context, parent); } +void DialogDelegateView::DeleteDelegate() { + delete this; +} + Widget* DialogDelegateView::GetWidget() { return View::GetWidget(); } diff --git a/ui/views/window/dialog_delegate.h b/ui/views/window/dialog_delegate.h index 01ef5eb..389f210 100644 --- a/ui/views/window/dialog_delegate.h +++ b/ui/views/window/dialog_delegate.h @@ -112,7 +112,8 @@ class VIEWS_EXPORT DialogDelegate : public WidgetDelegate { // A DialogDelegate implementation that is-a View. Used to override GetWidget() // to call View's GetWidget() for the common case where a DialogDelegate -// implementation is-a View. +// implementation is-a View. Note that DialogDelegateView is not owned by +// view's hierarchy and is expected to be deleted on DeleteDelegate call. class VIEWS_EXPORT DialogDelegateView : public DialogDelegate, public View { public: @@ -125,6 +126,7 @@ class VIEWS_EXPORT DialogDelegateView : public DialogDelegate, gfx::NativeWindow parent); // Overridden from DialogDelegate: + virtual void DeleteDelegate() OVERRIDE; virtual Widget* GetWidget() OVERRIDE; virtual const Widget* GetWidget() const OVERRIDE; virtual View* GetContentsView() OVERRIDE; |