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

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

Issue 1515203002: Update closing of nested asynchronous menus (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix Memory 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
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 "ui/views/controls/menu/menu_controller.h" 5 #include "ui/views/controls/menu/menu_controller.h"
6 6
7 #include "base/i18n/case_conversion.h" 7 #include "base/i18n/case_conversion.h"
8 #include "base/i18n/rtl.h" 8 #include "base/i18n/rtl.h"
9 #include "base/macros.h" 9 #include "base/macros.h"
10 #include "base/strings/utf_string_conversions.h" 10 #include "base/strings/utf_string_conversions.h"
(...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after
411 if (!blocking_run_) { 411 if (!blocking_run_) {
412 // If we didn't block the caller we need to notify the menu, which 412 // If we didn't block the caller we need to notify the menu, which
413 // triggers deleting us. 413 // triggers deleting us.
414 DCHECK(selected); 414 DCHECK(selected);
415 showing_ = false; 415 showing_ = false;
416 delegate_->OnMenuClosed(internal::MenuControllerDelegate::NOTIFY_DELEGATE, 416 delegate_->OnMenuClosed(internal::MenuControllerDelegate::NOTIFY_DELEGATE,
417 selected->GetRootMenuItem(), accept_event_flags_); 417 selected->GetRootMenuItem(), accept_event_flags_);
418 // WARNING: the call to MenuClosed deletes us. 418 // WARNING: the call to MenuClosed deletes us.
419 return; 419 return;
420 } 420 }
421 if (async_run_) { 421 ExitAsyncRun();
422 internal::MenuControllerDelegate* delegate = delegate_;
423 MenuItemView* result = ExitMenuRun();
424 delegate->OnMenuClosed(internal::MenuControllerDelegate::NOTIFY_DELEGATE,
425 result, accept_event_flags_);
426 }
427 } 422 }
428 423
429 void MenuController::AddNestedDelegate( 424 void MenuController::AddNestedDelegate(
430 internal::MenuControllerDelegate* delegate) { 425 internal::MenuControllerDelegate* delegate) {
431 delegate_stack_.push_back(std::make_pair(delegate, async_run_)); 426 delegate_stack_.push_back(std::make_pair(delegate, async_run_));
432 delegate_ = delegate; 427 delegate_ = delegate;
433 } 428 }
434 429
435 void MenuController::SetAsyncRun(bool is_async) { 430 void MenuController::SetAsyncRun(bool is_async) {
436 delegate_stack_.back().second = is_async; 431 delegate_stack_.back().second = is_async;
(...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after
850 DCHECK(drag_in_progress_); 845 DCHECK(drag_in_progress_);
851 drag_in_progress_ = false; 846 drag_in_progress_ = false;
852 // During a drag, mouse events are processed directly by the widget, and not 847 // During a drag, mouse events are processed directly by the widget, and not
853 // sent to the MenuController. At drag completion, reset pressed state and 848 // sent to the MenuController. At drag completion, reset pressed state and
854 // the event target. 849 // the event target.
855 current_mouse_pressed_state_ = 0; 850 current_mouse_pressed_state_ = 0;
856 current_mouse_event_target_ = nullptr; 851 current_mouse_event_target_ = nullptr;
857 if (showing_ && should_close && GetActiveInstance() == this) { 852 if (showing_ && should_close && GetActiveInstance() == this) {
858 CloseAllNestedMenus(); 853 CloseAllNestedMenus();
859 Cancel(EXIT_ALL); 854 Cancel(EXIT_ALL);
855 } else if (async_run_) {
856 ExitAsyncRun();
860 } 857 }
861 } 858 }
862 859
863 ui::PostDispatchAction MenuController::OnWillDispatchKeyEvent( 860 ui::PostDispatchAction MenuController::OnWillDispatchKeyEvent(
864 base::char16 character, 861 base::char16 character,
865 ui::KeyboardCode key_code) { 862 ui::KeyboardCode key_code) {
866 if (exit_type() == MenuController::EXIT_ALL || 863 if (exit_type() == MenuController::EXIT_ALL ||
867 exit_type() == MenuController::EXIT_DESTROYED) { 864 exit_type() == MenuController::EXIT_DESTROYED) {
868 TerminateNestedMessageLoopIfNecessary(); 865 TerminateNestedMessageLoopIfNecessary();
869 return ui::POST_DISPATCH_PERFORM_DEFAULT; 866 return ui::POST_DISPATCH_PERFORM_DEFAULT;
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
1065 item->GetDelegate()->WriteDragData(item, &data); 1062 item->GetDelegate()->WriteDragData(item, &data);
1066 drag_utils::SetDragImageOnDataObject(*canvas, 1063 drag_utils::SetDragImageOnDataObject(*canvas,
1067 press_loc.OffsetFromOrigin(), 1064 press_loc.OffsetFromOrigin(),
1068 &data); 1065 &data);
1069 StopScrolling(); 1066 StopScrolling();
1070 int drag_ops = item->GetDelegate()->GetDragOperations(item); 1067 int drag_ops = item->GetDelegate()->GetDragOperations(item);
1071 did_initiate_drag_ = true; 1068 did_initiate_drag_ = true;
1072 // TODO(varunjain): Properly determine and send DRAG_EVENT_SOURCE below. 1069 // TODO(varunjain): Properly determine and send DRAG_EVENT_SOURCE below.
1073 item->GetWidget()->RunShellDrag(NULL, data, widget_loc, drag_ops, 1070 item->GetWidget()->RunShellDrag(NULL, data, widget_loc, drag_ops,
1074 ui::DragDropTypes::DRAG_EVENT_SOURCE_MOUSE); 1071 ui::DragDropTypes::DRAG_EVENT_SOURCE_MOUSE);
1075 did_initiate_drag_ = false; 1072 if (GetActiveInstance())
sky 2016/01/11 20:56:04 Please add a comment as to why this check is neces
jonross 2016/01/11 21:27:15 Done.
1073 did_initiate_drag_ = false;
1076 } 1074 }
1077 1075
1078 void MenuController::OnKeyDown(ui::KeyboardCode key_code) { 1076 void MenuController::OnKeyDown(ui::KeyboardCode key_code) {
1079 DCHECK(blocking_run_); 1077 DCHECK(blocking_run_);
1080 1078
1081 switch (key_code) { 1079 switch (key_code) {
1082 case ui::VKEY_UP: 1080 case ui::VKEY_UP:
1083 IncrementSelection(INCREMENT_SELECTION_UP); 1081 IncrementSelection(INCREMENT_SELECTION_UP);
1084 break; 1082 break;
1085 1083
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
1268 void MenuController::Accept(MenuItemView* item, int event_flags) { 1266 void MenuController::Accept(MenuItemView* item, int event_flags) {
1269 DCHECK(IsBlockingRun()); 1267 DCHECK(IsBlockingRun());
1270 result_ = item; 1268 result_ = item;
1271 if (item && !menu_stack_.empty() && 1269 if (item && !menu_stack_.empty() &&
1272 !item->GetDelegate()->ShouldCloseAllMenusOnExecute(item->GetCommand())) { 1270 !item->GetDelegate()->ShouldCloseAllMenusOnExecute(item->GetCommand())) {
1273 SetExitType(EXIT_OUTERMOST); 1271 SetExitType(EXIT_OUTERMOST);
1274 } else { 1272 } else {
1275 SetExitType(EXIT_ALL); 1273 SetExitType(EXIT_ALL);
1276 } 1274 }
1277 accept_event_flags_ = event_flags; 1275 accept_event_flags_ = event_flags;
1278 if (async_run_) { 1276 ExitAsyncRun();
1279 internal::MenuControllerDelegate* delegate = delegate_;
1280 MenuItemView* result = ExitMenuRun();
1281 delegate->OnMenuClosed(internal::MenuControllerDelegate::NOTIFY_DELEGATE,
1282 result, accept_event_flags_);
1283 }
1284 } 1277 }
1285 1278
1286 bool MenuController::ShowSiblingMenu(SubmenuView* source, 1279 bool MenuController::ShowSiblingMenu(SubmenuView* source,
1287 const gfx::Point& mouse_location) { 1280 const gfx::Point& mouse_location) {
1288 if (!menu_stack_.empty() || !pressed_lock_.get()) 1281 if (!menu_stack_.empty() || !pressed_lock_.get())
1289 return false; 1282 return false;
1290 1283
1291 View* source_view = source->GetScrollViewContainer(); 1284 View* source_view = source->GetScrollViewContainer();
1292 if (mouse_location.x() >= 0 && 1285 if (mouse_location.x() >= 0 &&
1293 mouse_location.x() < source_view->width() && 1286 mouse_location.x() < source_view->width() &&
(...skipping 1116 matching lines...) Expand 10 before | Expand all | Expand 10 after
2410 2403
2411 bool MenuController::TerminateNestedMessageLoopIfNecessary() { 2404 bool MenuController::TerminateNestedMessageLoopIfNecessary() {
2412 // It is necessary to check both |async_run_| and |message_loop_depth_| 2405 // It is necessary to check both |async_run_| and |message_loop_depth_|
2413 // because the topmost async menu could be nested in a sync parent menu. 2406 // because the topmost async menu could be nested in a sync parent menu.
2414 bool quit_now = !async_run_ && exit_type_ != EXIT_NONE && message_loop_depth_; 2407 bool quit_now = !async_run_ && exit_type_ != EXIT_NONE && message_loop_depth_;
2415 if (quit_now) 2408 if (quit_now)
2416 message_loop_->QuitNow(); 2409 message_loop_->QuitNow();
2417 return quit_now; 2410 return quit_now;
2418 } 2411 }
2419 2412
2413 void MenuController::ExitAsyncRun() {
2414 if (!async_run_)
2415 return;
2416 bool nested = delegate_stack_.size() > 1;
2417 // ExitMenuRun unwinds nested delegates
2418 internal::MenuControllerDelegate* delegate = delegate_;
2419 MenuItemView* result = ExitMenuRun();
2420 delegate->OnMenuClosed(internal::MenuControllerDelegate::NOTIFY_DELEGATE,
2421 result, accept_event_flags_);
2422 if (nested && exit_type_ == EXIT_ALL)
2423 ExitAsyncRun();
2424 }
2425
2420 MenuItemView* MenuController::ExitMenuRun() { 2426 MenuItemView* MenuController::ExitMenuRun() {
2421 // Release the lock which prevents Chrome from shutting down while the menu is 2427 // Release the lock which prevents Chrome from shutting down while the menu is
2422 // showing. 2428 // showing.
2423 if (async_run_ && ViewsDelegate::GetInstance()) 2429 if (async_run_ && ViewsDelegate::GetInstance())
2424 ViewsDelegate::GetInstance()->ReleaseRef(); 2430 ViewsDelegate::GetInstance()->ReleaseRef();
2425 2431
2426 // Close any open menus. 2432 // Close any open menus.
2427 SetSelection(nullptr, SELECTION_UPDATE_IMMEDIATELY | SELECTION_EXIT); 2433 SetSelection(nullptr, SELECTION_UPDATE_IMMEDIATELY | SELECTION_EXIT);
2428 2434
2429 #if defined(OS_WIN) 2435 #if defined(OS_WIN)
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
2528 } 2534 }
2529 } 2535 }
2530 2536
2531 gfx::Screen* MenuController::GetScreen() { 2537 gfx::Screen* MenuController::GetScreen() {
2532 Widget* root = owner_ ? owner_->GetTopLevelWidget() : NULL; 2538 Widget* root = owner_ ? owner_->GetTopLevelWidget() : NULL;
2533 return root ? gfx::Screen::GetScreenFor(root->GetNativeView()) 2539 return root ? gfx::Screen::GetScreenFor(root->GetNativeView())
2534 : gfx::Screen::GetNativeScreen(); 2540 : gfx::Screen::GetNativeScreen();
2535 } 2541 }
2536 2542
2537 } // namespace views 2543 } // namespace views
OLDNEW
« no previous file with comments | « ui/views/controls/menu/menu_controller.h ('k') | ui/views/controls/menu/menu_controller_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698