Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "ui/views/widget/root_view.h" | 5 #include "ui/views/widget/root_view.h" |
| 6 | 6 |
| 7 #include "ui/events/event_utils.h" | |
| 7 #include "ui/views/context_menu_controller.h" | 8 #include "ui/views/context_menu_controller.h" |
| 8 #include "ui/views/test/views_test_base.h" | 9 #include "ui/views/test/views_test_base.h" |
| 9 #include "ui/views/view_targeter.h" | 10 #include "ui/views/view_targeter.h" |
| 10 #include "ui/views/widget/root_view.h" | 11 #include "ui/views/widget/root_view.h" |
| 11 | 12 |
| 12 namespace views { | 13 namespace views { |
| 13 namespace test { | 14 namespace test { |
| 14 | 15 |
| 15 typedef ViewsTestBase RootViewTest; | 16 typedef ViewsTestBase RootViewTest; |
| 16 | 17 |
| (...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 330 | 331 |
| 331 ui::GestureEvent end3( | 332 ui::GestureEvent end3( |
| 332 25, 5, 0, base::TimeDelta(), ui::GestureEventDetails(ui::ET_GESTURE_END)); | 333 25, 5, 0, base::TimeDelta(), ui::GestureEventDetails(ui::ET_GESTURE_END)); |
| 333 details = root_view->OnEventFromSource(&end3); | 334 details = root_view->OnEventFromSource(&end3); |
| 334 | 335 |
| 335 EXPECT_FALSE(details.target_destroyed); | 336 EXPECT_FALSE(details.target_destroyed); |
| 336 EXPECT_FALSE(details.dispatcher_destroyed); | 337 EXPECT_FALSE(details.dispatcher_destroyed); |
| 337 EXPECT_EQ(0, controller.show_context_menu_calls()); | 338 EXPECT_EQ(0, controller.show_context_menu_calls()); |
| 338 } | 339 } |
| 339 | 340 |
| 341 // This view class provides functionality to delete itself in the context of | |
| 342 // mouse exit event and helps test that we don't crash when we return from | |
| 343 // the mouse exit handler. | |
| 344 class DeleteViewOnMouseExit : public View { | |
| 345 public: | |
| 346 explicit DeleteViewOnMouseExit(bool* got_mouse_exit) | |
| 347 : got_mouse_exit_(got_mouse_exit) { | |
| 348 } | |
| 349 | |
| 350 ~DeleteViewOnMouseExit() override {} | |
| 351 | |
| 352 void OnMouseExited(const ui::MouseEvent& event) override { | |
| 353 *got_mouse_exit_ = true; | |
| 354 delete this; | |
| 355 } | |
| 356 | |
| 357 private: | |
| 358 // Set to true in OnMouseExited(). | |
| 359 bool* got_mouse_exit_; | |
| 360 | |
| 361 DISALLOW_COPY_AND_ASSIGN(DeleteViewOnMouseExit); | |
| 362 }; | |
| 363 | |
| 364 // Verifies deleting a View in OnMouseExited() doesn't crash. | |
| 365 TEST_F(RootViewTest, DeleteViewOnMouseExitDispatch) { | |
| 366 Widget widget; | |
| 367 Widget::InitParams init_params = | |
| 368 CreateParams(Widget::InitParams::TYPE_POPUP); | |
| 369 init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; | |
| 370 widget.Init(init_params); | |
| 371 widget.SetBounds(gfx::Rect(10, 10, 500, 500)); | |
| 372 | |
| 373 View* content = new View; | |
| 374 widget.SetContentsView(content); | |
| 375 | |
| 376 bool got_mouse_exit = false; | |
| 377 View* child = new DeleteViewOnMouseExit(&got_mouse_exit); | |
| 378 content->AddChildView(child); | |
| 379 child->SetBounds(10, 10, 500, 500); | |
| 380 | |
| 381 child->SetFocusable(true); | |
| 382 child->RequestFocus(); | |
|
sadrul
2015/03/18 22:30:00
Don't need focus, right?
ananta
2015/03/19 00:02:55
Done.
| |
| 383 | |
| 384 internal::RootView* root_view = | |
| 385 static_cast<internal::RootView*>(widget.GetRootView()); | |
| 386 | |
| 387 // Generate a mouse move event which ensures that the mouse_moved_handler_ | |
| 388 // member is set in the RootView class. | |
| 389 ui::MouseEvent moved_event(ui::ET_MOUSE_MOVED, gfx::Point(15, 15), | |
| 390 gfx::Point(100, 100), ui::EventTimeForNow(), 0, | |
| 391 0); | |
| 392 root_view->OnMouseMoved(moved_event); | |
|
sadrul
2015/03/18 22:30:00
EXPECT_FALSE here that !got_mouse_exit?
ananta
2015/03/19 00:02:55
Done.
| |
| 393 | |
| 394 // Generate a mouse exit event which in turn will delete the child view which | |
| 395 // was the target of the mouse move event above. This should not crash when | |
| 396 // the mouse exit handler returns from the child. | |
| 397 ui::MouseEvent exit_event(ui::ET_MOUSE_EXITED, gfx::Point(), gfx::Point(), | |
| 398 ui::EventTimeForNow(), 0, 0); | |
| 399 root_view->OnMouseExited(exit_event); | |
| 400 | |
| 401 EXPECT_TRUE(got_mouse_exit); | |
|
sadrul
2015/03/18 22:30:00
Also check that content->has_children() == false?
ananta
2015/03/19 00:02:55
Done.
| |
| 402 } | |
| 403 | |
| 340 } // namespace test | 404 } // namespace test |
| 341 } // namespace views | 405 } // namespace views |
| OLD | NEW |