summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ash/desktop_background/desktop_background_view.h3
-rw-r--r--ash/launcher/launcher.cc4
-rw-r--r--ash/shell/window_type_launcher.cc2
-rw-r--r--chrome/browser/chromeos/login/webui_login_view.h2
-rw-r--r--ui/oak/oak_window.cc1
-rw-r--r--ui/views/test/child_modal_window.cc2
-rw-r--r--ui/views/widget/widget_delegate.cc6
-rw-r--r--ui/views/widget/widget_delegate.h4
-rw-r--r--ui/views/widget/widget_unittest.cc24
-rw-r--r--ui/views/window/dialog_delegate.cc9
-rw-r--r--ui/views/window/dialog_delegate.h4
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;