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

Side by Side Diff: ui/views/controls/menu/menu_controller_unittest.cc

Issue 2155243007: Turn Bookmark Menus Async (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Merge the pretarget handlers Created 4 years, 4 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 | « ui/views/controls/menu/menu_controller.cc ('k') | ui/views/controls/menu/menu_host.h » ('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 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/macros.h" 8 #include "base/macros.h"
9 #include "base/single_thread_task_runner.h" 9 #include "base/single_thread_task_runner.h"
10 #include "base/strings/utf_string_conversions.h" 10 #include "base/strings/utf_string_conversions.h"
11 #include "build/build_config.h" 11 #include "build/build_config.h"
12 #include "ui/aura/scoped_window_targeter.h" 12 #include "ui/aura/scoped_window_targeter.h"
13 #include "ui/aura/window.h" 13 #include "ui/aura/window.h"
14 #include "ui/events/event.h" 14 #include "ui/events/event.h"
15 #include "ui/events/event_constants.h" 15 #include "ui/events/event_constants.h"
16 #include "ui/events/event_handler.h" 16 #include "ui/events/event_handler.h"
17 #include "ui/events/event_utils.h" 17 #include "ui/events/event_utils.h"
18 #include "ui/events/null_event_targeter.h" 18 #include "ui/events/null_event_targeter.h"
19 #include "ui/events/test/event_generator.h" 19 #include "ui/events/test/event_generator.h"
20 #include "ui/gfx/geometry/point.h" 20 #include "ui/gfx/geometry/point.h"
21 #include "ui/gfx/geometry/rect.h" 21 #include "ui/gfx/geometry/rect.h"
22 #include "ui/views/controls/menu/menu_controller_delegate.h" 22 #include "ui/views/controls/menu/menu_controller_delegate.h"
23 #include "ui/views/controls/menu/menu_delegate.h" 23 #include "ui/views/controls/menu/menu_delegate.h"
24 #include "ui/views/controls/menu/menu_host.h"
24 #include "ui/views/controls/menu/menu_item_view.h" 25 #include "ui/views/controls/menu/menu_item_view.h"
25 #include "ui/views/controls/menu/menu_message_loop.h" 26 #include "ui/views/controls/menu/menu_message_loop.h"
26 #include "ui/views/controls/menu/menu_scroll_view_container.h" 27 #include "ui/views/controls/menu/menu_scroll_view_container.h"
27 #include "ui/views/controls/menu/submenu_view.h" 28 #include "ui/views/controls/menu/submenu_view.h"
28 #include "ui/views/test/menu_test_utils.h" 29 #include "ui/views/test/menu_test_utils.h"
29 #include "ui/views/test/views_test_base.h" 30 #include "ui/views/test/views_test_base.h"
30 31
31 #if defined(USE_AURA) 32 #if defined(USE_AURA)
32 #include "ui/aura/scoped_window_targeter.h" 33 #include "ui/aura/scoped_window_targeter.h"
33 #include "ui/aura/window.h" 34 #include "ui/aura/window.h"
34 #include "ui/views/controls/menu/menu_key_event_handler.h" 35 #include "ui/views/controls/menu/menu_pre_target_handler.h"
35 #endif 36 #endif
36 37
37 #if defined(USE_X11) 38 #if defined(USE_X11)
38 #include <X11/Xlib.h> 39 #include <X11/Xlib.h>
39 #undef Bool 40 #undef Bool
40 #undef None 41 #undef None
41 #include "ui/events/test/events_test_utils_x11.h" 42 #include "ui/events/test/events_test_utils_x11.h"
42 #endif 43 #endif
43 44
44 namespace views { 45 namespace views {
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
153 explicit TestMenuMessageLoop(std::unique_ptr<MenuMessageLoop> original); 154 explicit TestMenuMessageLoop(std::unique_ptr<MenuMessageLoop> original);
154 ~TestMenuMessageLoop() override; 155 ~TestMenuMessageLoop() override;
155 156
156 bool is_running() const { return is_running_; } 157 bool is_running() const { return is_running_; }
157 158
158 // MenuMessageLoop: 159 // MenuMessageLoop:
159 void QuitNow() override; 160 void QuitNow() override;
160 161
161 private: 162 private:
162 // MenuMessageLoop: 163 // MenuMessageLoop:
163 void Run(MenuController* controller, 164 void Run() override;
164 Widget* owner,
165 bool nested_menu) override;
166 void ClearOwner() override;
167 165
168 std::unique_ptr<MenuMessageLoop> original_; 166 std::unique_ptr<MenuMessageLoop> original_;
169 bool is_running_; 167 bool is_running_;
170 168
171 DISALLOW_COPY_AND_ASSIGN(TestMenuMessageLoop); 169 DISALLOW_COPY_AND_ASSIGN(TestMenuMessageLoop);
172 }; 170 };
173 171
174 TestMenuMessageLoop::TestMenuMessageLoop( 172 TestMenuMessageLoop::TestMenuMessageLoop(
175 std::unique_ptr<MenuMessageLoop> original) 173 std::unique_ptr<MenuMessageLoop> original)
176 : original_(std::move(original)) { 174 : original_(std::move(original)) {
177 DCHECK(original_); 175 DCHECK(original_);
178 } 176 }
179 177
180 TestMenuMessageLoop::~TestMenuMessageLoop() {} 178 TestMenuMessageLoop::~TestMenuMessageLoop() {}
181 179
182 void TestMenuMessageLoop::Run(MenuController* controller, 180 void TestMenuMessageLoop::Run() {
183 Widget* owner,
184 bool nested_menu) {
185 is_running_ = true; 181 is_running_ = true;
186 original_->Run(controller, owner, nested_menu); 182 original_->Run();
187 } 183 }
188 184
189 void TestMenuMessageLoop::QuitNow() { 185 void TestMenuMessageLoop::QuitNow() {
190 is_running_ = false; 186 is_running_ = false;
191 original_->QuitNow(); 187 original_->QuitNow();
192 } 188 }
193 189
194 void TestMenuMessageLoop::ClearOwner() {
195 original_->ClearOwner();
196 }
197
198 } // namespace 190 } // namespace
199 191
200 class TestMenuItemViewShown : public MenuItemView { 192 class TestMenuItemViewShown : public MenuItemView {
201 public: 193 public:
202 TestMenuItemViewShown(MenuDelegate* delegate) : MenuItemView(delegate) { 194 TestMenuItemViewShown(MenuDelegate* delegate) : MenuItemView(delegate) {
203 submenu_ = new SubmenuViewShown(this); 195 submenu_ = new SubmenuViewShown(this);
204 } 196 }
205 ~TestMenuItemViewShown() override {} 197 ~TestMenuItemViewShown() override {}
206 198
207 void SetController(MenuController* controller) { 199 void SetController(MenuController* controller) {
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
250 event_generator_->PressKey(ui::VKEY_ESCAPE, 0); 242 event_generator_->PressKey(ui::VKEY_ESCAPE, 0);
251 EXPECT_EQ(MenuController::EXIT_NONE, menu_exit_type()); 243 EXPECT_EQ(MenuController::EXIT_NONE, menu_exit_type());
252 } 244 }
253 // Now that the targeter has been destroyed, expect to exit the menu 245 // Now that the targeter has been destroyed, expect to exit the menu
254 // normally when hitting escape. 246 // normally when hitting escape.
255 event_generator_->PressKey(ui::VKEY_ESCAPE, 0); 247 event_generator_->PressKey(ui::VKEY_ESCAPE, 0);
256 EXPECT_EQ(MenuController::EXIT_OUTERMOST, menu_exit_type()); 248 EXPECT_EQ(MenuController::EXIT_OUTERMOST, menu_exit_type());
257 } 249 }
258 #endif // defined(OS_LINUX) && defined(USE_X11) 250 #endif // defined(OS_LINUX) && defined(USE_X11)
259 251
252 #if defined(USE_AURA)
253 // Verifies that an open menu receives a cancel event, and closes.
254 void TestCancelEvent() {
255 EXPECT_EQ(MenuController::EXIT_NONE, menu_controller_->exit_type());
256 ui::CancelModeEvent cancel_event;
257 event_generator_->Dispatch(&cancel_event);
258 EXPECT_EQ(MenuController::EXIT_ALL, menu_controller_->exit_type());
259 }
260 #endif // defined(USE_AURA)
261
260 void TestAsynchronousNestedExitAll() { 262 void TestAsynchronousNestedExitAll() {
261 ASSERT_TRUE(test_message_loop_->is_running()); 263 ASSERT_TRUE(test_message_loop_->is_running());
262 264
263 std::unique_ptr<TestMenuControllerDelegate> nested_delegate( 265 std::unique_ptr<TestMenuControllerDelegate> nested_delegate(
264 new TestMenuControllerDelegate()); 266 new TestMenuControllerDelegate());
265 267
266 menu_controller()->AddNestedDelegate(nested_delegate.get()); 268 menu_controller()->AddNestedDelegate(nested_delegate.get());
267 menu_controller()->SetAsyncRun(true); 269 menu_controller()->SetAsyncRun(true);
268 270
269 int mouse_event_flags = 0; 271 int mouse_event_flags = 0;
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
371 } 373 }
372 374
373 internal::MenuControllerDelegate* GetCurrentDelegate() { 375 internal::MenuControllerDelegate* GetCurrentDelegate() {
374 return menu_controller_->delegate_; 376 return menu_controller_->delegate_;
375 } 377 }
376 378
377 bool IsAsyncRun() { return menu_controller_->async_run_; } 379 bool IsAsyncRun() { return menu_controller_->async_run_; }
378 380
379 bool IsShowing() { return menu_controller_->showing_; } 381 bool IsShowing() { return menu_controller_->showing_; }
380 382
383 MenuHost* GetMenuHost(SubmenuView* submenu) { return submenu->host_; }
384
385 void MenuHostOnDragWillStart(MenuHost* host) { host->OnDragWillStart(); }
386
387 void MenuHostOnDragComplete(MenuHost* host) { host->OnDragComplete(); }
388
381 void SelectByChar(base::char16 character) { 389 void SelectByChar(base::char16 character) {
382 menu_controller_->SelectByChar(character); 390 menu_controller_->SelectByChar(character);
383 } 391 }
384 392
385 void SetDropMenuItem(MenuItemView* target, 393 void SetDropMenuItem(MenuItemView* target,
386 MenuDelegate::DropPosition position) { 394 MenuDelegate::DropPosition position) {
387 menu_controller_->SetDropMenuItem(target, position); 395 menu_controller_->SetDropMenuItem(target, position);
388 } 396 }
389 397
390 void SetIsCombobox(bool is_combobox) { 398 void SetIsCombobox(bool is_combobox) {
391 menu_controller_->set_is_combobox(is_combobox); 399 menu_controller_->set_is_combobox(is_combobox);
392 } 400 }
393 401
394 void SetSelectionOnPointerDown(SubmenuView* source, 402 void SetSelectionOnPointerDown(SubmenuView* source,
395 const ui::LocatedEvent* event) { 403 const ui::LocatedEvent* event) {
396 menu_controller_->SetSelectionOnPointerDown(source, event); 404 menu_controller_->SetSelectionOnPointerDown(source, event);
397 } 405 }
398 406
399 // Note that coordinates of events passed to MenuController must be in that of 407 // Note that coordinates of events passed to MenuController must be in that of
400 // the MenuScrollViewContainer. 408 // the MenuScrollViewContainer.
401 void ProcessMouseMoved(SubmenuView* source, const ui::MouseEvent& event) { 409 void ProcessMouseMoved(SubmenuView* source, const ui::MouseEvent& event) {
402 menu_controller_->OnMouseMoved(source, event); 410 menu_controller_->OnMouseMoved(source, event);
403 } 411 }
404 412
405 void RunMenu() { 413 void RunMenu() {
406 #if defined(USE_AURA) 414 #if defined(USE_AURA)
407 std::unique_ptr<MenuKeyEventHandler> key_event_handler( 415 std::unique_ptr<MenuPreTargetHandler> menu_pre_target_handler(
408 new MenuKeyEventHandler); 416 new MenuPreTargetHandler(menu_controller_, owner_.get()));
409 #endif 417 #endif
410 418
411 menu_controller_->message_loop_depth_++; 419 menu_controller_->message_loop_depth_++;
412 menu_controller_->RunMessageLoop(false); 420 menu_controller_->RunMessageLoop();
413 menu_controller_->message_loop_depth_--; 421 menu_controller_->message_loop_depth_--;
414 } 422 }
415 423
416 void Accept(MenuItemView* item, int event_flags) { 424 void Accept(MenuItemView* item, int event_flags) {
417 menu_controller_->Accept(item, event_flags); 425 menu_controller_->Accept(item, event_flags);
418 } 426 }
419 427
420 void InstallTestMenuMessageLoop() { 428 void InstallTestMenuMessageLoop() {
421 test_message_loop_ = 429 test_message_loop_ =
422 new TestMenuMessageLoop(std::move(menu_controller_->message_loop_)); 430 new TestMenuMessageLoop(std::move(menu_controller_->message_loop_));
(...skipping 21 matching lines...) Expand all
444 for (int i = 0; i < 3; ++i) { 452 for (int i = 0; i < 3; ++i) {
445 LabelButton* button = 453 LabelButton* button =
446 new LabelButton(nullptr, base::ASCIIToUTF16("Label")); 454 new LabelButton(nullptr, base::ASCIIToUTF16("Label"));
447 // This is an in-menu button. Hence it must be always focusable. 455 // This is an in-menu button. Hence it must be always focusable.
448 button->SetFocusBehavior(View::FocusBehavior::ALWAYS); 456 button->SetFocusBehavior(View::FocusBehavior::ALWAYS);
449 item_view->AddChildView(button); 457 item_view->AddChildView(button);
450 } 458 }
451 menu_item()->GetSubmenu()->ShowAt(owner(), menu_item()->bounds(), false); 459 menu_item()->GetSubmenu()->ShowAt(owner(), menu_item()->bounds(), false);
452 } 460 }
453 461
462 void DestroyMenuItem() { menu_item_.reset(); }
463
454 CustomButton* GetHotButton() { 464 CustomButton* GetHotButton() {
455 return menu_controller_->hot_button_; 465 return menu_controller_->hot_button_;
456 } 466 }
457 467
458 void SetHotTrackedButton(CustomButton* hot_button) { 468 void SetHotTrackedButton(CustomButton* hot_button) {
459 menu_controller_->SetHotTrackedButton(hot_button); 469 menu_controller_->SetHotTrackedButton(hot_button);
460 } 470 }
461 471
462 void ExitMenuRun() { 472 void ExitMenuRun() {
463 menu_controller_->SetExitType(MenuController::ExitType::EXIT_OUTERMOST); 473 menu_controller_->SetExitType(MenuController::ExitType::EXIT_OUTERMOST);
(...skipping 548 matching lines...) Expand 10 before | Expand all | Expand 10 after
1012 1022
1013 EXPECT_FALSE(controller->drag_in_progress()); 1023 EXPECT_FALSE(controller->drag_in_progress());
1014 TestMenuControllerDelegate* controller_delegate = menu_controller_delegate(); 1024 TestMenuControllerDelegate* controller_delegate = menu_controller_delegate();
1015 EXPECT_EQ(1, controller_delegate->on_menu_closed_called()); 1025 EXPECT_EQ(1, controller_delegate->on_menu_closed_called());
1016 EXPECT_EQ(nullptr, controller_delegate->on_menu_closed_menu()); 1026 EXPECT_EQ(nullptr, controller_delegate->on_menu_closed_menu());
1017 EXPECT_EQ(internal::MenuControllerDelegate::NOTIFY_DELEGATE, 1027 EXPECT_EQ(internal::MenuControllerDelegate::NOTIFY_DELEGATE,
1018 controller_delegate->on_menu_closed_notify_type()); 1028 controller_delegate->on_menu_closed_notify_type());
1019 EXPECT_EQ(MenuController::EXIT_ALL, controller->exit_type()); 1029 EXPECT_EQ(MenuController::EXIT_ALL, controller->exit_type());
1020 } 1030 }
1021 1031
1032 // Tests that if a menu is destroyed while drag operations are occuring, that
1033 // the MenuHost does not crash as the drag completes.
1034 TEST_F(MenuControllerTest, AsynchronousDragHostDeleted) {
1035 MenuController* controller = menu_controller();
1036 controller->SetAsyncRun(true);
1037
1038 SubmenuView* submenu = menu_item()->GetSubmenu();
1039 submenu->ShowAt(owner(), menu_item()->bounds(), false);
1040 MenuHost* host = GetMenuHost(submenu);
1041 MenuHostOnDragWillStart(host);
1042 submenu->Close();
1043 DestroyMenuItem();
1044 MenuHostOnDragComplete(host);
1045 }
1046
1022 // Tets that an asynchronous menu nested within an asynchronous menu closes both 1047 // Tets that an asynchronous menu nested within an asynchronous menu closes both
1023 // menus, and notifies both delegates. 1048 // menus, and notifies both delegates.
1024 TEST_F(MenuControllerTest, DoubleAsynchronousNested) { 1049 TEST_F(MenuControllerTest, DoubleAsynchronousNested) {
1025 MenuController* controller = menu_controller(); 1050 MenuController* controller = menu_controller();
1026 TestMenuControllerDelegate* delegate = menu_controller_delegate(); 1051 TestMenuControllerDelegate* delegate = menu_controller_delegate();
1027 std::unique_ptr<TestMenuControllerDelegate> nested_delegate( 1052 std::unique_ptr<TestMenuControllerDelegate> nested_delegate(
1028 new TestMenuControllerDelegate()); 1053 new TestMenuControllerDelegate());
1029 1054
1030 ASSERT_FALSE(IsAsyncRun()); 1055 ASSERT_FALSE(IsAsyncRun());
1031 // Sets the run created in SetUp 1056 // Sets the run created in SetUp
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after
1244 1269
1245 int result_event_flags = 0; 1270 int result_event_flags = 0;
1246 // This creates a nested message loop. 1271 // This creates a nested message loop.
1247 EXPECT_EQ(nullptr, menu_controller()->Run(owner(), nullptr, menu_item(), 1272 EXPECT_EQ(nullptr, menu_controller()->Run(owner(), nullptr, menu_item(),
1248 gfx::Rect(), MENU_ANCHOR_TOPLEFT, 1273 gfx::Rect(), MENU_ANCHOR_TOPLEFT,
1249 false, false, &result_event_flags)); 1274 false, false, &result_event_flags));
1250 EXPECT_FALSE(menu_controller_delegate()->on_menu_closed_called()); 1275 EXPECT_FALSE(menu_controller_delegate()->on_menu_closed_called());
1251 EXPECT_TRUE(nested_delegate->on_menu_closed_called()); 1276 EXPECT_TRUE(nested_delegate->on_menu_closed_called());
1252 } 1277 }
1253 1278
1279 #if defined(USE_AURA)
1280 // Tests that when a synchronous menu receives a cancel event, that it closes.
1281 TEST_F(MenuControllerTest, SynchronousCancelEvent) {
1282 ExitMenuRun();
1283 // Post actual test to run once the menu has created a nested message loop.
1284 base::MessageLoopForUI::current()->PostTask(
1285 FROM_HERE,
1286 base::Bind(&MenuControllerTest::TestCancelEvent, base::Unretained(this)));
1287 int mouse_event_flags = 0;
1288 MenuItemView* run_result = menu_controller()->Run(
1289 owner(), nullptr, menu_item(), gfx::Rect(), MENU_ANCHOR_TOPLEFT, false,
1290 false, &mouse_event_flags);
1291 EXPECT_EQ(run_result, nullptr);
1292 }
1293
1294 // Tests that when an asynchronous menu receives a cancel event, that it closes.
1295 TEST_F(MenuControllerTest, AsynchronousCancelEvent) {
1296 ExitMenuRun();
1297 MenuController* controller = menu_controller();
1298 controller->SetAsyncRun(true);
1299
1300 int mouse_event_flags = 0;
1301 MenuItemView* run_result =
1302 controller->Run(owner(), nullptr, menu_item(), gfx::Rect(),
1303 MENU_ANCHOR_TOPLEFT, false, false, &mouse_event_flags);
1304 EXPECT_EQ(run_result, nullptr);
1305 TestCancelEvent();
1306 }
1307 #endif // defined(USE_AURA)
1308
1254 } // namespace test 1309 } // namespace test
1255 } // namespace views 1310 } // namespace views
OLDNEW
« no previous file with comments | « ui/views/controls/menu/menu_controller.cc ('k') | ui/views/controls/menu/menu_host.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698