Chromium Code Reviews| 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..ec0cd890076a3fff9a7a8925a7df342a9d0f6c43 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), |
| + destroy_on_message_(0) { |
| EXPECT_EQ(instance_, nullptr); |
| instance_ = this; |
| EXPECT_TRUE(Subclass()); |
| @@ -3233,6 +3234,10 @@ class SubclassWindowHelper { |
| messages_.clear(); |
| } |
| + void set_destroy_on_message(unsigned int message) { |
| + destroy_on_message_ = message; |
| + } |
| + |
| private: |
| bool Subclass() { |
| old_proc_ = reinterpret_cast<WNDPROC>( |
| @@ -3258,14 +3263,21 @@ 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 (instance_->destroy_on_message_ && |
|
sky
2016/01/27 03:14:30
Is there a reason for this check? Doesn't the next
ananta
2016/01/27 21:23:31
Yeah. Wrote that thinking about WM_NULL. Not neede
|
| + message == instance_->destroy_on_message_) { |
| + instance_->Unsubclass(); |
| + ::DestroyWindow(window); |
| + } |
| + return ret; |
| } |
| WNDPROC old_proc_; |
| HWND window_; |
| static SubclassWindowHelper* instance_; |
| std::set<unsigned int> messages_; |
| + unsigned int destroy_on_message_; |
|
sky
2016/01/27 03:14:30
nit: I first took this to mean destroy on any mess
ananta
2016/01/27 21:23:31
Done.
|
| DISALLOW_COPY_AND_ASSIGN(SubclassWindowHelper); |
| }; |
| @@ -3347,6 +3359,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_destroy_on_message(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. |