OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/controls/menu/menu_controller.h" | 5 #include "ui/views/controls/menu/menu_controller.h" |
6 | 6 |
7 #include "base/callback.h" | 7 #include "base/callback.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "base/macros.h" | 9 #include "base/macros.h" |
| 10 #include "base/run_loop.h" |
10 #include "base/single_thread_task_runner.h" | 11 #include "base/single_thread_task_runner.h" |
11 #include "base/strings/utf_string_conversions.h" | 12 #include "base/strings/utf_string_conversions.h" |
12 #include "base/threading/thread_task_runner_handle.h" | 13 #include "base/threading/thread_task_runner_handle.h" |
13 #include "build/build_config.h" | 14 #include "build/build_config.h" |
14 #include "ui/aura/scoped_window_targeter.h" | 15 #include "ui/aura/scoped_window_targeter.h" |
15 #include "ui/aura/window.h" | 16 #include "ui/aura/window.h" |
16 #include "ui/events/event.h" | 17 #include "ui/events/event.h" |
17 #include "ui/events/event_constants.h" | 18 #include "ui/events/event_constants.h" |
18 #include "ui/events/event_handler.h" | 19 #include "ui/events/event_handler.h" |
19 #include "ui/events/event_utils.h" | 20 #include "ui/events/event_utils.h" |
20 #include "ui/events/null_event_targeter.h" | 21 #include "ui/events/null_event_targeter.h" |
21 #include "ui/events/test/event_generator.h" | 22 #include "ui/events/test/event_generator.h" |
22 #include "ui/gfx/geometry/point.h" | 23 #include "ui/gfx/geometry/point.h" |
23 #include "ui/gfx/geometry/rect.h" | 24 #include "ui/gfx/geometry/rect.h" |
24 #include "ui/views/controls/menu/menu_controller_delegate.h" | 25 #include "ui/views/controls/menu/menu_controller_delegate.h" |
25 #include "ui/views/controls/menu/menu_delegate.h" | 26 #include "ui/views/controls/menu/menu_delegate.h" |
26 #include "ui/views/controls/menu/menu_host.h" | 27 #include "ui/views/controls/menu/menu_host.h" |
27 #include "ui/views/controls/menu/menu_host_root_view.h" | 28 #include "ui/views/controls/menu/menu_host_root_view.h" |
28 #include "ui/views/controls/menu/menu_item_view.h" | 29 #include "ui/views/controls/menu/menu_item_view.h" |
29 #include "ui/views/controls/menu/menu_message_loop.h" | |
30 #include "ui/views/controls/menu/menu_scroll_view_container.h" | 30 #include "ui/views/controls/menu/menu_scroll_view_container.h" |
31 #include "ui/views/controls/menu/submenu_view.h" | 31 #include "ui/views/controls/menu/submenu_view.h" |
32 #include "ui/views/test/menu_test_utils.h" | 32 #include "ui/views/test/menu_test_utils.h" |
33 #include "ui/views/test/test_views_delegate.h" | 33 #include "ui/views/test/test_views_delegate.h" |
34 #include "ui/views/test/views_test_base.h" | 34 #include "ui/views/test/views_test_base.h" |
35 #include "ui/views/widget/root_view.h" | 35 #include "ui/views/widget/root_view.h" |
36 | 36 |
37 #if defined(USE_AURA) | 37 #if defined(USE_AURA) |
38 #include "ui/aura/client/drag_drop_client.h" | 38 #include "ui/aura/client/drag_drop_client.h" |
39 #include "ui/aura/scoped_window_targeter.h" | 39 #include "ui/aura/scoped_window_targeter.h" |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
146 } | 146 } |
147 } | 147 } |
148 | 148 |
149 int outstanding_touches() const { return outstanding_touches_; } | 149 int outstanding_touches() const { return outstanding_touches_; } |
150 | 150 |
151 private: | 151 private: |
152 int outstanding_touches_; | 152 int outstanding_touches_; |
153 DISALLOW_COPY_AND_ASSIGN(TestEventHandler); | 153 DISALLOW_COPY_AND_ASSIGN(TestEventHandler); |
154 }; | 154 }; |
155 | 155 |
156 // A wrapper around MenuMessageLoop that can be used to track whether a message | |
157 // loop is running or not. | |
158 class TestMenuMessageLoop : public MenuMessageLoop { | |
159 public: | |
160 explicit TestMenuMessageLoop(std::unique_ptr<MenuMessageLoop> original); | |
161 ~TestMenuMessageLoop() override; | |
162 | |
163 bool is_running() const { return is_running_; } | |
164 | |
165 // MenuMessageLoop: | |
166 void QuitNow() override; | |
167 | |
168 private: | |
169 // MenuMessageLoop: | |
170 void Run() override; | |
171 | |
172 std::unique_ptr<MenuMessageLoop> original_; | |
173 bool is_running_; | |
174 | |
175 DISALLOW_COPY_AND_ASSIGN(TestMenuMessageLoop); | |
176 }; | |
177 | |
178 TestMenuMessageLoop::TestMenuMessageLoop( | |
179 std::unique_ptr<MenuMessageLoop> original) | |
180 : original_(std::move(original)) { | |
181 DCHECK(original_); | |
182 } | |
183 | |
184 TestMenuMessageLoop::~TestMenuMessageLoop() {} | |
185 | |
186 void TestMenuMessageLoop::Run() { | |
187 is_running_ = true; | |
188 original_->Run(); | |
189 } | |
190 | |
191 void TestMenuMessageLoop::QuitNow() { | |
192 is_running_ = false; | |
193 original_->QuitNow(); | |
194 } | |
195 | |
196 #if defined(USE_AURA) | 156 #if defined(USE_AURA) |
197 // A DragDropClient which does not trigger a nested message loop. Instead a | 157 // A DragDropClient which does not trigger a nested message loop. Instead a |
198 // callback is triggered during StartDragAndDrop in order to allow testing. | 158 // callback is triggered during StartDragAndDrop in order to allow testing. |
199 class TestDragDropClient : public aura::client::DragDropClient { | 159 class TestDragDropClient : public aura::client::DragDropClient { |
200 public: | 160 public: |
201 explicit TestDragDropClient(const base::Closure& callback) | 161 explicit TestDragDropClient(const base::Closure& callback) |
202 : start_drag_and_drop_callback_(callback), drag_in_progress_(false) {} | 162 : start_drag_and_drop_callback_(callback), drag_in_progress_(false) {} |
203 ~TestDragDropClient() override {} | 163 ~TestDragDropClient() override {} |
204 | 164 |
205 // aura::client::DragDropClient: | 165 // aura::client::DragDropClient: |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
309 | 269 |
310 void ReleaseTouchId(int id) { | 270 void ReleaseTouchId(int id) { |
311 event_generator_->ReleaseTouchId(id); | 271 event_generator_->ReleaseTouchId(id); |
312 } | 272 } |
313 | 273 |
314 void PressKey(ui::KeyboardCode key_code) { | 274 void PressKey(ui::KeyboardCode key_code) { |
315 event_generator_->PressKey(key_code, 0); | 275 event_generator_->PressKey(key_code, 0); |
316 } | 276 } |
317 | 277 |
318 #if defined(OS_LINUX) && defined(USE_X11) | 278 #if defined(OS_LINUX) && defined(USE_X11) |
319 void TestEventTargeter() { | |
320 { | |
321 // With the |ui::NullEventTargeter| instantiated and assigned we expect | |
322 // the menu to not handle the key event. | |
323 aura::ScopedWindowTargeter scoped_targeter( | |
324 owner()->GetNativeWindow()->GetRootWindow(), | |
325 std::unique_ptr<ui::EventTargeter>(new ui::NullEventTargeter)); | |
326 event_generator_->PressKey(ui::VKEY_ESCAPE, 0); | |
327 EXPECT_EQ(MenuController::EXIT_NONE, menu_exit_type()); | |
328 } | |
329 // Now that the targeter has been destroyed, expect to exit the menu | |
330 // normally when hitting escape. | |
331 event_generator_->PressKey(ui::VKEY_ESCAPE, 0); | |
332 EXPECT_EQ(MenuController::EXIT_ALL, menu_exit_type()); | |
333 } | |
334 | |
335 // Verifies that a non-nested menu fully closes when receiving an escape key. | 279 // Verifies that a non-nested menu fully closes when receiving an escape key. |
336 void TestAsyncEscapeKey() { | 280 void TestAsyncEscapeKey() { |
337 ui::KeyEvent event(ui::EventType::ET_KEY_PRESSED, ui::VKEY_ESCAPE, 0); | 281 ui::KeyEvent event(ui::EventType::ET_KEY_PRESSED, ui::VKEY_ESCAPE, 0); |
338 menu_controller_->OnWillDispatchKeyEvent(&event); | 282 menu_controller_->OnWillDispatchKeyEvent(&event); |
339 EXPECT_EQ(MenuController::EXIT_ALL, menu_exit_type()); | 283 EXPECT_EQ(MenuController::EXIT_ALL, menu_exit_type()); |
340 } | 284 } |
341 | |
342 #endif // defined(OS_LINUX) && defined(USE_X11) | 285 #endif // defined(OS_LINUX) && defined(USE_X11) |
343 | 286 |
344 #if defined(USE_AURA) | 287 #if defined(USE_AURA) |
345 // Verifies that an open menu receives a cancel event, and closes. | 288 // Verifies that an open menu receives a cancel event, and closes. |
346 void TestCancelEvent() { | 289 void TestCancelEvent() { |
347 EXPECT_EQ(MenuController::EXIT_NONE, menu_controller_->exit_type()); | 290 EXPECT_EQ(MenuController::EXIT_NONE, menu_controller_->exit_type()); |
348 ui::CancelModeEvent cancel_event; | 291 ui::CancelModeEvent cancel_event; |
349 event_generator_->Dispatch(&cancel_event); | 292 event_generator_->Dispatch(&cancel_event); |
350 EXPECT_EQ(MenuController::EXIT_ALL, menu_controller_->exit_type()); | 293 EXPECT_EQ(MenuController::EXIT_ALL, menu_controller_->exit_type()); |
351 } | 294 } |
352 #endif // defined(USE_AURA) | 295 #endif // defined(USE_AURA) |
353 | 296 |
354 // Verifies the state of the |menu_controller_| before destroying it. | 297 // Verifies the state of the |menu_controller_| before destroying it. |
355 void VerifyDragCompleteThenDestroy() { | 298 void VerifyDragCompleteThenDestroy() { |
356 EXPECT_FALSE(menu_controller()->drag_in_progress()); | 299 EXPECT_FALSE(menu_controller()->drag_in_progress()); |
357 EXPECT_EQ(MenuController::EXIT_ALL, menu_controller()->exit_type()); | 300 EXPECT_EQ(MenuController::EXIT_ALL, menu_controller()->exit_type()); |
358 DestroyMenuController(); | 301 DestroyMenuController(); |
359 } | 302 } |
360 | 303 |
361 // Setups |menu_controller_delegate_| to be destroyed when OnMenuClosed is | 304 // Setups |menu_controller_delegate_| to be destroyed when OnMenuClosed is |
362 // called. | 305 // called. |
363 void TestDragCompleteThenDestroyOnMenuClosed() { | 306 void TestDragCompleteThenDestroyOnMenuClosed() { |
364 menu_controller_delegate_->set_on_menu_closed_callback( | 307 menu_controller_delegate_->set_on_menu_closed_callback( |
365 base::Bind(&MenuControllerTest::VerifyDragCompleteThenDestroy, | 308 base::Bind(&MenuControllerTest::VerifyDragCompleteThenDestroy, |
366 base::Unretained(this))); | 309 base::Unretained(this))); |
367 } | 310 } |
368 | 311 |
369 void TestAsynchronousNestedExitAll() { | 312 void TestAsynchronousNestedExitAll() { |
370 ASSERT_TRUE(test_message_loop_->is_running()); | |
371 | |
372 std::unique_ptr<TestMenuControllerDelegate> nested_delegate( | 313 std::unique_ptr<TestMenuControllerDelegate> nested_delegate( |
373 new TestMenuControllerDelegate()); | 314 new TestMenuControllerDelegate()); |
374 | 315 |
375 menu_controller()->AddNestedDelegate(nested_delegate.get()); | 316 menu_controller()->AddNestedDelegate(nested_delegate.get()); |
376 menu_controller()->SetAsyncRun(true); | |
377 | 317 |
378 int mouse_event_flags = 0; | 318 int mouse_event_flags = 0; |
379 MenuItemView* run_result = menu_controller()->Run( | 319 MenuItemView* run_result = menu_controller()->Run( |
380 owner(), nullptr, menu_item(), gfx::Rect(), MENU_ANCHOR_TOPLEFT, false, | 320 owner(), nullptr, menu_item(), gfx::Rect(), MENU_ANCHOR_TOPLEFT, false, |
381 false, &mouse_event_flags); | 321 false, &mouse_event_flags); |
382 EXPECT_EQ(run_result, nullptr); | 322 EXPECT_EQ(run_result, nullptr); |
383 | 323 |
384 // Exit all menus and check that the parent menu's message loop is | 324 // Exit all menus and check that the parent menu's message loop is |
385 // terminated. | 325 // terminated. |
386 menu_controller()->Cancel(MenuController::EXIT_ALL); | 326 menu_controller()->Cancel(MenuController::EXIT_ALL); |
387 EXPECT_EQ(MenuController::EXIT_ALL, menu_controller()->exit_type()); | 327 EXPECT_EQ(MenuController::EXIT_ALL, menu_controller()->exit_type()); |
388 EXPECT_FALSE(test_message_loop_->is_running()); | |
389 } | 328 } |
390 | 329 |
391 void TestAsynchronousNestedExitOutermost() { | 330 void TestAsynchronousNestedExitOutermost() { |
392 ASSERT_TRUE(test_message_loop_->is_running()); | |
393 | |
394 std::unique_ptr<TestMenuControllerDelegate> nested_delegate( | 331 std::unique_ptr<TestMenuControllerDelegate> nested_delegate( |
395 new TestMenuControllerDelegate()); | 332 new TestMenuControllerDelegate()); |
396 | 333 |
397 menu_controller()->AddNestedDelegate(nested_delegate.get()); | 334 menu_controller()->AddNestedDelegate(nested_delegate.get()); |
398 menu_controller()->SetAsyncRun(true); | |
399 | 335 |
400 int mouse_event_flags = 0; | 336 int mouse_event_flags = 0; |
401 MenuItemView* run_result = menu_controller()->Run( | 337 MenuItemView* run_result = menu_controller()->Run( |
402 owner(), nullptr, menu_item(), gfx::Rect(), MENU_ANCHOR_TOPLEFT, false, | 338 owner(), nullptr, menu_item(), gfx::Rect(), MENU_ANCHOR_TOPLEFT, false, |
403 false, &mouse_event_flags); | 339 false, &mouse_event_flags); |
404 EXPECT_EQ(run_result, nullptr); | 340 EXPECT_EQ(run_result, nullptr); |
405 | 341 |
406 // Exit the nested menu and check that the parent menu's message loop is | 342 // Exit the nested menu and check that the parent menu's message loop is |
407 // still running. | 343 // still running. |
408 menu_controller()->Cancel(MenuController::EXIT_OUTERMOST); | 344 menu_controller()->Cancel(MenuController::EXIT_OUTERMOST); |
409 EXPECT_EQ(MenuController::EXIT_NONE, menu_controller()->exit_type()); | 345 EXPECT_EQ(MenuController::EXIT_NONE, menu_controller()->exit_type()); |
410 EXPECT_TRUE(test_message_loop_->is_running()); | |
411 | 346 |
412 // Now, exit the parent menu and check that its message loop is terminated. | 347 // Now, exit the parent menu and check that its message loop is terminated. |
413 menu_controller()->Cancel(MenuController::EXIT_OUTERMOST); | 348 menu_controller()->Cancel(MenuController::EXIT_OUTERMOST); |
414 EXPECT_EQ(MenuController::EXIT_OUTERMOST, menu_controller()->exit_type()); | 349 EXPECT_EQ(MenuController::EXIT_OUTERMOST, menu_controller()->exit_type()); |
415 EXPECT_FALSE(test_message_loop_->is_running()); | |
416 } | 350 } |
417 | 351 |
418 // This nested an asynchronous delegate onto a menu with a nested message | 352 // This nested an asynchronous delegate onto a menu with a nested message |
419 // loop, then kills the loop. Simulates the loop being killed not by | 353 // loop, then kills the loop. Simulates the loop being killed not by |
420 // MenuController. | 354 // MenuController. |
421 void TestNestedMessageLoopKillsItself( | 355 void TestNestedMessageLoopKillsItself( |
422 TestMenuControllerDelegate* nested_delegate) { | 356 TestMenuControllerDelegate* nested_delegate) { |
423 menu_controller_->AddNestedDelegate(nested_delegate); | 357 menu_controller_->AddNestedDelegate(nested_delegate); |
424 menu_controller_->SetAsyncRun(true); | |
425 | |
426 test_message_loop_->QuitNow(); | |
427 } | 358 } |
428 | 359 |
429 // Tests destroying the active |menu_controller_| and replacing it with a new | 360 // Tests destroying the active |menu_controller_| and replacing it with a new |
430 // active instance. | 361 // active instance. |
431 void TestMenuControllerReplacementDuringDrag() { | 362 void TestMenuControllerReplacementDuringDrag() { |
432 DestroyMenuController(); | 363 DestroyMenuController(); |
433 menu_item()->GetSubmenu()->Close(); | 364 menu_item()->GetSubmenu()->Close(); |
434 menu_controller_ = | 365 menu_controller_ = |
435 new MenuController(true, menu_controller_delegate_.get()); | 366 new MenuController(true, menu_controller_delegate_.get()); |
436 menu_controller_->owner_ = owner_.get(); | 367 menu_controller_->owner_ = owner_.get(); |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
503 MenuItemView* FindPreviousSelectableMenuItem(MenuItemView* parent, | 434 MenuItemView* FindPreviousSelectableMenuItem(MenuItemView* parent, |
504 int index) { | 435 int index) { |
505 return menu_controller_->FindNextSelectableMenuItem( | 436 return menu_controller_->FindNextSelectableMenuItem( |
506 parent, index, MenuController::INCREMENT_SELECTION_UP); | 437 parent, index, MenuController::INCREMENT_SELECTION_UP); |
507 } | 438 } |
508 | 439 |
509 internal::MenuControllerDelegate* GetCurrentDelegate() { | 440 internal::MenuControllerDelegate* GetCurrentDelegate() { |
510 return menu_controller_->delegate_; | 441 return menu_controller_->delegate_; |
511 } | 442 } |
512 | 443 |
513 bool IsAsyncRun() { return menu_controller_->async_run_; } | |
514 | |
515 bool IsShowing() { return menu_controller_->showing_; } | 444 bool IsShowing() { return menu_controller_->showing_; } |
516 | 445 |
517 MenuHost* GetMenuHost(SubmenuView* submenu) { return submenu->host_; } | 446 MenuHost* GetMenuHost(SubmenuView* submenu) { return submenu->host_; } |
518 | 447 |
519 MenuHostRootView* CreateMenuHostRootView(MenuHost* host) { | 448 MenuHostRootView* CreateMenuHostRootView(MenuHost* host) { |
520 return static_cast<MenuHostRootView*>(host->CreateRootView()); | 449 return static_cast<MenuHostRootView*>(host->CreateRootView()); |
521 } | 450 } |
522 | 451 |
523 void MenuHostOnDragWillStart(MenuHost* host) { host->OnDragWillStart(); } | 452 void MenuHostOnDragWillStart(MenuHost* host) { host->OnDragWillStart(); } |
524 | 453 |
(...skipping 16 matching lines...) Expand all Loading... |
541 const ui::LocatedEvent* event) { | 470 const ui::LocatedEvent* event) { |
542 menu_controller_->SetSelectionOnPointerDown(source, event); | 471 menu_controller_->SetSelectionOnPointerDown(source, event); |
543 } | 472 } |
544 | 473 |
545 // Note that coordinates of events passed to MenuController must be in that of | 474 // Note that coordinates of events passed to MenuController must be in that of |
546 // the MenuScrollViewContainer. | 475 // the MenuScrollViewContainer. |
547 void ProcessMouseMoved(SubmenuView* source, const ui::MouseEvent& event) { | 476 void ProcessMouseMoved(SubmenuView* source, const ui::MouseEvent& event) { |
548 menu_controller_->OnMouseMoved(source, event); | 477 menu_controller_->OnMouseMoved(source, event); |
549 } | 478 } |
550 | 479 |
551 void RunMenu() { | |
552 #if defined(USE_AURA) | |
553 std::unique_ptr<MenuPreTargetHandler> menu_pre_target_handler( | |
554 new MenuPreTargetHandler(menu_controller_, owner_.get())); | |
555 #endif | |
556 | |
557 menu_controller_->message_loop_depth_++; | |
558 menu_controller_->RunMessageLoop(); | |
559 menu_controller_->message_loop_depth_--; | |
560 } | |
561 | |
562 void Accept(MenuItemView* item, int event_flags) { | 480 void Accept(MenuItemView* item, int event_flags) { |
563 menu_controller_->Accept(item, event_flags); | 481 menu_controller_->Accept(item, event_flags); |
564 } | 482 } |
565 | 483 |
566 void InstallTestMenuMessageLoop() { | |
567 test_message_loop_ = | |
568 new TestMenuMessageLoop(std::move(menu_controller_->message_loop_)); | |
569 menu_controller_->message_loop_.reset(test_message_loop_); | |
570 } | |
571 | |
572 // Causes the |menu_controller_| to begin dragging. Use TestDragDropClient to | 484 // Causes the |menu_controller_| to begin dragging. Use TestDragDropClient to |
573 // avoid nesting message loops. | 485 // avoid nesting message loops. |
574 void StartDrag() { | 486 void StartDrag() { |
575 const gfx::Point location; | 487 const gfx::Point location; |
576 menu_controller_->state_.item = menu_item()->GetSubmenu()->GetMenuItemAt(0); | 488 menu_controller_->state_.item = menu_item()->GetSubmenu()->GetMenuItemAt(0); |
577 menu_controller_->StartDrag( | 489 menu_controller_->StartDrag( |
578 menu_item()->GetSubmenu()->GetMenuItemAt(0)->CreateSubmenu(), location); | 490 menu_item()->GetSubmenu()->GetMenuItemAt(0)->CreateSubmenu(), location); |
579 } | 491 } |
580 | 492 |
581 Widget* owner() { return owner_.get(); } | 493 Widget* owner() { return owner_.get(); } |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
670 | 582 |
671 // Not owned. | 583 // Not owned. |
672 DestructingTestViewsDelegate* test_views_delegate_; | 584 DestructingTestViewsDelegate* test_views_delegate_; |
673 | 585 |
674 std::unique_ptr<Widget> owner_; | 586 std::unique_ptr<Widget> owner_; |
675 std::unique_ptr<ui::test::EventGenerator> event_generator_; | 587 std::unique_ptr<ui::test::EventGenerator> event_generator_; |
676 std::unique_ptr<TestMenuItemViewShown> menu_item_; | 588 std::unique_ptr<TestMenuItemViewShown> menu_item_; |
677 std::unique_ptr<TestMenuControllerDelegate> menu_controller_delegate_; | 589 std::unique_ptr<TestMenuControllerDelegate> menu_controller_delegate_; |
678 std::unique_ptr<MenuDelegate> menu_delegate_; | 590 std::unique_ptr<MenuDelegate> menu_delegate_; |
679 MenuController* menu_controller_; | 591 MenuController* menu_controller_; |
680 TestMenuMessageLoop* test_message_loop_; | |
681 | 592 |
682 DISALLOW_COPY_AND_ASSIGN(MenuControllerTest); | 593 DISALLOW_COPY_AND_ASSIGN(MenuControllerTest); |
683 }; | 594 }; |
684 | 595 |
685 #if defined(OS_LINUX) && defined(USE_X11) | 596 #if defined(OS_LINUX) && defined(USE_X11) |
686 // Tests that an event targeter which blocks events will be honored by the menu | 597 // Tests that an event targeter which blocks events will be honored by the menu |
687 // event dispatcher. | 598 // event dispatcher. |
688 TEST_F(MenuControllerTest, EventTargeter) { | 599 TEST_F(MenuControllerTest, EventTargeter) { |
689 base::ThreadTaskRunnerHandle::Get()->PostTask( | 600 { |
690 FROM_HERE, base::Bind(&MenuControllerTest::TestEventTargeter, | 601 // With the |ui::NullEventTargeter| instantiated and assigned we expect |
691 base::Unretained(this))); | 602 // the menu to not handle the key event. |
692 RunMenu(); | 603 aura::ScopedWindowTargeter scoped_targeter( |
693 } | 604 owner()->GetNativeWindow()->GetRootWindow(), |
694 | 605 std::unique_ptr<ui::EventTargeter>(new ui::NullEventTargeter)); |
695 // Tests that an non-nested menu receiving an escape key will fully shut. This | 606 PressKey(ui::VKEY_ESCAPE); |
696 // should not crash by attempting to retarget the key to an inner menu. | 607 base::RunLoop().RunUntilIdle(); |
697 TEST_F(MenuControllerTest, AsyncEscapeKey) { | 608 EXPECT_EQ(MenuController::EXIT_NONE, menu_exit_type()); |
698 menu_controller()->SetAsyncRun(true); | 609 } |
| 610 // Now that the targeter has been destroyed, expect to exit the menu |
| 611 // normally when hitting escape. |
699 TestAsyncEscapeKey(); | 612 TestAsyncEscapeKey(); |
700 } | 613 } |
701 | 614 |
702 #endif // defined(OS_LINUX) && defined(USE_X11) | 615 #endif // defined(OS_LINUX) && defined(USE_X11) |
703 | 616 |
704 #if defined(USE_X11) | 617 #if defined(USE_X11) |
705 // Tests that touch event ids are released correctly. See crbug.com/439051 for | 618 // Tests that touch event ids are released correctly. See crbug.com/439051 for |
706 // details. When the ids aren't managed correctly, we get stuck down touches. | 619 // details. When the ids aren't managed correctly, we get stuck down touches. |
707 TEST_F(MenuControllerTest, TouchIdsReleasedCorrectly) { | 620 TEST_F(MenuControllerTest, TouchIdsReleasedCorrectly) { |
708 TestEventHandler test_event_handler; | 621 TestEventHandler test_event_handler; |
709 owner()->GetNativeWindow()->GetRootWindow()->AddPreTargetHandler( | 622 owner()->GetNativeWindow()->GetRootWindow()->AddPreTargetHandler( |
710 &test_event_handler); | 623 &test_event_handler); |
711 | 624 |
712 std::vector<int> devices; | 625 std::vector<int> devices; |
713 devices.push_back(1); | 626 devices.push_back(1); |
714 ui::SetUpTouchDevicesForTest(devices); | 627 ui::SetUpTouchDevicesForTest(devices); |
715 | 628 |
716 event_generator()->PressTouchId(0); | 629 event_generator()->PressTouchId(0); |
717 event_generator()->PressTouchId(1); | 630 event_generator()->PressTouchId(1); |
718 event_generator()->ReleaseTouchId(0); | 631 event_generator()->ReleaseTouchId(0); |
719 | 632 |
720 base::ThreadTaskRunnerHandle::Get()->PostTask( | 633 int mouse_event_flags = 0; |
721 FROM_HERE, base::Bind(&MenuControllerTest::ReleaseTouchId, | 634 MenuItemView* run_result = menu_controller()->Run( |
722 base::Unretained(this), 1)); | 635 owner(), nullptr, menu_item(), gfx::Rect(), MENU_ANCHOR_TOPLEFT, false, |
| 636 false, &mouse_event_flags); |
| 637 EXPECT_EQ(run_result, nullptr); |
723 | 638 |
724 base::ThreadTaskRunnerHandle::Get()->PostTask( | 639 MenuControllerTest::ReleaseTouchId(1); |
725 FROM_HERE, base::Bind(&MenuControllerTest::PressKey, | 640 TestAsyncEscapeKey(); |
726 base::Unretained(this), ui::VKEY_ESCAPE)); | |
727 | |
728 RunMenu(); | |
729 | 641 |
730 EXPECT_EQ(MenuController::EXIT_ALL, menu_exit_type()); | 642 EXPECT_EQ(MenuController::EXIT_ALL, menu_exit_type()); |
731 EXPECT_EQ(0, test_event_handler.outstanding_touches()); | 643 EXPECT_EQ(0, test_event_handler.outstanding_touches()); |
732 | 644 |
733 owner()->GetNativeWindow()->GetRootWindow()->RemovePreTargetHandler( | 645 owner()->GetNativeWindow()->GetRootWindow()->RemovePreTargetHandler( |
734 &test_event_handler); | 646 &test_event_handler); |
735 } | 647 } |
736 #endif // defined(USE_X11) | 648 #endif // defined(USE_X11) |
737 | 649 |
738 // Tests that initial selected menu items are correct when items are enabled or | 650 // Tests that initial selected menu items are correct when items are enabled or |
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1026 // Increment twice to move selection to |button2|. | 938 // Increment twice to move selection to |button2|. |
1027 IncrementSelection(); | 939 IncrementSelection(); |
1028 IncrementSelection(); | 940 IncrementSelection(); |
1029 EXPECT_EQ(5, pending_state_item()->GetCommand()); | 941 EXPECT_EQ(5, pending_state_item()->GetCommand()); |
1030 EXPECT_FALSE(button1->IsHotTracked()); | 942 EXPECT_FALSE(button1->IsHotTracked()); |
1031 EXPECT_TRUE(button2->IsHotTracked()); | 943 EXPECT_TRUE(button2->IsHotTracked()); |
1032 EXPECT_FALSE(button3->IsHotTracked()); | 944 EXPECT_FALSE(button3->IsHotTracked()); |
1033 EXPECT_EQ(button2, GetHotButton()); | 945 EXPECT_EQ(button2, GetHotButton()); |
1034 | 946 |
1035 MenuController* controller = menu_controller(); | 947 MenuController* controller = menu_controller(); |
1036 controller->SetAsyncRun(true); | |
1037 int mouse_event_flags = 0; | 948 int mouse_event_flags = 0; |
1038 MenuItemView* run_result = | 949 MenuItemView* run_result = |
1039 controller->Run(owner(), nullptr, menu_item(), gfx::Rect(), | 950 controller->Run(owner(), nullptr, menu_item(), gfx::Rect(), |
1040 MENU_ANCHOR_TOPLEFT, false, false, &mouse_event_flags); | 951 MENU_ANCHOR_TOPLEFT, false, false, &mouse_event_flags); |
1041 EXPECT_EQ(run_result, nullptr); | 952 EXPECT_EQ(run_result, nullptr); |
1042 | 953 |
1043 // |button2| should stay in hot-tracked state but menu controller should not | 954 // |button2| should stay in hot-tracked state but menu controller should not |
1044 // track it anymore (preventing resetting hot-tracked state when changing | 955 // track it anymore (preventing resetting hot-tracked state when changing |
1045 // selection while a nested run is active). | 956 // selection while a nested run is active). |
1046 EXPECT_TRUE(button2->IsHotTracked()); | 957 EXPECT_TRUE(button2->IsHotTracked()); |
1047 EXPECT_EQ(nullptr, GetHotButton()); | 958 EXPECT_EQ(nullptr, GetHotButton()); |
1048 | 959 |
1049 // Setting hot-tracked button while nested should get reverted when nested | 960 // Setting hot-tracked button while nested should get reverted when nested |
1050 // menu run ends. | 961 // menu run ends. |
1051 SetHotTrackedButton(button1); | 962 SetHotTrackedButton(button1); |
1052 EXPECT_TRUE(button1->IsHotTracked()); | 963 EXPECT_TRUE(button1->IsHotTracked()); |
1053 EXPECT_EQ(button1, GetHotButton()); | 964 EXPECT_EQ(button1, GetHotButton()); |
1054 | 965 |
1055 ExitMenuRun(); | 966 ExitMenuRun(); |
1056 EXPECT_FALSE(button1->IsHotTracked()); | 967 EXPECT_FALSE(button1->IsHotTracked()); |
1057 EXPECT_TRUE(button2->IsHotTracked()); | 968 EXPECT_TRUE(button2->IsHotTracked()); |
1058 EXPECT_EQ(button2, GetHotButton()); | 969 EXPECT_EQ(button2, GetHotButton()); |
1059 } | 970 } |
1060 | 971 |
1061 // Tests that a menu opened asynchronously, will notify its | 972 // Tests that a menu opened asynchronously, will notify its |
1062 // MenuControllerDelegate when Accept is called. | 973 // MenuControllerDelegate when Accept is called. |
1063 TEST_F(MenuControllerTest, AsynchronousAccept) { | 974 TEST_F(MenuControllerTest, AsynchronousAccept) { |
1064 MenuController* controller = menu_controller(); | 975 MenuController* controller = menu_controller(); |
1065 controller->SetAsyncRun(true); | |
1066 | 976 |
1067 int mouse_event_flags = 0; | 977 int mouse_event_flags = 0; |
1068 MenuItemView* run_result = | 978 MenuItemView* run_result = |
1069 controller->Run(owner(), nullptr, menu_item(), gfx::Rect(), | 979 controller->Run(owner(), nullptr, menu_item(), gfx::Rect(), |
1070 MENU_ANCHOR_TOPLEFT, false, false, &mouse_event_flags); | 980 MENU_ANCHOR_TOPLEFT, false, false, &mouse_event_flags); |
1071 EXPECT_EQ(run_result, nullptr); | 981 EXPECT_EQ(run_result, nullptr); |
1072 TestMenuControllerDelegate* delegate = menu_controller_delegate(); | 982 TestMenuControllerDelegate* delegate = menu_controller_delegate(); |
1073 EXPECT_EQ(0, delegate->on_menu_closed_called()); | 983 EXPECT_EQ(0, delegate->on_menu_closed_called()); |
1074 | 984 |
1075 MenuItemView* accepted = menu_item()->GetSubmenu()->GetMenuItemAt(0); | 985 MenuItemView* accepted = menu_item()->GetSubmenu()->GetMenuItemAt(0); |
1076 const int kEventFlags = 42; | 986 const int kEventFlags = 42; |
1077 Accept(accepted, kEventFlags); | 987 Accept(accepted, kEventFlags); |
1078 | 988 |
1079 EXPECT_EQ(1, delegate->on_menu_closed_called()); | 989 EXPECT_EQ(1, delegate->on_menu_closed_called()); |
1080 EXPECT_EQ(accepted, delegate->on_menu_closed_menu()); | 990 EXPECT_EQ(accepted, delegate->on_menu_closed_menu()); |
1081 EXPECT_EQ(kEventFlags, delegate->on_menu_closed_mouse_event_flags()); | 991 EXPECT_EQ(kEventFlags, delegate->on_menu_closed_mouse_event_flags()); |
1082 EXPECT_EQ(internal::MenuControllerDelegate::NOTIFY_DELEGATE, | 992 EXPECT_EQ(internal::MenuControllerDelegate::NOTIFY_DELEGATE, |
1083 delegate->on_menu_closed_notify_type()); | 993 delegate->on_menu_closed_notify_type()); |
1084 } | 994 } |
1085 | 995 |
1086 // Tests that a menu opened asynchronously, will notify its | 996 // Tests that a menu opened asynchronously, will notify its |
1087 // MenuControllerDelegate when CancelAll is called. | 997 // MenuControllerDelegate when CancelAll is called. |
1088 TEST_F(MenuControllerTest, AsynchronousCancelAll) { | 998 TEST_F(MenuControllerTest, AsynchronousCancelAll) { |
1089 MenuController* controller = menu_controller(); | 999 MenuController* controller = menu_controller(); |
1090 controller->SetAsyncRun(true); | |
1091 | 1000 |
1092 int mouse_event_flags = 0; | 1001 int mouse_event_flags = 0; |
1093 MenuItemView* run_result = | 1002 MenuItemView* run_result = |
1094 controller->Run(owner(), nullptr, menu_item(), gfx::Rect(), | 1003 controller->Run(owner(), nullptr, menu_item(), gfx::Rect(), |
1095 MENU_ANCHOR_TOPLEFT, false, false, &mouse_event_flags); | 1004 MENU_ANCHOR_TOPLEFT, false, false, &mouse_event_flags); |
1096 EXPECT_EQ(run_result, nullptr); | 1005 EXPECT_EQ(run_result, nullptr); |
1097 TestMenuControllerDelegate* delegate = menu_controller_delegate(); | 1006 TestMenuControllerDelegate* delegate = menu_controller_delegate(); |
1098 EXPECT_EQ(0, delegate->on_menu_closed_called()); | 1007 EXPECT_EQ(0, delegate->on_menu_closed_called()); |
1099 | 1008 |
1100 controller->CancelAll(); | 1009 controller->CancelAll(); |
1101 EXPECT_EQ(1, delegate->on_menu_closed_called()); | 1010 EXPECT_EQ(1, delegate->on_menu_closed_called()); |
1102 EXPECT_EQ(nullptr, delegate->on_menu_closed_menu()); | 1011 EXPECT_EQ(nullptr, delegate->on_menu_closed_menu()); |
1103 EXPECT_EQ(0, delegate->on_menu_closed_mouse_event_flags()); | 1012 EXPECT_EQ(0, delegate->on_menu_closed_mouse_event_flags()); |
1104 EXPECT_EQ(internal::MenuControllerDelegate::NOTIFY_DELEGATE, | 1013 EXPECT_EQ(internal::MenuControllerDelegate::NOTIFY_DELEGATE, |
1105 delegate->on_menu_closed_notify_type()); | 1014 delegate->on_menu_closed_notify_type()); |
1106 EXPECT_EQ(MenuController::EXIT_ALL, controller->exit_type()); | 1015 EXPECT_EQ(MenuController::EXIT_ALL, controller->exit_type()); |
1107 } | 1016 } |
1108 | 1017 |
1109 // Tests that an asynchrnous menu nested within a synchronous menu restores the | 1018 // Tests that canceling a nested menu restores the previous |
1110 // previous MenuControllerDelegate and synchronous settings. | 1019 // MenuControllerDelegate, and notifies each delegate. |
1111 TEST_F(MenuControllerTest, AsynchronousNestedDelegate) { | 1020 TEST_F(MenuControllerTest, AsynchronousNestedDelegate) { |
1112 MenuController* controller = menu_controller(); | 1021 MenuController* controller = menu_controller(); |
1113 TestMenuControllerDelegate* delegate = menu_controller_delegate(); | 1022 TestMenuControllerDelegate* delegate = menu_controller_delegate(); |
1114 std::unique_ptr<TestMenuControllerDelegate> nested_delegate( | 1023 std::unique_ptr<TestMenuControllerDelegate> nested_delegate( |
1115 new TestMenuControllerDelegate()); | 1024 new TestMenuControllerDelegate()); |
1116 | 1025 |
1117 ASSERT_FALSE(IsAsyncRun()); | |
1118 controller->AddNestedDelegate(nested_delegate.get()); | 1026 controller->AddNestedDelegate(nested_delegate.get()); |
1119 controller->SetAsyncRun(true); | |
1120 | |
1121 EXPECT_TRUE(IsAsyncRun()); | |
1122 EXPECT_EQ(nested_delegate.get(), GetCurrentDelegate()); | 1027 EXPECT_EQ(nested_delegate.get(), GetCurrentDelegate()); |
1123 | 1028 |
1124 int mouse_event_flags = 0; | 1029 int mouse_event_flags = 0; |
1125 MenuItemView* run_result = | 1030 MenuItemView* run_result = |
1126 controller->Run(owner(), nullptr, menu_item(), gfx::Rect(), | 1031 controller->Run(owner(), nullptr, menu_item(), gfx::Rect(), |
1127 MENU_ANCHOR_TOPLEFT, false, false, &mouse_event_flags); | 1032 MENU_ANCHOR_TOPLEFT, false, false, &mouse_event_flags); |
1128 EXPECT_EQ(run_result, nullptr); | 1033 EXPECT_EQ(run_result, nullptr); |
1129 | 1034 |
1130 controller->CancelAll(); | 1035 controller->CancelAll(); |
1131 EXPECT_FALSE(IsAsyncRun()); | |
1132 EXPECT_EQ(delegate, GetCurrentDelegate()); | 1036 EXPECT_EQ(delegate, GetCurrentDelegate()); |
1133 EXPECT_EQ(0, delegate->on_menu_closed_called()); | 1037 EXPECT_EQ(1, delegate->on_menu_closed_called()); |
1134 EXPECT_EQ(1, nested_delegate->on_menu_closed_called()); | 1038 EXPECT_EQ(1, nested_delegate->on_menu_closed_called()); |
1135 EXPECT_EQ(nullptr, nested_delegate->on_menu_closed_menu()); | 1039 EXPECT_EQ(nullptr, nested_delegate->on_menu_closed_menu()); |
1136 EXPECT_EQ(0, nested_delegate->on_menu_closed_mouse_event_flags()); | 1040 EXPECT_EQ(0, nested_delegate->on_menu_closed_mouse_event_flags()); |
1137 EXPECT_EQ(internal::MenuControllerDelegate::NOTIFY_DELEGATE, | 1041 EXPECT_EQ(internal::MenuControllerDelegate::NOTIFY_DELEGATE, |
1138 nested_delegate->on_menu_closed_notify_type()); | 1042 nested_delegate->on_menu_closed_notify_type()); |
1139 EXPECT_EQ(MenuController::EXIT_ALL, controller->exit_type()); | 1043 EXPECT_EQ(MenuController::EXIT_ALL, controller->exit_type()); |
1140 } | 1044 } |
1141 | 1045 |
1142 // Tests that dropping within an asynchronous menu stops the menu from showing | 1046 // Tests that dropping within an asynchronous menu stops the menu from showing |
1143 // and does not notify the controller. | 1047 // and does not notify the controller. |
1144 TEST_F(MenuControllerTest, AsynchronousPerformDrop) { | 1048 TEST_F(MenuControllerTest, AsynchronousPerformDrop) { |
1145 MenuController* controller = menu_controller(); | 1049 MenuController* controller = menu_controller(); |
1146 controller->SetAsyncRun(true); | |
1147 SubmenuView* source = menu_item()->GetSubmenu(); | 1050 SubmenuView* source = menu_item()->GetSubmenu(); |
1148 MenuItemView* target = source->GetMenuItemAt(0); | 1051 MenuItemView* target = source->GetMenuItemAt(0); |
1149 | 1052 |
1150 SetDropMenuItem(target, MenuDelegate::DropPosition::DROP_AFTER); | 1053 SetDropMenuItem(target, MenuDelegate::DropPosition::DROP_AFTER); |
1151 | 1054 |
1152 ui::OSExchangeData drop_data; | 1055 ui::OSExchangeData drop_data; |
1153 gfx::Rect bounds(target->bounds()); | 1056 gfx::Rect bounds(target->bounds()); |
1154 gfx::Point location(bounds.x(), bounds.y()); | 1057 gfx::Point location(bounds.x(), bounds.y()); |
1155 ui::DropTargetEvent target_event(drop_data, location, location, | 1058 ui::DropTargetEvent target_event(drop_data, location, location, |
1156 ui::DragDropTypes::DRAG_MOVE); | 1059 ui::DragDropTypes::DRAG_MOVE); |
1157 controller->OnPerformDrop(source, target_event); | 1060 controller->OnPerformDrop(source, target_event); |
1158 | 1061 |
1159 TestMenuDelegate* menu_delegate = | 1062 TestMenuDelegate* menu_delegate = |
1160 static_cast<TestMenuDelegate*>(target->GetDelegate()); | 1063 static_cast<TestMenuDelegate*>(target->GetDelegate()); |
1161 TestMenuControllerDelegate* controller_delegate = menu_controller_delegate(); | 1064 TestMenuControllerDelegate* controller_delegate = menu_controller_delegate(); |
1162 EXPECT_TRUE(menu_delegate->on_perform_drop_called()); | 1065 EXPECT_TRUE(menu_delegate->on_perform_drop_called()); |
1163 EXPECT_FALSE(IsShowing()); | 1066 EXPECT_FALSE(IsShowing()); |
1164 EXPECT_EQ(0, controller_delegate->on_menu_closed_called()); | 1067 EXPECT_EQ(0, controller_delegate->on_menu_closed_called()); |
1165 } | 1068 } |
1166 | 1069 |
1167 // Tests that dragging within an asynchronous menu notifies the | 1070 // Tests that dragging within an asynchronous menu notifies the |
1168 // MenuControllerDelegate for shutdown. | 1071 // MenuControllerDelegate for shutdown. |
1169 TEST_F(MenuControllerTest, AsynchronousDragComplete) { | 1072 TEST_F(MenuControllerTest, AsynchronousDragComplete) { |
1170 MenuController* controller = menu_controller(); | 1073 MenuController* controller = menu_controller(); |
1171 controller->SetAsyncRun(true); | |
1172 TestDragCompleteThenDestroyOnMenuClosed(); | 1074 TestDragCompleteThenDestroyOnMenuClosed(); |
1173 | 1075 |
1174 controller->OnDragWillStart(); | 1076 controller->OnDragWillStart(); |
1175 controller->OnDragComplete(true); | 1077 controller->OnDragComplete(true); |
1176 | 1078 |
1177 TestMenuControllerDelegate* controller_delegate = menu_controller_delegate(); | 1079 TestMenuControllerDelegate* controller_delegate = menu_controller_delegate(); |
1178 EXPECT_EQ(1, controller_delegate->on_menu_closed_called()); | 1080 EXPECT_EQ(1, controller_delegate->on_menu_closed_called()); |
1179 EXPECT_EQ(nullptr, controller_delegate->on_menu_closed_menu()); | 1081 EXPECT_EQ(nullptr, controller_delegate->on_menu_closed_menu()); |
1180 EXPECT_EQ(internal::MenuControllerDelegate::NOTIFY_DELEGATE, | 1082 EXPECT_EQ(internal::MenuControllerDelegate::NOTIFY_DELEGATE, |
1181 controller_delegate->on_menu_closed_notify_type()); | 1083 controller_delegate->on_menu_closed_notify_type()); |
1182 } | 1084 } |
1183 | 1085 |
1184 // Tests that if Cancel is called during a drag, that OnMenuClosed is still | 1086 // Tests that if Cancel is called during a drag, that OnMenuClosed is still |
1185 // notified when the drag completes. | 1087 // notified when the drag completes. |
1186 TEST_F(MenuControllerTest, AsynchronousCancelDuringDrag) { | 1088 TEST_F(MenuControllerTest, AsynchronousCancelDuringDrag) { |
1187 MenuController* controller = menu_controller(); | 1089 MenuController* controller = menu_controller(); |
1188 controller->SetAsyncRun(true); | |
1189 TestDragCompleteThenDestroyOnMenuClosed(); | 1090 TestDragCompleteThenDestroyOnMenuClosed(); |
1190 | 1091 |
1191 controller->OnDragWillStart(); | 1092 controller->OnDragWillStart(); |
1192 controller->CancelAll(); | 1093 controller->CancelAll(); |
1193 controller->OnDragComplete(true); | 1094 controller->OnDragComplete(true); |
1194 | 1095 |
1195 TestMenuControllerDelegate* controller_delegate = menu_controller_delegate(); | 1096 TestMenuControllerDelegate* controller_delegate = menu_controller_delegate(); |
1196 EXPECT_EQ(1, controller_delegate->on_menu_closed_called()); | 1097 EXPECT_EQ(1, controller_delegate->on_menu_closed_called()); |
1197 EXPECT_EQ(nullptr, controller_delegate->on_menu_closed_menu()); | 1098 EXPECT_EQ(nullptr, controller_delegate->on_menu_closed_menu()); |
1198 EXPECT_EQ(internal::MenuControllerDelegate::NOTIFY_DELEGATE, | 1099 EXPECT_EQ(internal::MenuControllerDelegate::NOTIFY_DELEGATE, |
1199 controller_delegate->on_menu_closed_notify_type()); | 1100 controller_delegate->on_menu_closed_notify_type()); |
1200 } | 1101 } |
1201 | 1102 |
1202 // Tests that if a menu is destroyed while drag operations are occuring, that | 1103 // Tests that if a menu is destroyed while drag operations are occuring, that |
1203 // the MenuHost does not crash as the drag completes. | 1104 // the MenuHost does not crash as the drag completes. |
1204 TEST_F(MenuControllerTest, AsynchronousDragHostDeleted) { | 1105 TEST_F(MenuControllerTest, AsynchronousDragHostDeleted) { |
1205 MenuController* controller = menu_controller(); | |
1206 controller->SetAsyncRun(true); | |
1207 | |
1208 SubmenuView* submenu = menu_item()->GetSubmenu(); | 1106 SubmenuView* submenu = menu_item()->GetSubmenu(); |
1209 submenu->ShowAt(owner(), menu_item()->bounds(), false); | 1107 submenu->ShowAt(owner(), menu_item()->bounds(), false); |
1210 MenuHost* host = GetMenuHost(submenu); | 1108 MenuHost* host = GetMenuHost(submenu); |
1211 MenuHostOnDragWillStart(host); | 1109 MenuHostOnDragWillStart(host); |
1212 submenu->Close(); | 1110 submenu->Close(); |
1213 DestroyMenuItem(); | 1111 DestroyMenuItem(); |
1214 MenuHostOnDragComplete(host); | 1112 MenuHostOnDragComplete(host); |
1215 } | 1113 } |
1216 | 1114 |
1217 // Widget destruction and cleanup occurs on the MessageLoop after the | 1115 // Widget destruction and cleanup occurs on the MessageLoop after the |
1218 // MenuController has been destroyed. A MenuHostRootView should not attempt to | 1116 // MenuController has been destroyed. A MenuHostRootView should not attempt to |
1219 // access a destroyed MenuController. This test should not cause a crash. | 1117 // access a destroyed MenuController. This test should not cause a crash. |
1220 TEST_F(MenuControllerTest, HostReceivesInputBeforeDestruction) { | 1118 TEST_F(MenuControllerTest, HostReceivesInputBeforeDestruction) { |
1221 MenuController* controller = menu_controller(); | |
1222 controller->SetAsyncRun(true); | |
1223 | |
1224 SubmenuView* submenu = menu_item()->GetSubmenu(); | 1119 SubmenuView* submenu = menu_item()->GetSubmenu(); |
1225 submenu->ShowAt(owner(), menu_item()->bounds(), false); | 1120 submenu->ShowAt(owner(), menu_item()->bounds(), false); |
1226 gfx::Point location(submenu->bounds().bottom_right()); | 1121 gfx::Point location(submenu->bounds().bottom_right()); |
1227 location.Offset(1, 1); | 1122 location.Offset(1, 1); |
1228 | 1123 |
1229 MenuHost* host = GetMenuHost(submenu); | 1124 MenuHost* host = GetMenuHost(submenu); |
1230 // Normally created as the full Widget is brought up. Explicitly created here | 1125 // Normally created as the full Widget is brought up. Explicitly created here |
1231 // for testing. | 1126 // for testing. |
1232 std::unique_ptr<MenuHostRootView> root_view(CreateMenuHostRootView(host)); | 1127 std::unique_ptr<MenuHostRootView> root_view(CreateMenuHostRootView(host)); |
1233 DestroyMenuController(); | 1128 DestroyMenuController(); |
1234 | 1129 |
1235 ui::MouseEvent event(ui::ET_MOUSE_MOVED, location, location, | 1130 ui::MouseEvent event(ui::ET_MOUSE_MOVED, location, location, |
1236 ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON, 0); | 1131 ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON, 0); |
1237 | 1132 |
1238 // This should not attempt to access the destroyed MenuController and should | 1133 // This should not attempt to access the destroyed MenuController and should |
1239 // not crash. | 1134 // not crash. |
1240 root_view->OnMouseMoved(event); | 1135 root_view->OnMouseMoved(event); |
1241 } | 1136 } |
1242 | 1137 |
1243 // Tets that an asynchronous menu nested within an asynchronous menu closes both | 1138 // Tets that an asynchronous menu nested within an asynchronous menu closes both |
1244 // menus, and notifies both delegates. | 1139 // menus, and notifies both delegates. |
1245 TEST_F(MenuControllerTest, DoubleAsynchronousNested) { | 1140 TEST_F(MenuControllerTest, DoubleAsynchronousNested) { |
1246 MenuController* controller = menu_controller(); | 1141 MenuController* controller = menu_controller(); |
1247 TestMenuControllerDelegate* delegate = menu_controller_delegate(); | 1142 TestMenuControllerDelegate* delegate = menu_controller_delegate(); |
1248 std::unique_ptr<TestMenuControllerDelegate> nested_delegate( | 1143 std::unique_ptr<TestMenuControllerDelegate> nested_delegate( |
1249 new TestMenuControllerDelegate()); | 1144 new TestMenuControllerDelegate()); |
1250 | 1145 |
1251 ASSERT_FALSE(IsAsyncRun()); | |
1252 // Sets the run created in SetUp | |
1253 controller->SetAsyncRun(true); | |
1254 | |
1255 // Nested run | 1146 // Nested run |
1256 controller->AddNestedDelegate(nested_delegate.get()); | 1147 controller->AddNestedDelegate(nested_delegate.get()); |
1257 controller->SetAsyncRun(true); | |
1258 int mouse_event_flags = 0; | 1148 int mouse_event_flags = 0; |
1259 MenuItemView* run_result = | 1149 MenuItemView* run_result = |
1260 controller->Run(owner(), nullptr, menu_item(), gfx::Rect(), | 1150 controller->Run(owner(), nullptr, menu_item(), gfx::Rect(), |
1261 MENU_ANCHOR_TOPLEFT, false, false, &mouse_event_flags); | 1151 MENU_ANCHOR_TOPLEFT, false, false, &mouse_event_flags); |
1262 EXPECT_EQ(run_result, nullptr); | 1152 EXPECT_EQ(run_result, nullptr); |
1263 | 1153 |
1264 controller->CancelAll(); | 1154 controller->CancelAll(); |
1265 EXPECT_EQ(1, delegate->on_menu_closed_called()); | 1155 EXPECT_EQ(1, delegate->on_menu_closed_called()); |
1266 EXPECT_EQ(1, nested_delegate->on_menu_closed_called()); | 1156 EXPECT_EQ(1, nested_delegate->on_menu_closed_called()); |
1267 } | 1157 } |
1268 | 1158 |
1269 // Tests that an asynchronous menu nested within a synchronous menu does not | 1159 // Tests that a nested menu does not crash when trying to repost events that |
1270 // crash when trying to repost events that occur outside of the bounds of the | 1160 // occur outside of the bounds of the menu. Instead a proper shutdown should |
1271 // menu. Instead a proper shutdown should occur. | 1161 // occur. |
1272 TEST_F(MenuControllerTest, AsynchronousRepostEvent) { | 1162 TEST_F(MenuControllerTest, AsynchronousRepostEvent) { |
1273 MenuController* controller = menu_controller(); | 1163 MenuController* controller = menu_controller(); |
1274 TestMenuControllerDelegate* delegate = menu_controller_delegate(); | 1164 TestMenuControllerDelegate* delegate = menu_controller_delegate(); |
1275 std::unique_ptr<TestMenuControllerDelegate> nested_delegate( | 1165 std::unique_ptr<TestMenuControllerDelegate> nested_delegate( |
1276 new TestMenuControllerDelegate()); | 1166 new TestMenuControllerDelegate()); |
1277 | 1167 |
1278 ASSERT_FALSE(IsAsyncRun()); | |
1279 | |
1280 controller->AddNestedDelegate(nested_delegate.get()); | 1168 controller->AddNestedDelegate(nested_delegate.get()); |
1281 controller->SetAsyncRun(true); | |
1282 | |
1283 EXPECT_TRUE(IsAsyncRun()); | |
1284 EXPECT_EQ(nested_delegate.get(), GetCurrentDelegate()); | 1169 EXPECT_EQ(nested_delegate.get(), GetCurrentDelegate()); |
1285 | 1170 |
1286 MenuItemView* item = menu_item(); | 1171 MenuItemView* item = menu_item(); |
1287 int mouse_event_flags = 0; | 1172 int mouse_event_flags = 0; |
1288 MenuItemView* run_result = | 1173 MenuItemView* run_result = |
1289 controller->Run(owner(), nullptr, item, gfx::Rect(), MENU_ANCHOR_TOPLEFT, | 1174 controller->Run(owner(), nullptr, item, gfx::Rect(), MENU_ANCHOR_TOPLEFT, |
1290 false, false, &mouse_event_flags); | 1175 false, false, &mouse_event_flags); |
1291 EXPECT_EQ(run_result, nullptr); | 1176 EXPECT_EQ(run_result, nullptr); |
1292 | 1177 |
1293 // Show a sub menu to target with a pointer selection. However have the event | 1178 // Show a sub menu to target with a pointer selection. However have the event |
1294 // occur outside of the bounds of the entire menu. | 1179 // occur outside of the bounds of the entire menu. |
1295 SubmenuView* sub_menu = item->GetSubmenu(); | 1180 SubmenuView* sub_menu = item->GetSubmenu(); |
1296 sub_menu->ShowAt(owner(), item->bounds(), false); | 1181 sub_menu->ShowAt(owner(), item->bounds(), false); |
1297 gfx::Point location(sub_menu->bounds().bottom_right()); | 1182 gfx::Point location(sub_menu->bounds().bottom_right()); |
1298 location.Offset(1, 1); | 1183 location.Offset(1, 1); |
1299 ui::MouseEvent event(ui::ET_MOUSE_PRESSED, location, location, | 1184 ui::MouseEvent event(ui::ET_MOUSE_PRESSED, location, location, |
1300 ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON, 0); | 1185 ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON, 0); |
1301 | 1186 |
1302 // When attempting to select outside of all menus this should lead to a | 1187 // When attempting to select outside of all menus this should lead to a |
1303 // shutdown. This should not crash while attempting to repost the event. | 1188 // shutdown. This should not crash while attempting to repost the event. |
1304 SetSelectionOnPointerDown(sub_menu, &event); | 1189 SetSelectionOnPointerDown(sub_menu, &event); |
1305 | 1190 |
1306 EXPECT_FALSE(IsAsyncRun()); | |
1307 EXPECT_EQ(delegate, GetCurrentDelegate()); | 1191 EXPECT_EQ(delegate, GetCurrentDelegate()); |
1308 EXPECT_EQ(0, delegate->on_menu_closed_called()); | 1192 EXPECT_EQ(1, delegate->on_menu_closed_called()); |
1309 EXPECT_EQ(1, nested_delegate->on_menu_closed_called()); | 1193 EXPECT_EQ(1, nested_delegate->on_menu_closed_called()); |
1310 EXPECT_EQ(nullptr, nested_delegate->on_menu_closed_menu()); | 1194 EXPECT_EQ(nullptr, nested_delegate->on_menu_closed_menu()); |
1311 EXPECT_EQ(0, nested_delegate->on_menu_closed_mouse_event_flags()); | 1195 EXPECT_EQ(0, nested_delegate->on_menu_closed_mouse_event_flags()); |
1312 EXPECT_EQ(internal::MenuControllerDelegate::NOTIFY_DELEGATE, | 1196 EXPECT_EQ(internal::MenuControllerDelegate::NOTIFY_DELEGATE, |
1313 nested_delegate->on_menu_closed_notify_type()); | 1197 nested_delegate->on_menu_closed_notify_type()); |
1314 EXPECT_EQ(MenuController::EXIT_ALL, controller->exit_type()); | 1198 EXPECT_EQ(MenuController::EXIT_ALL, controller->exit_type()); |
1315 } | 1199 } |
1316 | 1200 |
1317 // Tests that an asynchronous menu reposts touch events that occur outside of | 1201 // Tests that an asynchronous menu reposts touch events that occur outside of |
1318 // the bounds of the menu, and that the menu closes. | 1202 // the bounds of the menu, and that the menu closes. |
1319 TEST_F(MenuControllerTest, AsynchronousTouchEventRepostEvent) { | 1203 TEST_F(MenuControllerTest, AsynchronousTouchEventRepostEvent) { |
1320 MenuController* controller = menu_controller(); | 1204 MenuController* controller = menu_controller(); |
1321 TestMenuControllerDelegate* delegate = menu_controller_delegate(); | 1205 TestMenuControllerDelegate* delegate = menu_controller_delegate(); |
1322 controller->SetAsyncRun(true); | |
1323 | 1206 |
1324 // Show a sub menu to target with a touch event. However have the event occur | 1207 // Show a sub menu to target with a touch event. However have the event occur |
1325 // outside of the bounds of the entire menu. | 1208 // outside of the bounds of the entire menu. |
1326 MenuItemView* item = menu_item(); | 1209 MenuItemView* item = menu_item(); |
1327 SubmenuView* sub_menu = item->GetSubmenu(); | 1210 SubmenuView* sub_menu = item->GetSubmenu(); |
1328 sub_menu->ShowAt(owner(), item->bounds(), false); | 1211 sub_menu->ShowAt(owner(), item->bounds(), false); |
1329 gfx::Point location(sub_menu->bounds().bottom_right()); | 1212 gfx::Point location(sub_menu->bounds().bottom_right()); |
1330 location.Offset(1, 1); | 1213 location.Offset(1, 1); |
1331 ui::TouchEvent event( | 1214 ui::TouchEvent event( |
1332 ui::ET_TOUCH_PRESSED, location, ui::EventTimeForNow(), | 1215 ui::ET_TOUCH_PRESSED, location, ui::EventTimeForNow(), |
1333 ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 0)); | 1216 ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 0)); |
1334 controller->OnTouchEvent(sub_menu, &event); | 1217 controller->OnTouchEvent(sub_menu, &event); |
1335 | 1218 |
1336 EXPECT_FALSE(IsShowing()); | 1219 EXPECT_FALSE(IsShowing()); |
1337 EXPECT_EQ(1, delegate->on_menu_closed_called()); | 1220 EXPECT_EQ(1, delegate->on_menu_closed_called()); |
1338 EXPECT_EQ(nullptr, delegate->on_menu_closed_menu()); | 1221 EXPECT_EQ(nullptr, delegate->on_menu_closed_menu()); |
1339 EXPECT_EQ(0, delegate->on_menu_closed_mouse_event_flags()); | 1222 EXPECT_EQ(0, delegate->on_menu_closed_mouse_event_flags()); |
1340 EXPECT_EQ(internal::MenuControllerDelegate::NOTIFY_DELEGATE, | 1223 EXPECT_EQ(internal::MenuControllerDelegate::NOTIFY_DELEGATE, |
1341 delegate->on_menu_closed_notify_type()); | 1224 delegate->on_menu_closed_notify_type()); |
1342 EXPECT_EQ(MenuController::EXIT_ALL, controller->exit_type()); | 1225 EXPECT_EQ(MenuController::EXIT_ALL, controller->exit_type()); |
1343 } | 1226 } |
1344 | 1227 |
1345 // Tests that if you exit all menus when an asynchrnous menu is nested within a | |
1346 // synchronous menu, the message loop for the parent menu finishes running. | |
1347 TEST_F(MenuControllerTest, AsynchronousNestedExitAll) { | |
1348 InstallTestMenuMessageLoop(); | |
1349 | |
1350 base::ThreadTaskRunnerHandle::Get()->PostTask( | |
1351 FROM_HERE, base::Bind(&MenuControllerTest::TestAsynchronousNestedExitAll, | |
1352 base::Unretained(this))); | |
1353 | |
1354 RunMenu(); | |
1355 } | |
1356 | |
1357 // Tests that if you exit the nested menu when an asynchrnous menu is nested | |
1358 // within a synchronous menu, the message loop for the parent menu remains | |
1359 // running. | |
1360 TEST_F(MenuControllerTest, AsynchronousNestedExitOutermost) { | |
1361 InstallTestMenuMessageLoop(); | |
1362 | |
1363 base::ThreadTaskRunnerHandle::Get()->PostTask( | |
1364 FROM_HERE, | |
1365 base::Bind(&MenuControllerTest::TestAsynchronousNestedExitOutermost, | |
1366 base::Unretained(this))); | |
1367 | |
1368 RunMenu(); | |
1369 } | |
1370 | |
1371 // Tests that having the MenuController deleted during RepostEvent does not | 1228 // Tests that having the MenuController deleted during RepostEvent does not |
1372 // cause a crash. ASAN bots should not detect use-after-free in MenuController. | 1229 // cause a crash. ASAN bots should not detect use-after-free in MenuController. |
1373 TEST_F(MenuControllerTest, AsynchronousRepostEventDeletesController) { | 1230 TEST_F(MenuControllerTest, AsynchronousRepostEventDeletesController) { |
1374 MenuController* controller = menu_controller(); | 1231 MenuController* controller = menu_controller(); |
1375 std::unique_ptr<TestMenuControllerDelegate> nested_delegate( | 1232 std::unique_ptr<TestMenuControllerDelegate> nested_delegate( |
1376 new TestMenuControllerDelegate()); | 1233 new TestMenuControllerDelegate()); |
1377 | 1234 |
1378 ASSERT_FALSE(IsAsyncRun()); | |
1379 | |
1380 controller->AddNestedDelegate(nested_delegate.get()); | 1235 controller->AddNestedDelegate(nested_delegate.get()); |
1381 controller->SetAsyncRun(true); | |
1382 | |
1383 EXPECT_TRUE(IsAsyncRun()); | |
1384 EXPECT_EQ(nested_delegate.get(), GetCurrentDelegate()); | 1236 EXPECT_EQ(nested_delegate.get(), GetCurrentDelegate()); |
1385 | 1237 |
1386 MenuItemView* item = menu_item(); | 1238 MenuItemView* item = menu_item(); |
1387 int mouse_event_flags = 0; | 1239 int mouse_event_flags = 0; |
1388 MenuItemView* run_result = | 1240 MenuItemView* run_result = |
1389 controller->Run(owner(), nullptr, item, gfx::Rect(), MENU_ANCHOR_TOPLEFT, | 1241 controller->Run(owner(), nullptr, item, gfx::Rect(), MENU_ANCHOR_TOPLEFT, |
1390 false, false, &mouse_event_flags); | 1242 false, false, &mouse_event_flags); |
1391 EXPECT_EQ(run_result, nullptr); | 1243 EXPECT_EQ(run_result, nullptr); |
1392 | 1244 |
1393 // Show a sub menu to target with a pointer selection. However have the event | 1245 // Show a sub menu to target with a pointer selection. However have the event |
(...skipping 16 matching lines...) Expand all Loading... |
1410 sub_menu->Close(); | 1262 sub_menu->Close(); |
1411 EXPECT_EQ(1, nested_delegate->on_menu_closed_called()); | 1263 EXPECT_EQ(1, nested_delegate->on_menu_closed_called()); |
1412 } | 1264 } |
1413 | 1265 |
1414 // Tests that having the MenuController deleted during OnGestureEvent does not | 1266 // Tests that having the MenuController deleted during OnGestureEvent does not |
1415 // cause a crash. ASAN bots should not detect use-after-free in MenuController. | 1267 // cause a crash. ASAN bots should not detect use-after-free in MenuController. |
1416 TEST_F(MenuControllerTest, AsynchronousGestureDeletesController) { | 1268 TEST_F(MenuControllerTest, AsynchronousGestureDeletesController) { |
1417 MenuController* controller = menu_controller(); | 1269 MenuController* controller = menu_controller(); |
1418 std::unique_ptr<TestMenuControllerDelegate> nested_delegate( | 1270 std::unique_ptr<TestMenuControllerDelegate> nested_delegate( |
1419 new TestMenuControllerDelegate()); | 1271 new TestMenuControllerDelegate()); |
1420 ASSERT_FALSE(IsAsyncRun()); | |
1421 | 1272 |
1422 controller->AddNestedDelegate(nested_delegate.get()); | 1273 controller->AddNestedDelegate(nested_delegate.get()); |
1423 controller->SetAsyncRun(true); | |
1424 | |
1425 EXPECT_TRUE(IsAsyncRun()); | |
1426 EXPECT_EQ(nested_delegate.get(), GetCurrentDelegate()); | 1274 EXPECT_EQ(nested_delegate.get(), GetCurrentDelegate()); |
1427 | 1275 |
1428 MenuItemView* item = menu_item(); | 1276 MenuItemView* item = menu_item(); |
1429 int mouse_event_flags = 0; | 1277 int mouse_event_flags = 0; |
1430 MenuItemView* run_result = | 1278 MenuItemView* run_result = |
1431 controller->Run(owner(), nullptr, item, gfx::Rect(), MENU_ANCHOR_TOPLEFT, | 1279 controller->Run(owner(), nullptr, item, gfx::Rect(), MENU_ANCHOR_TOPLEFT, |
1432 false, false, &mouse_event_flags); | 1280 false, false, &mouse_event_flags); |
1433 EXPECT_EQ(run_result, nullptr); | 1281 EXPECT_EQ(run_result, nullptr); |
1434 | 1282 |
1435 // Show a sub menu to target with a tap event. | 1283 // Show a sub menu to target with a tap event. |
1436 SubmenuView* sub_menu = item->GetSubmenu(); | 1284 SubmenuView* sub_menu = item->GetSubmenu(); |
1437 sub_menu->ShowAt(owner(), gfx::Rect(0, 0, 100, 100), true); | 1285 sub_menu->ShowAt(owner(), gfx::Rect(0, 0, 100, 100), true); |
1438 | 1286 |
1439 gfx::Point location(sub_menu->bounds().CenterPoint()); | 1287 gfx::Point location(sub_menu->bounds().CenterPoint()); |
1440 ui::GestureEvent event(location.x(), location.y(), 0, ui::EventTimeForNow(), | 1288 ui::GestureEvent event(location.x(), location.y(), 0, ui::EventTimeForNow(), |
1441 ui::GestureEventDetails(ui::ET_GESTURE_TAP)); | 1289 ui::GestureEventDetails(ui::ET_GESTURE_TAP)); |
1442 | 1290 |
1443 // This will lead to MenuController being deleted during the processing of the | 1291 // This will lead to MenuController being deleted during the processing of the |
1444 // gesture event. The remainder of this test, and TearDown should not crash. | 1292 // gesture event. The remainder of this test, and TearDown should not crash. |
1445 DestroyMenuControllerOnMenuClosed(nested_delegate.get()); | 1293 DestroyMenuControllerOnMenuClosed(nested_delegate.get()); |
1446 controller->OnGestureEvent(sub_menu, &event); | 1294 controller->OnGestureEvent(sub_menu, &event); |
1447 | 1295 |
1448 // Close to remove observers before test TearDown | 1296 // Close to remove observers before test TearDown |
1449 sub_menu->Close(); | 1297 sub_menu->Close(); |
1450 EXPECT_EQ(1, nested_delegate->on_menu_closed_called()); | 1298 EXPECT_EQ(1, nested_delegate->on_menu_closed_called()); |
1451 } | 1299 } |
1452 | 1300 |
1453 // Tests that when an asynchronous menu is nested, and the nested message loop | |
1454 // is kill not by the MenuController, that the nested menu is notified of | |
1455 // destruction. | |
1456 TEST_F(MenuControllerTest, NestedMessageLoopDiesWithNestedMenu) { | |
1457 menu_controller()->CancelAll(); | |
1458 InstallTestMenuMessageLoop(); | |
1459 std::unique_ptr<TestMenuControllerDelegate> nested_delegate( | |
1460 new TestMenuControllerDelegate()); | |
1461 // This will nest an asynchronous menu, and then kill the nested message loop. | |
1462 base::ThreadTaskRunnerHandle::Get()->PostTask( | |
1463 FROM_HERE, | |
1464 base::Bind(&MenuControllerTest::TestNestedMessageLoopKillsItself, | |
1465 base::Unretained(this), nested_delegate.get())); | |
1466 | |
1467 int result_event_flags = 0; | |
1468 // This creates a nested message loop. | |
1469 EXPECT_EQ(nullptr, menu_controller()->Run(owner(), nullptr, menu_item(), | |
1470 gfx::Rect(), MENU_ANCHOR_TOPLEFT, | |
1471 false, false, &result_event_flags)); | |
1472 EXPECT_FALSE(menu_controller_delegate()->on_menu_closed_called()); | |
1473 EXPECT_TRUE(nested_delegate->on_menu_closed_called()); | |
1474 } | |
1475 | |
1476 #if defined(USE_AURA) | 1301 #if defined(USE_AURA) |
1477 // Tests that when a synchronous menu receives a cancel event, that it closes. | |
1478 TEST_F(MenuControllerTest, SynchronousCancelEvent) { | |
1479 ExitMenuRun(); | |
1480 // Post actual test to run once the menu has created a nested message loop. | |
1481 base::ThreadTaskRunnerHandle::Get()->PostTask( | |
1482 FROM_HERE, | |
1483 base::Bind(&MenuControllerTest::TestCancelEvent, base::Unretained(this))); | |
1484 int mouse_event_flags = 0; | |
1485 MenuItemView* run_result = menu_controller()->Run( | |
1486 owner(), nullptr, menu_item(), gfx::Rect(), MENU_ANCHOR_TOPLEFT, false, | |
1487 false, &mouse_event_flags); | |
1488 EXPECT_EQ(run_result, nullptr); | |
1489 } | |
1490 | |
1491 // Tests that when an asynchronous menu receives a cancel event, that it closes. | 1302 // Tests that when an asynchronous menu receives a cancel event, that it closes. |
1492 TEST_F(MenuControllerTest, AsynchronousCancelEvent) { | 1303 TEST_F(MenuControllerTest, AsynchronousCancelEvent) { |
1493 ExitMenuRun(); | 1304 ExitMenuRun(); |
1494 MenuController* controller = menu_controller(); | 1305 MenuController* controller = menu_controller(); |
1495 controller->SetAsyncRun(true); | |
1496 | 1306 |
1497 int mouse_event_flags = 0; | 1307 int mouse_event_flags = 0; |
1498 MenuItemView* run_result = | 1308 MenuItemView* run_result = |
1499 controller->Run(owner(), nullptr, menu_item(), gfx::Rect(), | 1309 controller->Run(owner(), nullptr, menu_item(), gfx::Rect(), |
1500 MENU_ANCHOR_TOPLEFT, false, false, &mouse_event_flags); | 1310 MENU_ANCHOR_TOPLEFT, false, false, &mouse_event_flags); |
1501 EXPECT_EQ(run_result, nullptr); | 1311 EXPECT_EQ(run_result, nullptr); |
1502 TestCancelEvent(); | 1312 TestCancelEvent(); |
1503 } | 1313 } |
1504 | 1314 |
1505 // Tests that if a menu is ran without a widget, that MenuPreTargetHandler does | 1315 // Tests that if a menu is ran without a widget, that MenuPreTargetHandler does |
1506 // not cause a crash. | 1316 // not cause a crash. |
1507 TEST_F(MenuControllerTest, RunWithoutWidgetDoesntCrash) { | 1317 TEST_F(MenuControllerTest, RunWithoutWidgetDoesntCrash) { |
1508 ExitMenuRun(); | 1318 ExitMenuRun(); |
1509 MenuController* controller = menu_controller(); | 1319 MenuController* controller = menu_controller(); |
1510 controller->SetAsyncRun(true); | |
1511 int mouse_event_flags = 0; | 1320 int mouse_event_flags = 0; |
1512 MenuItemView* run_result = | 1321 MenuItemView* run_result = |
1513 controller->Run(nullptr, nullptr, menu_item(), gfx::Rect(), | 1322 controller->Run(nullptr, nullptr, menu_item(), gfx::Rect(), |
1514 MENU_ANCHOR_TOPLEFT, false, false, &mouse_event_flags); | 1323 MENU_ANCHOR_TOPLEFT, false, false, &mouse_event_flags); |
1515 EXPECT_EQ(run_result, nullptr); | 1324 EXPECT_EQ(run_result, nullptr); |
1516 } | 1325 } |
1517 | 1326 |
1518 // Tests that if a MenuController is destroying during drag/drop, and another | 1327 // Tests that if a MenuController is destroying during drag/drop, and another |
1519 // MenuController becomes active, that the exiting of drag does not cause a | 1328 // MenuController becomes active, that the exiting of drag does not cause a |
1520 // crash. | 1329 // crash. |
(...skipping 10 matching lines...) Expand all Loading... |
1531 ->GetNativeWindow() | 1340 ->GetNativeWindow() |
1532 ->GetRootWindow(), | 1341 ->GetRootWindow(), |
1533 &drag_drop_client); | 1342 &drag_drop_client); |
1534 StartDrag(); | 1343 StartDrag(); |
1535 } | 1344 } |
1536 | 1345 |
1537 // Tests that if a CancelAll is called during drag-and-drop that it does not | 1346 // Tests that if a CancelAll is called during drag-and-drop that it does not |
1538 // destroy the MenuController. On Windows and Linux this destruction also | 1347 // destroy the MenuController. On Windows and Linux this destruction also |
1539 // destroys the Widget used for drag-and-drop, thereby ending the drag. | 1348 // destroys the Widget used for drag-and-drop, thereby ending the drag. |
1540 TEST_F(MenuControllerTest, CancelAllDuringDrag) { | 1349 TEST_F(MenuControllerTest, CancelAllDuringDrag) { |
1541 MenuController* controller = menu_controller(); | |
1542 controller->SetAsyncRun(true); | |
1543 | |
1544 // Build the menu so that the appropriate root window is available to set the | 1350 // Build the menu so that the appropriate root window is available to set the |
1545 // drag drop client on. | 1351 // drag drop client on. |
1546 AddButtonMenuItems(); | 1352 AddButtonMenuItems(); |
1547 TestDragDropClient drag_drop_client(base::Bind( | 1353 TestDragDropClient drag_drop_client(base::Bind( |
1548 &MenuControllerTest::TestCancelAllDuringDrag, base::Unretained(this))); | 1354 &MenuControllerTest::TestCancelAllDuringDrag, base::Unretained(this))); |
1549 aura::client::SetDragDropClient(menu_item() | 1355 aura::client::SetDragDropClient(menu_item() |
1550 ->GetSubmenu() | 1356 ->GetSubmenu() |
1551 ->GetWidget() | 1357 ->GetWidget() |
1552 ->GetNativeWindow() | 1358 ->GetNativeWindow() |
1553 ->GetRootWindow(), | 1359 ->GetRootWindow(), |
1554 &drag_drop_client); | 1360 &drag_drop_client); |
1555 StartDrag(); | 1361 StartDrag(); |
1556 } | 1362 } |
1557 | 1363 |
1558 // Tests that when releasing the ref on ViewsDelegate and MenuController is | 1364 // Tests that when releasing the ref on ViewsDelegate and MenuController is |
1559 // deleted, that shutdown occurs without crashing. | 1365 // deleted, that shutdown occurs without crashing. |
1560 TEST_F(MenuControllerTest, DestroyedDuringViewsRelease) { | 1366 TEST_F(MenuControllerTest, DestroyedDuringViewsRelease) { |
1561 ExitMenuRun(); | 1367 ExitMenuRun(); |
1562 MenuController* controller = menu_controller(); | 1368 MenuController* controller = menu_controller(); |
1563 controller->SetAsyncRun(true); | |
1564 | 1369 |
1565 int mouse_event_flags = 0; | 1370 int mouse_event_flags = 0; |
1566 MenuItemView* run_result = | 1371 MenuItemView* run_result = |
1567 controller->Run(owner(), nullptr, menu_item(), gfx::Rect(), | 1372 controller->Run(owner(), nullptr, menu_item(), gfx::Rect(), |
1568 MENU_ANCHOR_TOPLEFT, false, false, &mouse_event_flags); | 1373 MENU_ANCHOR_TOPLEFT, false, false, &mouse_event_flags); |
1569 EXPECT_EQ(run_result, nullptr); | 1374 EXPECT_EQ(run_result, nullptr); |
1570 TestDestroyedDuringViewsRelease(); | 1375 TestDestroyedDuringViewsRelease(); |
1571 } | 1376 } |
1572 | 1377 |
1573 #endif // defined(USE_AURA) | 1378 #endif // defined(USE_AURA) |
1574 | 1379 |
1575 } // namespace test | 1380 } // namespace test |
1576 } // namespace views | 1381 } // namespace views |
OLD | NEW |