#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/base/hit_test.h"
#include "ui/events/event_utils.h"
#include "ui/gfx/native_widget_types.h"
#include "ui/gfx/point.h"
return widget->IsFullscreen() ? ui::SHOW_STATE_FULLSCREEN :
widget->IsMaximized() ? ui::SHOW_STATE_MAXIMIZED :
widget->IsMinimized() ? ui::SHOW_STATE_MINIMIZED :
- ui::SHOW_STATE_NORMAL;
+ widget->IsActive() ? ui::SHOW_STATE_NORMAL :
+ ui::SHOW_STATE_INACTIVE;
}
TEST_F(WidgetTest, WidgetInitParams) {
- ASSERT_FALSE(views_delegate().UseTransparentWindows());
-
// Widgets are not transparent by default.
Widget::InitParams init1;
EXPECT_EQ(Widget::InitParams::INFER_OPACITY, init1.opacity);
-
- // Non-window widgets are not transparent either.
- Widget::InitParams init2(Widget::InitParams::TYPE_MENU);
- EXPECT_EQ(Widget::InitParams::INFER_OPACITY, init2.opacity);
-
- // A ViewsDelegate can set windows transparent by default.
- views_delegate().SetUseTransparentWindows(true);
- Widget::InitParams init3;
- EXPECT_EQ(Widget::InitParams::TRANSLUCENT_WINDOW, init3.opacity);
-
- // Non-window widgets stay opaque.
- Widget::InitParams init4(Widget::InitParams::TYPE_MENU);
- EXPECT_EQ(Widget::InitParams::INFER_OPACITY, init4.opacity);
}
////////////////////////////////////////////////////////////////////////////////
// |child| should be automatically destroyed with |toplevel|.
}
-#if defined(OS_WIN) && !defined(USE_AURA)
-// On Windows, it is possible to have child window that are TYPE_POPUP. Unlike
-// regular child windows, these should be created as hidden and must be shown
-// explicitly.
-TEST_F(WidgetTest, Visibility_ChildPopup) {
- Widget* toplevel = CreateTopLevelPlatformWidget();
- Widget* child_popup = CreateChildPopupPlatformWidget(
- toplevel->GetNativeView());
-
- EXPECT_FALSE(toplevel->IsVisible());
- EXPECT_FALSE(child_popup->IsVisible());
-
- toplevel->Show();
-
- EXPECT_TRUE(toplevel->IsVisible());
- EXPECT_FALSE(child_popup->IsVisible());
-
- child_popup->Show();
-
- EXPECT_TRUE(child_popup->IsVisible());
-
- toplevel->CloseNow();
- // |child_popup| should be automatically destroyed with |toplevel|.
-}
-#endif
-
////////////////////////////////////////////////////////////////////////////////
// Widget ownership tests.
//
widget->StackAtTop();
widget->IsClosed();
widget->Close();
- widget->Show();
widget->Hide();
widget->Activate();
widget->Deactivate();
// widget->CenterWindow(gfx::Size(50, 60));
// widget->GetRestoredBounds();
// widget->ShowInactive();
+ // widget->Show();
}
private:
View* container = toplevel->client_view();
Textfield* textfield = new Textfield();
- textfield->SetText(ASCIIToUTF16("some text"));
+ textfield->SetText(base::ASCIIToUTF16("some text"));
container->AddChildView(textfield);
toplevel->Show();
textfield->RequestFocus();
TEST_F(WidgetTest, DISABLED_FocusChangesOnBubble) {
// Create a widget, show and activate it and focus the contents view.
View* contents_view = new View;
- contents_view->set_focusable(true);
+ contents_view->SetFocusable(true);
Widget widget;
Widget::InitParams init_params =
CreateParams(Widget::InitParams::TYPE_WINDOW_FRAMELESS);
// Show a bubble.
BubbleDelegateView* bubble_delegate_view =
new BubbleDelegateView(contents_view, BubbleBorder::TOP_LEFT);
- bubble_delegate_view->set_focusable(true);
+ bubble_delegate_view->SetFocusable(true);
BubbleDelegateView::CreateBubble(bubble_delegate_view)->Show();
bubble_delegate_view->RequestFocus();
EXPECT_TRUE(contents_view->HasFocus());
}
+class TestBubbleDelegateView : public BubbleDelegateView {
+ public:
+ TestBubbleDelegateView(View* anchor)
+ : BubbleDelegateView(anchor, BubbleBorder::NONE),
+ reset_controls_called_(false) {}
+ virtual ~TestBubbleDelegateView() {}
+
+ virtual bool ShouldShowCloseButton() const OVERRIDE {
+ reset_controls_called_ = true;
+ return true;
+ }
+
+ mutable bool reset_controls_called_;
+};
+
+TEST_F(WidgetTest, BubbleControlsResetOnInit) {
+ Widget* anchor = CreateTopLevelPlatformWidget();
+ anchor->Show();
+
+ TestBubbleDelegateView* bubble_delegate =
+ new TestBubbleDelegateView(anchor->client_view());
+ Widget* bubble_widget(BubbleDelegateView::CreateBubble(bubble_delegate));
+ EXPECT_TRUE(bubble_delegate->reset_controls_called_);
+ bubble_widget->Show();
+ bubble_widget->CloseNow();
+
+ anchor->Hide();
+ anchor->CloseNow();
+}
+
// Desktop native widget Aura tests are for non Chrome OS platforms.
#if !defined(OS_CHROMEOS)
// Test to ensure that after minimize, view width is set to zero.
TEST_F(WidgetTest, DesktopNativeWidgetAuraNoPaintAfterCloseTest) {
View* contents_view = new View;
- contents_view->set_focusable(true);
+ contents_view->SetFocusable(true);
DesktopAuraTestValidPaintWidget widget;
Widget::InitParams init_params =
CreateParams(Widget::InitParams::TYPE_WINDOW_FRAMELESS);
TEST_F(WidgetTest, DesktopNativeWidgetAuraNoPaintAfterHideTest) {
View* contents_view = new View;
- contents_view->set_focusable(true);
+ contents_view->SetFocusable(true);
DesktopAuraTestValidPaintWidget widget;
Widget::InitParams init_params =
CreateParams(Widget::InitParams::TYPE_WINDOW_FRAMELESS);
init_params.type = Widget::InitParams::TYPE_WINDOW;
init_params.bounds = bounds;
init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
- init_params.layer_type = ui::LAYER_NOT_DRAWN;
+ init_params.layer_type = aura::WINDOW_LAYER_NOT_DRAWN;
init_params.accept_events = fullscreen;
widget_.Init(init_params);
owned_window_ = new aura::Window(&child_window_delegate_);
- owned_window_->SetType(aura::client::WINDOW_TYPE_NORMAL);
+ owned_window_->SetType(ui::wm::WINDOW_TYPE_NORMAL);
owned_window_->SetName("TestTopLevelWindow");
if (fullscreen) {
owned_window_->SetProperty(aura::client::kShowStateKey,
ui::SHOW_STATE_FULLSCREEN);
} else {
- owned_window_->SetType(aura::client::WINDOW_TYPE_MENU);
+ owned_window_->SetType(ui::wm::WINDOW_TYPE_MENU);
}
- owned_window_->Init(ui::LAYER_TEXTURED);
+ owned_window_->Init(aura::WINDOW_LAYER_TEXTURED);
aura::client::ParentWindowWithContext(
owned_window_,
widget_.GetNativeView()->GetRootWindow(),
}
}
+ aura::Window* owned_window() {
+ return owned_window_;
+ }
+
+ views::Widget* top_level_widget() {
+ return top_level_widget_;
+ }
+
private:
views::Widget widget_;
views::Widget* top_level_widget_;
RunPendingMessages();
}
-// TODO(erg): Disabled on desktop linux until http://crbug.com/288988 is fixed.
-#if !defined(OS_LINUX)
TEST_F(WidgetTest, DesktopAuraTopLevelOwnedPopupTest) {
ViewsDelegate::views_delegate = NULL;
DesktopAuraTopLevelWindowTest popup_window;
ASSERT_NO_FATAL_FAILURE(popup_window.DestroyOwnedWindow());
RunPendingMessages();
}
-#endif
+
+// This test validates that when a top level owned popup Aura window is
+// resized, the widget is resized as well.
+TEST_F(WidgetTest, DesktopAuraTopLevelOwnedPopupResizeTest) {
+ ViewsDelegate::views_delegate = NULL;
+ DesktopAuraTopLevelWindowTest popup_window;
+ ASSERT_NO_FATAL_FAILURE(popup_window.CreateTopLevelWindow(
+ gfx::Rect(0, 0, 200, 200), false));
+
+ gfx::Rect new_size(0, 0, 400, 400);
+ popup_window.owned_window()->SetBounds(new_size);
+
+ EXPECT_EQ(popup_window.top_level_widget()->GetNativeView()->bounds().size(),
+ new_size.size());
+ RunPendingMessages();
+ ASSERT_NO_FATAL_FAILURE(popup_window.DestroyOwnedWindow());
+ RunPendingMessages();
+}
// Test to ensure that the aura Window's visiblity state is set to visible if
// the underlying widget is hidden and then shown.
void GenerateMouseEvents(Widget* widget, ui::EventType last_event_type) {
const gfx::Rect screen_bounds(widget->GetWindowBoundsInScreen());
ui::MouseEvent move_event(ui::ET_MOUSE_MOVED, screen_bounds.CenterPoint(),
- screen_bounds.CenterPoint(), 0);
- aura::RootWindowHostDelegate* rwhd =
- widget->GetNativeWindow()->GetDispatcher()->AsRootWindowHostDelegate();
- rwhd->OnHostMouseEvent(&move_event);
- if (last_event_type == ui::ET_MOUSE_ENTERED)
+ screen_bounds.CenterPoint(), 0, 0);
+ aura::WindowEventDispatcher* dispatcher =
+ widget->GetNativeWindow()->GetDispatcher();
+ ui::EventDispatchDetails details = dispatcher->OnEventFromSource(&move_event);
+ if (last_event_type == ui::ET_MOUSE_ENTERED || details.dispatcher_destroyed)
return;
- rwhd->OnHostMouseEvent(&move_event);
- if (last_event_type == ui::ET_MOUSE_MOVED)
+ details = dispatcher->OnEventFromSource(&move_event);
+ if (last_event_type == ui::ET_MOUSE_MOVED || details.dispatcher_destroyed)
return;
ui::MouseEvent press_event(ui::ET_MOUSE_PRESSED, screen_bounds.CenterPoint(),
- screen_bounds.CenterPoint(), 0);
- rwhd->OnHostMouseEvent(&press_event);
- if (last_event_type == ui::ET_MOUSE_PRESSED)
+ screen_bounds.CenterPoint(), 0, 0);
+ details = dispatcher->OnEventFromSource(&press_event);
+ if (last_event_type == ui::ET_MOUSE_PRESSED || details.dispatcher_destroyed)
return;
gfx::Point end_point(screen_bounds.CenterPoint());
end_point.Offset(1, 1);
- ui::MouseEvent drag_event(ui::ET_MOUSE_DRAGGED, end_point, end_point, 0);
- rwhd->OnHostMouseEvent(&drag_event);
- if (last_event_type == ui::ET_MOUSE_DRAGGED)
+ ui::MouseEvent drag_event(ui::ET_MOUSE_DRAGGED, end_point, end_point, 0, 0);
+ details = dispatcher->OnEventFromSource(&drag_event);
+ if (last_event_type == ui::ET_MOUSE_DRAGGED || details.dispatcher_destroyed)
return;
- ui::MouseEvent release_event(ui::ET_MOUSE_RELEASED, end_point, end_point, 0);
- rwhd->OnHostMouseEvent(&release_event);
+ ui::MouseEvent release_event(ui::ET_MOUSE_RELEASED, end_point, end_point, 0,
+ 0);
+ details = dispatcher->OnEventFromSource(&release_event);
+ if (details.dispatcher_destroyed)
+ return;
}
// Creates a widget and invokes GenerateMouseEvents() with |last_event_type|.
gfx::Point cursor_location(5, 5);
ui::MouseEvent move(ui::ET_MOUSE_MOVED, cursor_location, cursor_location,
- ui::EF_NONE);
+ ui::EF_NONE, ui::EF_NONE);
widget->OnMouseEvent(&move);
EXPECT_EQ(1, v1->GetEventCount(ui::ET_MOUSE_ENTERED));
EXPECT_EQ(1, delegate->count());
}
+class WidgetWindowTitleTest : public WidgetTest {
+ protected:
+ void RunTest(bool desktop_native_widget) {
+ Widget* widget = new Widget(); // Destroyed by CloseNow() below.
+ Widget::InitParams init_params =
+ CreateParams(Widget::InitParams::TYPE_WINDOW);
+ widget->Init(init_params);
+
+#if defined(USE_AURA) && !defined(OS_CHROMEOS)
+ if (desktop_native_widget)
+ init_params.native_widget = new DesktopNativeWidgetAura(widget);
+#else
+ DCHECK(!desktop_native_widget)
+ << "DesktopNativeWidget does not exist on non-Aura or on ChromeOS.";
+#endif
+
+ internal::NativeWidgetPrivate* native_widget =
+ widget->native_widget_private();
+
+ base::string16 empty;
+ base::string16 s1(base::UTF8ToUTF16("Title1"));
+ base::string16 s2(base::UTF8ToUTF16("Title2"));
+ base::string16 s3(base::UTF8ToUTF16("TitleLong"));
+
+ // The widget starts with no title, setting empty should not change
+ // anything.
+ EXPECT_FALSE(native_widget->SetWindowTitle(empty));
+ // Setting the title to something non-empty should cause a change.
+ EXPECT_TRUE(native_widget->SetWindowTitle(s1));
+ // Setting the title to something else with the same length should cause a
+ // change.
+ EXPECT_TRUE(native_widget->SetWindowTitle(s2));
+ // Setting the title to something else with a different length should cause
+ // a change.
+ EXPECT_TRUE(native_widget->SetWindowTitle(s3));
+ // Setting the title to the same thing twice should not cause a change.
+ EXPECT_FALSE(native_widget->SetWindowTitle(s3));
+
+ widget->CloseNow();
+ }
+};
+
+TEST_F(WidgetWindowTitleTest, SetWindowTitleChanged_NativeWidget) {
+ // Use the default NativeWidget.
+ bool desktop_native_widget = false;
+ RunTest(desktop_native_widget);
+}
+
+// DesktopNativeWidget does not exist on non-Aura or on ChromeOS.
+#if defined(USE_AURA) && !defined(OS_CHROMEOS)
+TEST_F(WidgetWindowTitleTest, SetWindowTitleChanged_DesktopNativeWidget) {
+ // Override to use a DesktopNativeWidget.
+ bool desktop_native_widget = true;
+ RunTest(desktop_native_widget);
+}
+#endif // USE_AURA && !OS_CHROMEOS
+
// Used by SetTopLevelCorrectly to track calls to OnBeforeWidgetInit().
class VerifyTopLevelDelegate : public TestViewsDelegate {
public:
gfx::Point click_location(45, 15);
ui::MouseEvent press(ui::ET_MOUSE_PRESSED, click_location, click_location,
- ui::EF_LEFT_MOUSE_BUTTON);
+ ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON);
widget->OnMouseEvent(&press);
// Yay we did not crash!
EXPECT_EQ(NULL, GetMousePressedHandler(root_view));
gfx::Point click_location(45, 15);
ui::MouseEvent press(ui::ET_MOUSE_PRESSED, click_location, click_location,
- ui::EF_LEFT_MOUSE_BUTTON);
+ ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON);
widget->OnMouseEvent(&press);
EXPECT_EQ(view, GetMousePressedHandler(root_view));
widget->Hide();
widget->Show();
EXPECT_EQ(NULL, GetMouseMoveHandler(root_view));
gfx::Point move_location(45, 15);
- ui::MouseEvent move(ui::ET_MOUSE_MOVED, move_location, move_location, 0);
+ ui::MouseEvent move(ui::ET_MOUSE_MOVED, move_location, move_location, 0, 0);
widget->OnMouseEvent(&move);
EXPECT_EQ(view, GetMouseMoveHandler(root_view));
widget->Hide();
ui::MouseEvent move_main(ui::ET_MOUSE_MOVED,
cursor_location_main,
cursor_location_main,
+ ui::EF_NONE,
ui::EF_NONE);
- top_level_widget.GetNativeView()->GetDispatcher()->
- AsRootWindowHostDelegate()->OnHostMouseEvent(&move_main);
+ ui::EventDispatchDetails details = top_level_widget.GetNativeView()->
+ GetDispatcher()->OnEventFromSource(&move_main);
+ ASSERT_FALSE(details.dispatcher_destroyed);
EXPECT_EQ(1, widget_view->GetEventCount(ui::ET_MOUSE_ENTERED));
widget_view->ResetCounts();
ui::MouseEvent mouse_down_dialog(ui::ET_MOUSE_PRESSED,
cursor_location_dialog,
cursor_location_dialog,
+ ui::EF_NONE,
ui::EF_NONE);
- top_level_widget.GetNativeView()->GetDispatcher()->
- AsRootWindowHostDelegate()->OnHostMouseEvent(&mouse_down_dialog);
+ details = top_level_widget.GetNativeView()->GetDispatcher()->
+ OnEventFromSource(&mouse_down_dialog);
+ ASSERT_FALSE(details.dispatcher_destroyed);
EXPECT_EQ(1, dialog_widget_view->GetEventCount(ui::ET_MOUSE_PRESSED));
// Send a mouse move message to the main window. It should not be received by
ui::MouseEvent mouse_down_main(ui::ET_MOUSE_MOVED,
cursor_location_main2,
cursor_location_main2,
+ ui::EF_NONE,
ui::EF_NONE);
- top_level_widget.GetNativeView()->GetDispatcher()->
- AsRootWindowHostDelegate()->OnHostMouseEvent(&mouse_down_main);
+ details = top_level_widget.GetNativeView()->GetDispatcher()->
+ OnEventFromSource(&mouse_down_main);
+ ASSERT_FALSE(details.dispatcher_destroyed);
EXPECT_EQ(0, widget_view->GetEventCount(ui::ET_MOUSE_MOVED));
modal_dialog_widget->CloseNow();
top_level_widget.CloseNow();
}
+#if defined(USE_AURA)
+// Verifies nativeview visbility matches that of Widget visibility when
+// SetFullscreen is invoked.
+TEST_F(WidgetTest, FullscreenStatePropagated) {
+ Widget::InitParams init_params =
+ CreateParams(Widget::InitParams::TYPE_WINDOW);
+ init_params.show_state = ui::SHOW_STATE_NORMAL;
+ init_params.bounds = gfx::Rect(0, 0, 500, 500);
+ init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+
+ {
+ Widget top_level_widget;
+ top_level_widget.Init(init_params);
+ top_level_widget.SetFullscreen(true);
+ EXPECT_EQ(top_level_widget.IsVisible(),
+ top_level_widget.GetNativeView()->IsVisible());
+ top_level_widget.CloseNow();
+ }
+
+#if !defined(OS_CHROMEOS)
+ {
+ Widget top_level_widget;
+ init_params.native_widget = new DesktopNativeWidgetAura(&top_level_widget);
+ top_level_widget.Init(init_params);
+ top_level_widget.SetFullscreen(true);
+ EXPECT_EQ(top_level_widget.IsVisible(),
+ top_level_widget.GetNativeView()->IsVisible());
+ top_level_widget.CloseNow();
+ }
+#endif
+}
+#endif
+
#if defined(OS_WIN)
// Provides functionality to test widget activation via an activation flag
#endif
#endif
+TEST_F(WidgetTest, ShowCreatesActiveWindow) {
+ Widget* widget = CreateTopLevelPlatformWidget();
+
+ widget->Show();
+ EXPECT_EQ(GetWidgetShowState(widget), ui::SHOW_STATE_NORMAL);
+
+ widget->CloseNow();
+}
+
+TEST_F(WidgetTest, ShowInactive) {
+ Widget* widget = CreateTopLevelPlatformWidget();
+
+ widget->ShowInactive();
+ EXPECT_EQ(GetWidgetShowState(widget), ui::SHOW_STATE_INACTIVE);
+
+ widget->CloseNow();
+}
+
+TEST_F(WidgetTest, ShowInactiveAfterShow) {
+ Widget* widget = CreateTopLevelPlatformWidget();
+
+ widget->Show();
+ widget->ShowInactive();
+ EXPECT_EQ(GetWidgetShowState(widget), ui::SHOW_STATE_NORMAL);
+
+ widget->CloseNow();
+}
+
+TEST_F(WidgetTest, ShowAfterShowInactive) {
+ Widget* widget = CreateTopLevelPlatformWidget();
+
+ widget->ShowInactive();
+ widget->Show();
+ EXPECT_EQ(GetWidgetShowState(widget), ui::SHOW_STATE_NORMAL);
+
+ widget->CloseNow();
+}
+
+#if defined(USE_AURA) && !defined(OS_CHROMEOS)
+TEST_F(WidgetTest, InactiveWidgetDoesNotGrabActivation) {
+ Widget* widget = CreateTopLevelPlatformWidget();
+ widget->Show();
+ EXPECT_EQ(GetWidgetShowState(widget), ui::SHOW_STATE_NORMAL);
+
+ Widget widget2;
+ Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
+ params.can_activate = false;
+ params.native_widget = new DesktopNativeWidgetAura(&widget2);
+ params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+ widget2.Init(params);
+ widget2.Show();
+
+ EXPECT_EQ(GetWidgetShowState(&widget2), ui::SHOW_STATE_INACTIVE);
+ EXPECT_EQ(GetWidgetShowState(widget), ui::SHOW_STATE_NORMAL);
+
+ widget->CloseNow();
+ widget2.CloseNow();
+}
+#endif
+
+namespace {
+
+class FullscreenAwareFrame : public views::NonClientFrameView {
+ public:
+ explicit FullscreenAwareFrame(views::Widget* widget)
+ : widget_(widget), fullscreen_layout_called_(false) {}
+ virtual ~FullscreenAwareFrame() {}
+
+ // views::NonClientFrameView overrides:
+ virtual gfx::Rect GetBoundsForClientView() const OVERRIDE {
+ return gfx::Rect();
+ }
+ virtual gfx::Rect GetWindowBoundsForClientBounds(
+ const gfx::Rect& client_bounds) const OVERRIDE {
+ return gfx::Rect();
+ }
+ virtual int NonClientHitTest(const gfx::Point& point) OVERRIDE {
+ return HTNOWHERE;
+ }
+ virtual void GetWindowMask(const gfx::Size& size,
+ gfx::Path* window_mask) OVERRIDE {}
+ virtual void ResetWindowControls() OVERRIDE {}
+ virtual void UpdateWindowIcon() OVERRIDE {}
+ virtual void UpdateWindowTitle() OVERRIDE {}
+
+ // views::View overrides:
+ virtual void Layout() OVERRIDE {
+ if (widget_->IsFullscreen())
+ fullscreen_layout_called_ = true;
+ }
+
+ bool fullscreen_layout_called() const { return fullscreen_layout_called_; }
+
+ private:
+ views::Widget* widget_;
+ bool fullscreen_layout_called_;
+
+ DISALLOW_COPY_AND_ASSIGN(FullscreenAwareFrame);
+};
+
+} // namespace
+
+// Tests that frame Layout is called when a widget goes fullscreen without
+// changing its size or title.
+TEST_F(WidgetTest, FullscreenFrameLayout) {
+ Widget* widget = CreateTopLevelPlatformWidget();
+ FullscreenAwareFrame* frame = new FullscreenAwareFrame(widget);
+ widget->non_client_view()->SetFrameView(frame); // Owns |frame|.
+
+ widget->Maximize();
+ RunPendingMessages();
+
+ EXPECT_FALSE(frame->fullscreen_layout_called());
+ widget->SetFullscreen(true);
+ widget->Show();
+ RunPendingMessages();
+ EXPECT_TRUE(frame->fullscreen_layout_called());
+
+ widget->CloseNow();
+}
+
+#if !defined(OS_CHROMEOS)
+namespace {
+
+// Trivial WidgetObserverTest that invokes Widget::IsActive() from
+// OnWindowDestroying.
+class IsActiveFromDestroyObserver : public WidgetObserver {
+ public:
+ IsActiveFromDestroyObserver() {}
+ virtual ~IsActiveFromDestroyObserver() {}
+ virtual void OnWidgetDestroying(Widget* widget) OVERRIDE {
+ widget->IsActive();
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(IsActiveFromDestroyObserver);
+};
+
+} // namespace
+
+// Verifies Widget::IsActive() invoked from
+// WidgetObserver::OnWidgetDestroying() in a child widget doesn't crash.
+TEST_F(WidgetTest, IsActiveFromDestroy) {
+ // Create two widgets, one a child of the other.
+ IsActiveFromDestroyObserver observer;
+ Widget parent_widget;
+ Widget::InitParams parent_params =
+ CreateParams(Widget::InitParams::TYPE_POPUP);
+ parent_params.native_widget = new DesktopNativeWidgetAura(&parent_widget);
+ parent_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+ parent_widget.Init(parent_params);
+ parent_widget.Show();
+
+ Widget child_widget;
+ Widget::InitParams child_params =
+ CreateParams(Widget::InitParams::TYPE_POPUP);
+ child_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+ child_params.context = parent_widget.GetNativeView();
+ child_widget.Init(child_params);
+ child_widget.AddObserver(&observer);
+ child_widget.Show();
+
+ parent_widget.CloseNow();
+}
+#endif
+
} // namespace test
} // namespace views