| 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 2557 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2568 message_loop_->QuitNow(); | 2568 message_loop_->QuitNow(); |
| 2569 return quit_now; | 2569 return quit_now; |
| 2570 } | 2570 } |
| 2571 | 2571 |
| 2572 void MenuController::ExitAsyncRun() { | 2572 void MenuController::ExitAsyncRun() { |
| 2573 if (!async_run_) | 2573 if (!async_run_) |
| 2574 return; | 2574 return; |
| 2575 bool nested = delegate_stack_.size() > 1; | 2575 bool nested = delegate_stack_.size() > 1; |
| 2576 // ExitMenuRun unwinds nested delegates | 2576 // ExitMenuRun unwinds nested delegates |
| 2577 internal::MenuControllerDelegate* delegate = delegate_; | 2577 internal::MenuControllerDelegate* delegate = delegate_; |
| 2578 // MenuController may have been deleted when releasing ViewsDelegate ref. |
| 2579 // However as |delegate| can outlive this, it must still be notified of the |
| 2580 // menu closing so that it can perform teardown. |
| 2581 int accept_event_flags = accept_event_flags_; |
| 2578 MenuItemView* result = ExitMenuRun(); | 2582 MenuItemView* result = ExitMenuRun(); |
| 2579 delegate->OnMenuClosed(internal::MenuControllerDelegate::NOTIFY_DELEGATE, | 2583 delegate->OnMenuClosed(internal::MenuControllerDelegate::NOTIFY_DELEGATE, |
| 2580 result, accept_event_flags_); | 2584 result, accept_event_flags); |
| 2581 // MenuController may have been deleted by |delegate|. | 2585 // MenuController may have been deleted by |delegate|. |
| 2582 if (GetActiveInstance() && nested && exit_type_ == EXIT_ALL) | 2586 if (GetActiveInstance() && nested && exit_type_ == EXIT_ALL) |
| 2583 ExitAsyncRun(); | 2587 ExitAsyncRun(); |
| 2584 } | 2588 } |
| 2585 | 2589 |
| 2586 MenuItemView* MenuController::ExitMenuRun() { | 2590 MenuItemView* MenuController::ExitMenuRun() { |
| 2587 // Release the lock which prevents Chrome from shutting down while the menu is | 2591 // Release the lock which prevents Chrome from shutting down while the menu is |
| 2588 // showing. | 2592 // showing. |
| 2589 if (async_run_ && ViewsDelegate::GetInstance()) | 2593 if (async_run_ && ViewsDelegate::GetInstance()) |
| 2590 ViewsDelegate::GetInstance()->ReleaseRef(); | 2594 ViewsDelegate::GetInstance()->ReleaseRef(); |
| 2591 | 2595 |
| 2596 // Releasing the lock can result in Chrome shutting down, deleting this. |
| 2597 if (!GetActiveInstance()) |
| 2598 return nullptr; |
| 2599 |
| 2592 // Close any open menus. | 2600 // Close any open menus. |
| 2593 SetSelection(nullptr, SELECTION_UPDATE_IMMEDIATELY | SELECTION_EXIT); | 2601 SetSelection(nullptr, SELECTION_UPDATE_IMMEDIATELY | SELECTION_EXIT); |
| 2594 | 2602 |
| 2595 #if defined(OS_WIN) | 2603 #if defined(OS_WIN) |
| 2596 // On Windows, if we select the menu item by touch and if the window at the | 2604 // On Windows, if we select the menu item by touch and if the window at the |
| 2597 // location is another window on the same thread, that window gets a | 2605 // location is another window on the same thread, that window gets a |
| 2598 // WM_MOUSEACTIVATE message and ends up activating itself, which is not | 2606 // WM_MOUSEACTIVATE message and ends up activating itself, which is not |
| 2599 // correct. We workaround this by setting a property on the window at the | 2607 // correct. We workaround this by setting a property on the window at the |
| 2600 // current cursor location. We check for this property in our | 2608 // current cursor location. We check for this property in our |
| 2601 // WM_MOUSEACTIVATE handler and don't activate the window if the property is | 2609 // WM_MOUSEACTIVATE handler and don't activate the window if the property is |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2724 if (hot_button_) | 2732 if (hot_button_) |
| 2725 hot_button_->SetHotTracked(false); | 2733 hot_button_->SetHotTracked(false); |
| 2726 hot_button_ = hot_button; | 2734 hot_button_ = hot_button; |
| 2727 if (hot_button) { | 2735 if (hot_button) { |
| 2728 hot_button->SetHotTracked(true); | 2736 hot_button->SetHotTracked(true); |
| 2729 hot_button->NotifyAccessibilityEvent(ui::AX_EVENT_SELECTION, true); | 2737 hot_button->NotifyAccessibilityEvent(ui::AX_EVENT_SELECTION, true); |
| 2730 } | 2738 } |
| 2731 } | 2739 } |
| 2732 | 2740 |
| 2733 } // namespace views | 2741 } // namespace views |
| OLD | NEW |