Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |