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 487 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
498 | 498 |
499 void MenuController::Cancel(ExitType type) { | 499 void MenuController::Cancel(ExitType type) { |
500 // If the menu has already been destroyed, no further cancellation is | 500 // If the menu has already been destroyed, no further cancellation is |
501 // needed. We especially don't want to set the |exit_type_| to a lesser | 501 // needed. We especially don't want to set the |exit_type_| to a lesser |
502 // value. | 502 // value. |
503 if (exit_type_ == EXIT_DESTROYED || exit_type_ == type) | 503 if (exit_type_ == EXIT_DESTROYED || exit_type_ == type) |
504 return; | 504 return; |
505 | 505 |
506 if (!showing_) { | 506 if (!showing_) { |
507 // This occurs if we're in the process of notifying the delegate for a drop | 507 // This occurs if we're in the process of notifying the delegate for a drop |
508 // and the delegate cancels us. | 508 // and the delegate cancels us. Or if the releasing of ViewsDelegate causes |
| 509 // an immediate shutdown. |
509 return; | 510 return; |
510 } | 511 } |
511 | 512 |
512 MenuItemView* selected = state_.item; | 513 MenuItemView* selected = state_.item; |
513 SetExitType(type); | 514 SetExitType(type); |
514 | 515 |
515 SendMouseCaptureLostToActiveView(); | 516 SendMouseCaptureLostToActiveView(); |
516 | 517 |
517 // Hide windows immediately. | 518 // Hide windows immediately. |
518 SetSelection(NULL, SELECTION_UPDATE_IMMEDIATELY | SELECTION_EXIT); | 519 SetSelection(NULL, SELECTION_UPDATE_IMMEDIATELY | SELECTION_EXIT); |
519 | 520 |
520 if (!blocking_run_) { | 521 if (!blocking_run_) { |
521 // If we didn't block the caller we need to notify the menu, which | 522 // If we didn't block the caller we need to notify the menu, which |
522 // triggers deleting us. | 523 // triggers deleting us. |
523 DCHECK(selected); | 524 DCHECK(selected); |
524 showing_ = false; | 525 showing_ = false; |
525 delegate_->OnMenuClosed(internal::MenuControllerDelegate::NOTIFY_DELEGATE, | 526 delegate_->OnMenuClosed(internal::MenuControllerDelegate::NOTIFY_DELEGATE, |
526 selected->GetRootMenuItem(), accept_event_flags_); | 527 selected->GetRootMenuItem(), accept_event_flags_); |
527 // WARNING: the call to MenuClosed deletes us. | 528 // WARNING: the call to MenuClosed deletes us. |
528 return; | 529 return; |
529 } | 530 } |
530 | 531 |
| 532 // If |type| is EXIT_ALL we update the state of the menu to not showing. For |
| 533 // dragging this ensures that the correct visual state is reported until the |
| 534 // drag operation completes. For non-dragging cases it is possible that the |
| 535 // release of ViewsDelegate leads immediately to shutdown, which can trigger |
| 536 // nested calls to Cancel. We want to reject these to prevent attempting a |
| 537 // nested tear down of this and |delegate_|. |
| 538 if (type == EXIT_ALL) |
| 539 showing_ = false; |
| 540 |
531 // On Windows and Linux the destruction of this menu's Widget leads to the | 541 // On Windows and Linux the destruction of this menu's Widget leads to the |
532 // teardown of the platform specific drag-and-drop Widget. Do not shutdown | 542 // teardown of the platform specific drag-and-drop Widget. Do not shutdown |
533 // while dragging, leave the Widget hidden until drag-and-drop has completed, | 543 // while dragging, leave the Widget hidden until drag-and-drop has completed, |
534 // at which point all menus will be destroyed. | 544 // at which point all menus will be destroyed. |
535 // | |
536 // If |type| is EXIT_ALL we update the state of the menu to not showing. So | |
537 // that during the completion of a drag we are not incorrectly reporting the | |
538 // visual state. | |
539 if (!drag_in_progress_) | 545 if (!drag_in_progress_) |
540 ExitAsyncRun(); | 546 ExitAsyncRun(); |
541 else if (type == EXIT_ALL) | |
542 showing_ = false; | |
543 } | 547 } |
544 | 548 |
545 void MenuController::AddNestedDelegate( | 549 void MenuController::AddNestedDelegate( |
546 internal::MenuControllerDelegate* delegate) { | 550 internal::MenuControllerDelegate* delegate) { |
547 delegate_stack_.push_back(std::make_pair(delegate, async_run_)); | 551 delegate_stack_.push_back(std::make_pair(delegate, async_run_)); |
548 delegate_ = delegate; | 552 delegate_ = delegate; |
549 } | 553 } |
550 | 554 |
551 void MenuController::SetAsyncRun(bool is_async) { | 555 void MenuController::SetAsyncRun(bool is_async) { |
552 delegate_stack_.back().second = is_async; | 556 delegate_stack_.back().second = is_async; |
(...skipping 2193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2746 if (hot_button_) | 2750 if (hot_button_) |
2747 hot_button_->SetHotTracked(false); | 2751 hot_button_->SetHotTracked(false); |
2748 hot_button_ = hot_button; | 2752 hot_button_ = hot_button; |
2749 if (hot_button) { | 2753 if (hot_button) { |
2750 hot_button->SetHotTracked(true); | 2754 hot_button->SetHotTracked(true); |
2751 hot_button->NotifyAccessibilityEvent(ui::AX_EVENT_SELECTION, true); | 2755 hot_button->NotifyAccessibilityEvent(ui::AX_EVENT_SELECTION, true); |
2752 } | 2756 } |
2753 } | 2757 } |
2754 | 2758 |
2755 } // namespace views | 2759 } // namespace views |
OLD | NEW |