| 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_runner_impl.h" | 5 #include "ui/views/controls/menu/menu_runner_impl.h" |
| 6 | 6 |
| 7 #include "build/build_config.h" | 7 #include "build/build_config.h" |
| 8 #include "ui/native_theme/native_theme.h" | 8 #include "ui/native_theme/native_theme.h" |
| 9 #include "ui/views/controls/button/menu_button.h" | 9 #include "ui/views/controls/button/menu_button.h" |
| 10 #include "ui/views/controls/menu/menu_controller.h" | 10 #include "ui/views/controls/menu/menu_controller.h" |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 62 | 62 |
| 63 // Verify that the MenuController is still active. It may have been | 63 // Verify that the MenuController is still active. It may have been |
| 64 // destroyed out of order. | 64 // destroyed out of order. |
| 65 if (controller_) { | 65 if (controller_) { |
| 66 // Release is invoked when MenuRunner is destroyed. Assume this is | 66 // Release is invoked when MenuRunner is destroyed. Assume this is |
| 67 // happening because the object referencing the menu has been destroyed | 67 // happening because the object referencing the menu has been destroyed |
| 68 // and the menu button is no longer valid. | 68 // and the menu button is no longer valid. |
| 69 controller_->Cancel(MenuController::EXIT_DESTROYED); | 69 controller_->Cancel(MenuController::EXIT_DESTROYED); |
| 70 return; | 70 return; |
| 71 } | 71 } |
| 72 |
| 73 // TODO(jonross): remove after tracking down the cause of |
| 74 // (crbug.com/683087). |
| 75 // Update for the ASAN stack trace to determine if we are in the running |
| 76 // state during the incorrect destruction order. |
| 77 delete this; |
| 78 } else { |
| 79 delete this; |
| 72 } | 80 } |
| 73 | |
| 74 delete this; | |
| 75 } | 81 } |
| 76 | 82 |
| 77 MenuRunner::RunResult MenuRunnerImpl::RunMenuAt(Widget* parent, | 83 MenuRunner::RunResult MenuRunnerImpl::RunMenuAt(Widget* parent, |
| 78 MenuButton* button, | 84 MenuButton* button, |
| 79 const gfx::Rect& bounds, | 85 const gfx::Rect& bounds, |
| 80 MenuAnchorPosition anchor, | 86 MenuAnchorPosition anchor, |
| 81 int32_t run_types) { | 87 int32_t run_types) { |
| 82 closing_event_time_ = base::TimeTicks(); | 88 closing_event_time_ = base::TimeTicks(); |
| 83 if (running_) { | 89 if (running_) { |
| 84 // Ignore requests to show the menu while it's already showing. MenuItemView | 90 // Ignore requests to show the menu while it's already showing. MenuItemView |
| 85 // doesn't handle this very well (meaning it crashes). | 91 // doesn't handle this very well (meaning it crashes). |
| 86 return MenuRunner::NORMAL_EXIT; | 92 return MenuRunner::NORMAL_EXIT; |
| 87 } | 93 } |
| 88 | 94 |
| 95 // TODO(jonross): remove after tracking down the cause of (crbug.com/683087). |
| 96 // Verify that this was not a delegate previously used for a run, which was |
| 97 // shutdown, but not deleted. Nesting the same delegate multiple times is |
| 98 // dangerous. |
| 99 CHECK(!controller_); |
| 100 |
| 89 MenuController* controller = MenuController::GetActiveInstance(); | 101 MenuController* controller = MenuController::GetActiveInstance(); |
| 90 if (controller) { | 102 if (controller) { |
| 91 if ((run_types & MenuRunner::IS_NESTED) != 0) { | 103 if ((run_types & MenuRunner::IS_NESTED) != 0) { |
| 92 if (!controller->IsBlockingRun()) { | 104 if (!controller->IsBlockingRun()) { |
| 93 controller->CancelAll(); | 105 controller->CancelAll(); |
| 94 controller = NULL; | 106 controller = NULL; |
| 95 } else { | 107 } else { |
| 96 // Only nest the delegate when not cancelling drag-and-drop. When | 108 // Only nest the delegate when not cancelling drag-and-drop. When |
| 97 // cancelling this will become the root delegate of the new | 109 // cancelling this will become the root delegate of the new |
| 98 // MenuController | 110 // MenuController |
| (...skipping 15 matching lines...) Expand all Loading... |
| 114 } | 126 } |
| 115 | 127 |
| 116 running_ = true; | 128 running_ = true; |
| 117 async_ = (run_types & MenuRunner::ASYNC) != 0; | 129 async_ = (run_types & MenuRunner::ASYNC) != 0; |
| 118 for_drop_ = (run_types & MenuRunner::FOR_DROP) != 0; | 130 for_drop_ = (run_types & MenuRunner::FOR_DROP) != 0; |
| 119 bool has_mnemonics = (run_types & MenuRunner::HAS_MNEMONICS) != 0; | 131 bool has_mnemonics = (run_types & MenuRunner::HAS_MNEMONICS) != 0; |
| 120 owns_controller_ = false; | 132 owns_controller_ = false; |
| 121 if (!controller) { | 133 if (!controller) { |
| 122 // No menus are showing, show one. | 134 // No menus are showing, show one. |
| 123 controller = new MenuController(!for_drop_, this); | 135 controller = new MenuController(!for_drop_, this); |
| 136 // TODO(jonross): remove after tracking down the cause of |
| 137 // (crbug.com/683087). |
| 124 owns_controller_ = true; | 138 owns_controller_ = true; |
| 125 } | 139 } |
| 126 controller->SetAsyncRun(async_); | 140 controller->SetAsyncRun(async_); |
| 127 controller->set_is_combobox((run_types & MenuRunner::COMBOBOX) != 0); | 141 controller->set_is_combobox((run_types & MenuRunner::COMBOBOX) != 0); |
| 128 controller_ = controller->AsWeakPtr(); | 142 controller_ = controller->AsWeakPtr(); |
| 129 menu_->set_controller(controller_.get()); | 143 menu_->set_controller(controller_.get()); |
| 130 menu_->PrepareForRun(owns_controller_, | 144 menu_->PrepareForRun(owns_controller_, |
| 131 has_mnemonics, | 145 has_mnemonics, |
| 132 !for_drop_ && ShouldShowMnemonics(button)); | 146 !for_drop_ && ShouldShowMnemonics(button)); |
| 133 | 147 |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 183 MenuRunner::RunResult MenuRunnerImpl::MenuDone(NotifyType type, | 197 MenuRunner::RunResult MenuRunnerImpl::MenuDone(NotifyType type, |
| 184 MenuItemView* result, | 198 MenuItemView* result, |
| 185 int mouse_event_flags) { | 199 int mouse_event_flags) { |
| 186 menu_->RemoveEmptyMenus(); | 200 menu_->RemoveEmptyMenus(); |
| 187 menu_->set_controller(nullptr); | 201 menu_->set_controller(nullptr); |
| 188 | 202 |
| 189 if (owns_controller_ && controller_) { | 203 if (owns_controller_ && controller_) { |
| 190 // We created the controller and need to delete it. | 204 // We created the controller and need to delete it. |
| 191 delete controller_.get(); | 205 delete controller_.get(); |
| 192 owns_controller_ = false; | 206 owns_controller_ = false; |
| 207 controller_ = nullptr; |
| 193 } | 208 } |
| 194 controller_ = nullptr; | 209 |
| 195 // Make sure all the windows we created to show the menus have been | 210 // Make sure all the windows we created to show the menus have been |
| 196 // destroyed. | 211 // destroyed. |
| 197 menu_->DestroyAllMenuHosts(); | 212 menu_->DestroyAllMenuHosts(); |
| 198 if (delete_after_run_) { | 213 if (delete_after_run_) { |
| 199 delete this; | 214 delete this; |
| 200 return MenuRunner::MENU_DELETED; | 215 return MenuRunner::MENU_DELETED; |
| 201 } | 216 } |
| 202 running_ = false; | 217 running_ = false; |
| 203 if (menu_->GetDelegate()) { | 218 if (menu_->GetDelegate()) { |
| 204 // Executing the command may also delete this. | 219 // Executing the command may also delete this. |
| (...skipping 18 matching lines...) Expand all Loading... |
| 223 #if defined(OS_WIN) | 238 #if defined(OS_WIN) |
| 224 // This is only needed on Windows. | 239 // This is only needed on Windows. |
| 225 if (!show_mnemonics) | 240 if (!show_mnemonics) |
| 226 show_mnemonics = ui::win::IsAltPressed(); | 241 show_mnemonics = ui::win::IsAltPressed(); |
| 227 #endif | 242 #endif |
| 228 return show_mnemonics; | 243 return show_mnemonics; |
| 229 } | 244 } |
| 230 | 245 |
| 231 } // namespace internal | 246 } // namespace internal |
| 232 } // namespace views | 247 } // namespace views |
| OLD | NEW |