| Index: ui/views/widget/widget_unittest.cc
|
| diff --git a/ui/views/widget/widget_unittest.cc b/ui/views/widget/widget_unittest.cc
|
| index 41bbe8198d7b40b9136deaf3ae068bb795c3be87..57235012eee16f786ca0c6d8b49c0f1c7aca4366 100644
|
| --- a/ui/views/widget/widget_unittest.cc
|
| +++ b/ui/views/widget/widget_unittest.cc
|
| @@ -3213,7 +3213,8 @@ TEST_F(WidgetTest, CharMessagesAsKeyboardMessagesDoesNotCrash) {
|
| class SubclassWindowHelper {
|
| public:
|
| explicit SubclassWindowHelper(HWND window)
|
| - : window_(window) {
|
| + : window_(window),
|
| + message_to_destroy_on_(0) {
|
| EXPECT_EQ(instance_, nullptr);
|
| instance_ = this;
|
| EXPECT_TRUE(Subclass());
|
| @@ -3233,6 +3234,10 @@ class SubclassWindowHelper {
|
| messages_.clear();
|
| }
|
|
|
| + void set_message_to_destroy_on(unsigned int message) {
|
| + message_to_destroy_on_ = message;
|
| + }
|
| +
|
| private:
|
| bool Subclass() {
|
| old_proc_ = reinterpret_cast<WNDPROC>(
|
| @@ -3258,14 +3263,20 @@ class SubclassWindowHelper {
|
| // Keep track of messags received for this window.
|
| instance_->messages_.insert(message);
|
|
|
| - return ::CallWindowProc(instance_->old_proc_, window, message, w_param,
|
| - l_param);
|
| + LRESULT ret = ::CallWindowProc(instance_->old_proc_, window, message,
|
| + w_param, l_param);
|
| + if (message == instance_->message_to_destroy_on_) {
|
| + instance_->Unsubclass();
|
| + ::DestroyWindow(window);
|
| + }
|
| + return ret;
|
| }
|
|
|
| WNDPROC old_proc_;
|
| HWND window_;
|
| static SubclassWindowHelper* instance_;
|
| std::set<unsigned int> messages_;
|
| + unsigned int message_to_destroy_on_;
|
|
|
| DISALLOW_COPY_AND_ASSIGN(SubclassWindowHelper);
|
| };
|
| @@ -3347,6 +3358,38 @@ TEST_F(WidgetTest, SysCommandMoveOnNCLButtonDownOnCaptionAndMoveTest) {
|
|
|
| widget.CloseNow();
|
| }
|
| +
|
| +// This test validates that destroying the window in the context of the
|
| +// WM_SYSCOMMAND message with SC_MOVE does not crash.
|
| +TEST_F(WidgetTest, DestroyInSysCommandNCLButtonDownOnCaption) {
|
| + Widget widget;
|
| + Widget::InitParams params =
|
| + CreateParams(Widget::InitParams::TYPE_WINDOW);
|
| + params.native_widget = new PlatformDesktopNativeWidget(&widget);
|
| + params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
|
| + widget.Init(params);
|
| + widget.SetBounds(gfx::Rect(0, 0, 200, 200));
|
| + widget.Show();
|
| + ::SetCursorPos(500, 500);
|
| +
|
| + HWND window = widget.GetNativeWindow()->GetHost()->GetAcceleratedWidget();
|
| +
|
| + SubclassWindowHelper subclass_helper(window);
|
| +
|
| + // Destroying the window in the context of the WM_SYSCOMMAND message
|
| + // should not crash.
|
| + subclass_helper.set_message_to_destroy_on(WM_SYSCOMMAND);
|
| +
|
| + ::PostMessage(window, WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(100, 100));
|
| + ::PostMessage(window, WM_NCMOUSEMOVE, HTCAPTION, MAKELPARAM(110, 110));
|
| + RunPendingMessages();
|
| +
|
| + EXPECT_TRUE(subclass_helper.received_message(WM_NCLBUTTONDOWN));
|
| + EXPECT_TRUE(subclass_helper.received_message(WM_SYSCOMMAND));
|
| +
|
| + widget.CloseNow();
|
| +}
|
| +
|
| #endif
|
|
|
| // Test that SetAlwaysOnTop and IsAlwaysOnTop are consistent.
|
|
|