Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(70)

Side by Side Diff: ui/views/widget/widget_unittest.cc

Issue 1636183003: Fix crash in the HWNDMessageHandler::HandleMouseInputForCaption function. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Added views_unittest DestroyInSysCommandNCLButtonDownOnCaption, which verifies that we don't crash … Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | ui/views/win/hwnd_message_handler.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <algorithm> 5 #include <algorithm>
6 #include <set> 6 #include <set>
7 7
8 #include "base/bind.h" 8 #include "base/bind.h"
9 #include "base/macros.h" 9 #include "base/macros.h"
10 #include "base/memory/scoped_ptr.h" 10 #include "base/memory/scoped_ptr.h"
(...skipping 3195 matching lines...) Expand 10 before | Expand all | Expand 10 after
3206 target->HandleKeyboardMessage(WM_SYSCHAR, 0, 0, &handled); 3206 target->HandleKeyboardMessage(WM_SYSCHAR, 0, 0, &handled);
3207 target->HandleKeyboardMessage(WM_SYSDEADCHAR, 0, 0, &handled); 3207 target->HandleKeyboardMessage(WM_SYSDEADCHAR, 0, 0, &handled);
3208 widget.CloseNow(); 3208 widget.CloseNow();
3209 } 3209 }
3210 3210
3211 // Provides functionality to subclass a window and keep track of messages 3211 // Provides functionality to subclass a window and keep track of messages
3212 // received. 3212 // received.
3213 class SubclassWindowHelper { 3213 class SubclassWindowHelper {
3214 public: 3214 public:
3215 explicit SubclassWindowHelper(HWND window) 3215 explicit SubclassWindowHelper(HWND window)
3216 : window_(window) { 3216 : window_(window),
3217 destroy_on_message_(0) {
3217 EXPECT_EQ(instance_, nullptr); 3218 EXPECT_EQ(instance_, nullptr);
3218 instance_ = this; 3219 instance_ = this;
3219 EXPECT_TRUE(Subclass()); 3220 EXPECT_TRUE(Subclass());
3220 } 3221 }
3221 3222
3222 ~SubclassWindowHelper() { 3223 ~SubclassWindowHelper() {
3223 Unsubclass(); 3224 Unsubclass();
3224 instance_ = nullptr; 3225 instance_ = nullptr;
3225 } 3226 }
3226 3227
3227 // Returns true if the |message| passed in was received. 3228 // Returns true if the |message| passed in was received.
3228 bool received_message(unsigned int message) { 3229 bool received_message(unsigned int message) {
3229 return (messages_.find(message) != messages_.end()); 3230 return (messages_.find(message) != messages_.end());
3230 } 3231 }
3231 3232
3232 void Clear() { 3233 void Clear() {
3233 messages_.clear(); 3234 messages_.clear();
3234 } 3235 }
3235 3236
3237 void set_destroy_on_message(unsigned int message) {
3238 destroy_on_message_ = message;
3239 }
3240
3236 private: 3241 private:
3237 bool Subclass() { 3242 bool Subclass() {
3238 old_proc_ = reinterpret_cast<WNDPROC>( 3243 old_proc_ = reinterpret_cast<WNDPROC>(
3239 ::SetWindowLongPtr(window_, 3244 ::SetWindowLongPtr(window_,
3240 GWLP_WNDPROC, 3245 GWLP_WNDPROC,
3241 reinterpret_cast<LONG_PTR>(WndProc))); 3246 reinterpret_cast<LONG_PTR>(WndProc)));
3242 return old_proc_ != nullptr; 3247 return old_proc_ != nullptr;
3243 } 3248 }
3244 3249
3245 void Unsubclass() { 3250 void Unsubclass() {
3246 ::SetWindowLongPtr(window_, 3251 ::SetWindowLongPtr(window_,
3247 GWLP_WNDPROC, 3252 GWLP_WNDPROC,
3248 reinterpret_cast<LONG_PTR>(old_proc_)); 3253 reinterpret_cast<LONG_PTR>(old_proc_));
3249 } 3254 }
3250 3255
3251 static LRESULT CALLBACK WndProc(HWND window, 3256 static LRESULT CALLBACK WndProc(HWND window,
3252 unsigned int message, 3257 unsigned int message,
3253 WPARAM w_param, 3258 WPARAM w_param,
3254 LPARAM l_param) { 3259 LPARAM l_param) {
3255 EXPECT_NE(instance_, nullptr); 3260 EXPECT_NE(instance_, nullptr);
3256 EXPECT_EQ(window, instance_->window_); 3261 EXPECT_EQ(window, instance_->window_);
3257 3262
3258 // Keep track of messags received for this window. 3263 // Keep track of messags received for this window.
3259 instance_->messages_.insert(message); 3264 instance_->messages_.insert(message);
3260 3265
3261 return ::CallWindowProc(instance_->old_proc_, window, message, w_param, 3266 LRESULT ret = ::CallWindowProc(instance_->old_proc_, window, message,
3262 l_param); 3267 w_param, l_param);
3268 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
3269 message == instance_->destroy_on_message_) {
3270 instance_->Unsubclass();
3271 ::DestroyWindow(window);
3272 }
3273 return ret;
3263 } 3274 }
3264 3275
3265 WNDPROC old_proc_; 3276 WNDPROC old_proc_;
3266 HWND window_; 3277 HWND window_;
3267 static SubclassWindowHelper* instance_; 3278 static SubclassWindowHelper* instance_;
3268 std::set<unsigned int> messages_; 3279 std::set<unsigned int> messages_;
3280 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.
3269 3281
3270 DISALLOW_COPY_AND_ASSIGN(SubclassWindowHelper); 3282 DISALLOW_COPY_AND_ASSIGN(SubclassWindowHelper);
3271 }; 3283 };
3272 3284
3273 SubclassWindowHelper* SubclassWindowHelper::instance_ = nullptr; 3285 SubclassWindowHelper* SubclassWindowHelper::instance_ = nullptr;
3274 3286
3275 // This test validates whether the WM_SYSCOMMAND message for SC_MOVE is 3287 // This test validates whether the WM_SYSCOMMAND message for SC_MOVE is
3276 // received when we post a WM_NCLBUTTONDOWN message for the caption in the 3288 // received when we post a WM_NCLBUTTONDOWN message for the caption in the
3277 // following scenarios:- 3289 // following scenarios:-
3278 // 1. Posting a WM_NCMOUSEMOVE message for a different location. 3290 // 1. Posting a WM_NCMOUSEMOVE message for a different location.
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
3340 ::PostMessage(window, WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(100, 100)); 3352 ::PostMessage(window, WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(100, 100));
3341 ::PostMessage(window, WM_MOUSEMOVE, HTCLIENT, MAKELPARAM(110, 110)); 3353 ::PostMessage(window, WM_MOUSEMOVE, HTCLIENT, MAKELPARAM(110, 110));
3342 RunPendingMessages(); 3354 RunPendingMessages();
3343 3355
3344 EXPECT_TRUE(subclass_helper.received_message(WM_NCLBUTTONDOWN)); 3356 EXPECT_TRUE(subclass_helper.received_message(WM_NCLBUTTONDOWN));
3345 EXPECT_TRUE(subclass_helper.received_message(WM_MOUSEMOVE)); 3357 EXPECT_TRUE(subclass_helper.received_message(WM_MOUSEMOVE));
3346 EXPECT_TRUE(subclass_helper.received_message(WM_SYSCOMMAND)); 3358 EXPECT_TRUE(subclass_helper.received_message(WM_SYSCOMMAND));
3347 3359
3348 widget.CloseNow(); 3360 widget.CloseNow();
3349 } 3361 }
3362
3363 // This test validates that destroying the window in the context of the
3364 // WM_SYSCOMMAND message with SC_MOVE does not crash.
3365 TEST_F(WidgetTest, DestroyInSysCommandNCLButtonDownOnCaption) {
3366 Widget widget;
3367 Widget::InitParams params =
3368 CreateParams(Widget::InitParams::TYPE_WINDOW);
3369 params.native_widget = new PlatformDesktopNativeWidget(&widget);
3370 params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
3371 widget.Init(params);
3372 widget.SetBounds(gfx::Rect(0, 0, 200, 200));
3373 widget.Show();
3374 ::SetCursorPos(500, 500);
3375
3376 HWND window = widget.GetNativeWindow()->GetHost()->GetAcceleratedWidget();
3377
3378 SubclassWindowHelper subclass_helper(window);
3379
3380 // Destroying the window in the context of the WM_SYSCOMMAND message
3381 // should not crash.
3382 subclass_helper.set_destroy_on_message(WM_SYSCOMMAND);
3383
3384 ::PostMessage(window, WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(100, 100));
3385 ::PostMessage(window, WM_NCMOUSEMOVE, HTCAPTION, MAKELPARAM(110, 110));
3386 RunPendingMessages();
3387
3388 EXPECT_TRUE(subclass_helper.received_message(WM_NCLBUTTONDOWN));
3389 EXPECT_TRUE(subclass_helper.received_message(WM_SYSCOMMAND));
3390
3391 widget.CloseNow();
3392 }
3393
3350 #endif 3394 #endif
3351 3395
3352 // Test that SetAlwaysOnTop and IsAlwaysOnTop are consistent. 3396 // Test that SetAlwaysOnTop and IsAlwaysOnTop are consistent.
3353 TEST_F(WidgetTest, AlwaysOnTop) { 3397 TEST_F(WidgetTest, AlwaysOnTop) {
3354 WidgetAutoclosePtr widget(CreateTopLevelNativeWidget()); 3398 WidgetAutoclosePtr widget(CreateTopLevelNativeWidget());
3355 EXPECT_FALSE(widget->IsAlwaysOnTop()); 3399 EXPECT_FALSE(widget->IsAlwaysOnTop());
3356 widget->SetAlwaysOnTop(true); 3400 widget->SetAlwaysOnTop(true);
3357 EXPECT_TRUE(widget->IsAlwaysOnTop()); 3401 EXPECT_TRUE(widget->IsAlwaysOnTop());
3358 widget->SetAlwaysOnTop(false); 3402 widget->SetAlwaysOnTop(false);
3359 EXPECT_FALSE(widget->IsAlwaysOnTop()); 3403 EXPECT_FALSE(widget->IsAlwaysOnTop());
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
3396 EXPECT_EQ(scale_factor, view->last_scale_factor()); 3440 EXPECT_EQ(scale_factor, view->last_scale_factor());
3397 3441
3398 // Changes should be propagated. 3442 // Changes should be propagated.
3399 scale_factor *= 2.0f; 3443 scale_factor *= 2.0f;
3400 widget->GetLayer()->OnDeviceScaleFactorChanged(scale_factor); 3444 widget->GetLayer()->OnDeviceScaleFactorChanged(scale_factor);
3401 EXPECT_EQ(scale_factor, view->last_scale_factor()); 3445 EXPECT_EQ(scale_factor, view->last_scale_factor());
3402 } 3446 }
3403 3447
3404 } // namespace test 3448 } // namespace test
3405 } // namespace views 3449 } // namespace views
OLDNEW
« no previous file with comments | « no previous file | ui/views/win/hwnd_message_handler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698