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

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

Issue 1775533002: Fixes incorrect clearing of hot-tracked state when context menu is opened from a menu item (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Moves hot_button tracking from MenuController to MenuController::State Created 4 years, 9 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 346 matching lines...) Expand 10 before | Expand all | Expand 10 after
357 // If there are multiple matches this is the index of the item after the 357 // If there are multiple matches this is the index of the item after the
358 // currently selected item whose mnemonic matches. This may remain -1 even 358 // currently selected item whose mnemonic matches. This may remain -1 even
359 // though there are matches. 359 // though there are matches.
360 int next_match; 360 int next_match;
361 }; 361 };
362 362
363 // MenuController:State ------------------------------------------------------ 363 // MenuController:State ------------------------------------------------------
364 364
365 MenuController::State::State() 365 MenuController::State::State()
366 : item(NULL), 366 : item(NULL),
367 hot_button(NULL),
sky 2016/03/23 21:42:40 nullptr (feel free to change NULL on the previous
varkha 2016/03/24 18:36:18 Done.
367 submenu_open(false), 368 submenu_open(false),
368 anchor(MENU_ANCHOR_TOPLEFT), 369 anchor(MENU_ANCHOR_TOPLEFT),
369 context_menu(false) { 370 context_menu(false) {
370 } 371 }
371 372
372 MenuController::State::State(const State& other) = default; 373 MenuController::State::State(const State& other) = default;
373 374
374 MenuController::State::~State() {} 375 MenuController::State::~State() {}
375 376
376 // MenuController ------------------------------------------------------------ 377 // MenuController ------------------------------------------------------------
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
417 } 418 }
418 } 419 }
419 } 420 }
420 421
421 bool nested_menu = showing_; 422 bool nested_menu = showing_;
422 if (showing_) { 423 if (showing_) {
423 // Only support nesting of blocking_run menus, nesting of 424 // Only support nesting of blocking_run menus, nesting of
424 // blocking/non-blocking shouldn't be needed. 425 // blocking/non-blocking shouldn't be needed.
425 DCHECK(blocking_run_); 426 DCHECK(blocking_run_);
426 427
428 state_.hot_button = pending_state_.hot_button;
427 // We're already showing, push the current state. 429 // We're already showing, push the current state.
428 menu_stack_.push_back( 430 menu_stack_.push_back(
429 std::make_pair(state_, make_linked_ptr(pressed_lock_.release()))); 431 std::make_pair(state_, make_linked_ptr(pressed_lock_.release())));
430 432
431 // The context menu should be owned by the same parent. 433 // The context menu should be owned by the same parent.
432 DCHECK_EQ(owner_, parent); 434 DCHECK_EQ(owner_, parent);
433 } else { 435 } else {
434 showing_ = true; 436 showing_ = true;
435 437
436 #if defined(USE_AURA) 438 #if defined(USE_AURA)
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
551 553
552 current_mouse_pressed_state_ |= event.changed_button_flags(); 554 current_mouse_pressed_state_ |= event.changed_button_flags();
553 555
554 if (forward_to_root) { 556 if (forward_to_root) {
555 ui::MouseEvent event_for_root(event); 557 ui::MouseEvent event_for_root(event);
556 // Reset hot-tracking if a different view is getting a mouse press. 558 // Reset hot-tracking if a different view is getting a mouse press.
557 ConvertLocatedEventForRootView(source, forward_to_root, &event_for_root); 559 ConvertLocatedEventForRootView(source, forward_to_root, &event_for_root);
558 View* view = 560 View* view =
559 forward_to_root->GetEventHandlerForPoint(event_for_root.location()); 561 forward_to_root->GetEventHandlerForPoint(event_for_root.location());
560 CustomButton* button = CustomButton::AsCustomButton(view); 562 CustomButton* button = CustomButton::AsCustomButton(view);
561 if (hot_button_ && hot_button_ != button) 563 if (pending_state_.hot_button != button)
562 SetHotTrackedButton(nullptr); 564 SetHotTrackedButton(button);
563 565
564 // Empty menu items are always handled by the menu controller. 566 // Empty menu items are always handled by the menu controller.
565 if (!view || view->id() != MenuItemView::kEmptyMenuItemViewID) { 567 if (!view || view->id() != MenuItemView::kEmptyMenuItemViewID) {
566 bool processed = forward_to_root->ProcessMousePressed(event_for_root); 568 bool processed = forward_to_root->ProcessMousePressed(event_for_root);
567 // If the event was processed, the root view becomes our current mouse 569 // If the event was processed, the root view becomes our current mouse
568 // handler... 570 // handler...
569 if (processed && !current_mouse_event_target_) { 571 if (processed && !current_mouse_event_target_) {
570 current_mouse_event_target_ = forward_to_root; 572 current_mouse_event_target_ = forward_to_root;
571 } 573 }
572 574
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
751 void MenuController::OnGestureEvent(SubmenuView* source, 753 void MenuController::OnGestureEvent(SubmenuView* source,
752 ui::GestureEvent* event) { 754 ui::GestureEvent* event) {
753 MenuHostRootView* root_view = GetRootView(source, event->location()); 755 MenuHostRootView* root_view = GetRootView(source, event->location());
754 if (root_view) { 756 if (root_view) {
755 // Reset hot-tracking if a different view is getting a touch event. 757 // Reset hot-tracking if a different view is getting a touch event.
756 ui::GestureEvent event_for_root(*event); 758 ui::GestureEvent event_for_root(*event);
757 ConvertLocatedEventForRootView(source, root_view, &event_for_root); 759 ConvertLocatedEventForRootView(source, root_view, &event_for_root);
758 View* view = 760 View* view =
759 root_view->GetEventHandlerForPoint(event_for_root.location()); 761 root_view->GetEventHandlerForPoint(event_for_root.location());
760 CustomButton* button = CustomButton::AsCustomButton(view); 762 CustomButton* button = CustomButton::AsCustomButton(view);
761 if (hot_button_ && hot_button_ != button) 763 if (pending_state_.hot_button && pending_state_.hot_button != button)
762 SetHotTrackedButton(nullptr); 764 SetHotTrackedButton(nullptr);
763 } 765 }
764 766
765 MenuPart part = GetMenuPart(source, event->location()); 767 MenuPart part = GetMenuPart(source, event->location());
766 if (event->type() == ui::ET_GESTURE_TAP_DOWN) { 768 if (event->type() == ui::ET_GESTURE_TAP_DOWN) {
767 SetSelectionOnPointerDown(source, event); 769 SetSelectionOnPointerDown(source, event);
768 event->StopPropagation(); 770 event->StopPropagation();
769 } else if (event->type() == ui::ET_GESTURE_LONG_PRESS) { 771 } else if (event->type() == ui::ET_GESTURE_LONG_PRESS) {
770 if (part.type == MenuPart::MENU_ITEM && part.menu) { 772 if (part.type == MenuPart::MENU_ITEM && part.menu) {
771 gfx::Point screen_location(event->location()); 773 gfx::Point screen_location(event->location());
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
827 829
828 void MenuController::ViewHierarchyChanged( 830 void MenuController::ViewHierarchyChanged(
829 SubmenuView* source, 831 SubmenuView* source,
830 const View::ViewHierarchyChangedDetails& details) { 832 const View::ViewHierarchyChangedDetails& details) {
831 if (!details.is_add) { 833 if (!details.is_add) {
832 // If the current mouse handler is removed, remove it as the handler. 834 // If the current mouse handler is removed, remove it as the handler.
833 if (details.child == current_mouse_event_target_) { 835 if (details.child == current_mouse_event_target_) {
834 current_mouse_event_target_ = nullptr; 836 current_mouse_event_target_ = nullptr;
835 current_mouse_pressed_state_ = 0; 837 current_mouse_pressed_state_ = 0;
836 } 838 }
837 // Update |hot_button_| if it gets removed while a menu is up. 839 // Update |pending_state_.hot_button| if it gets removed while a menu is up.
838 if (details.child == hot_button_) 840 if (details.child == pending_state_.hot_button)
839 hot_button_ = nullptr; 841 pending_state_.hot_button = nullptr;
840 } 842 }
841 } 843 }
842 844
843 bool MenuController::GetDropFormats( 845 bool MenuController::GetDropFormats(
844 SubmenuView* source, 846 SubmenuView* source,
845 int* formats, 847 int* formats,
846 std::set<ui::Clipboard::FormatType>* format_types) { 848 std::set<ui::Clipboard::FormatType>* format_types) {
847 return source->GetMenuItem()->GetDelegate()->GetDropFormats( 849 return source->GetMenuItem()->GetDelegate()->GetDropFormats(
848 source->GetMenuItem(), formats, format_types); 850 source->GetMenuItem(), formats, format_types);
849 } 851 }
(...skipping 459 matching lines...) Expand 10 before | Expand all | Expand 10 after
1309 drop_target_(NULL), 1311 drop_target_(NULL),
1310 drop_position_(MenuDelegate::DROP_UNKNOWN), 1312 drop_position_(MenuDelegate::DROP_UNKNOWN),
1311 owner_(NULL), 1313 owner_(NULL),
1312 possible_drag_(false), 1314 possible_drag_(false),
1313 drag_in_progress_(false), 1315 drag_in_progress_(false),
1314 did_initiate_drag_(false), 1316 did_initiate_drag_(false),
1315 valid_drop_coordinates_(false), 1317 valid_drop_coordinates_(false),
1316 last_drop_operation_(MenuDelegate::DROP_UNKNOWN), 1318 last_drop_operation_(MenuDelegate::DROP_UNKNOWN),
1317 showing_submenu_(false), 1319 showing_submenu_(false),
1318 active_mouse_view_id_(ViewStorage::GetInstance()->CreateStorageID()), 1320 active_mouse_view_id_(ViewStorage::GetInstance()->CreateStorageID()),
1319 hot_button_(nullptr),
1320 delegate_(delegate), 1321 delegate_(delegate),
1321 message_loop_depth_(0), 1322 message_loop_depth_(0),
1322 closing_event_time_(base::TimeDelta()), 1323 closing_event_time_(base::TimeDelta()),
1323 menu_start_time_(base::TimeTicks()), 1324 menu_start_time_(base::TimeTicks()),
1324 async_run_(false), 1325 async_run_(false),
1325 is_combobox_(false), 1326 is_combobox_(false),
1326 item_selected_by_touch_(false), 1327 item_selected_by_touch_(false),
1327 current_mouse_event_target_(nullptr), 1328 current_mouse_event_target_(nullptr),
1328 current_mouse_pressed_state_(0), 1329 current_mouse_pressed_state_(0),
1329 message_loop_(MenuMessageLoop::Create()) { 1330 message_loop_(MenuMessageLoop::Create()) {
(...skipping 787 matching lines...) Expand 10 before | Expand all | Expand 10 after
2117 if (item->GetSubmenu()->GetMenuItemCount()) { 2118 if (item->GetSubmenu()->GetMenuItemCount()) {
2118 MenuItemView* to_select = FindInitialSelectableMenuItem(item, direction); 2119 MenuItemView* to_select = FindInitialSelectableMenuItem(item, direction);
2119 SetInitialHotTrackedView(to_select, direction); 2120 SetInitialHotTrackedView(to_select, direction);
2120 return; 2121 return;
2121 } 2122 }
2122 } 2123 }
2123 2124
2124 if (item->has_children()) { 2125 if (item->has_children()) {
2125 CustomButton* button = GetFirstHotTrackedView(item); 2126 CustomButton* button = GetFirstHotTrackedView(item);
2126 if (button) { 2127 if (button) {
2127 DCHECK_EQ(hot_button_, button); 2128 DCHECK_EQ(pending_state_.hot_button, button);
2128 SetHotTrackedButton(nullptr); 2129 SetHotTrackedButton(nullptr);
2129 } 2130 }
2130 bool direction_is_down = direction == INCREMENT_SELECTION_DOWN; 2131 bool direction_is_down = direction == INCREMENT_SELECTION_DOWN;
2131 View* to_make_hot = button 2132 View* to_make_hot = button
2132 ? GetNextFocusableView(item, button, direction_is_down) 2133 ? GetNextFocusableView(item, button, direction_is_down)
2133 : GetInitialFocusableView(item, direction_is_down); 2134 : GetInitialFocusableView(item, direction_is_down);
2134 CustomButton* hot_button = CustomButton::AsCustomButton(to_make_hot); 2135 CustomButton* hot_button = CustomButton::AsCustomButton(to_make_hot);
2135 if (hot_button) { 2136 if (hot_button) {
2136 SetHotTrackedButton(hot_button); 2137 SetHotTrackedButton(hot_button);
2137 return; 2138 return;
(...skipping 443 matching lines...) Expand 10 before | Expand all | Expand 10 after
2581 SetSelection(nullptr, SELECTION_UPDATE_IMMEDIATELY | SELECTION_EXIT); 2582 SetSelection(nullptr, SELECTION_UPDATE_IMMEDIATELY | SELECTION_EXIT);
2582 2583
2583 // Set exit_all_, which makes sure all nested loops exit immediately. 2584 // Set exit_all_, which makes sure all nested loops exit immediately.
2584 if (exit_type_ != EXIT_DESTROYED) 2585 if (exit_type_ != EXIT_DESTROYED)
2585 SetExitType(EXIT_ALL); 2586 SetExitType(EXIT_ALL);
2586 } else { 2587 } else {
2587 TerminateNestedMessageLoopIfNecessary(); 2588 TerminateNestedMessageLoopIfNecessary();
2588 } 2589 }
2589 } 2590 }
2590 2591
2591 // Reset our pressed lock to the previous state's, if there was one. 2592 // Reset our pressed lock and hot-tracked state to the previous state's, if
2592 // The lock handles the case if the button was destroyed. 2593 // they were active. The lock handles the case if the button was destroyed.
2593 pressed_lock_.reset(nested_pressed_lock.release()); 2594 pressed_lock_.reset(nested_pressed_lock.release());
2595 if (pending_state_.hot_button)
2596 pending_state_.hot_button->SetHotTracked(true);
2594 2597
2595 return result; 2598 return result;
2596 } 2599 }
2597 2600
2598 void MenuController::HandleMouseLocation(SubmenuView* source, 2601 void MenuController::HandleMouseLocation(SubmenuView* source,
2599 const gfx::Point& mouse_location) { 2602 const gfx::Point& mouse_location) {
2600 if (showing_submenu_) 2603 if (showing_submenu_)
2601 return; 2604 return;
2602 2605
2603 // Ignore mouse events if we're closing the menu. 2606 // Ignore mouse events if we're closing the menu.
(...skipping 28 matching lines...) Expand all
2632 SelectionIncrementDirectionType direction) { 2635 SelectionIncrementDirectionType direction) {
2633 if (!item) 2636 if (!item)
2634 return; 2637 return;
2635 SetSelection(item, SELECTION_DEFAULT); 2638 SetSelection(item, SELECTION_DEFAULT);
2636 View* hot_view = 2639 View* hot_view =
2637 GetInitialFocusableView(item, direction == INCREMENT_SELECTION_DOWN); 2640 GetInitialFocusableView(item, direction == INCREMENT_SELECTION_DOWN);
2638 SetHotTrackedButton(CustomButton::AsCustomButton(hot_view)); 2641 SetHotTrackedButton(CustomButton::AsCustomButton(hot_view));
2639 } 2642 }
2640 2643
2641 void MenuController::SetHotTrackedButton(CustomButton* hot_button) { 2644 void MenuController::SetHotTrackedButton(CustomButton* hot_button) {
2642 if (hot_button == hot_button_) { 2645 if (hot_button == pending_state_.hot_button) {
2643 // Hot-tracked state may change outside of the MenuController. Correct it. 2646 // Hot-tracked state may change outside of the MenuController. Correct it.
2644 if (hot_button && !hot_button->IsHotTracked()) 2647 if (hot_button && !hot_button->IsHotTracked())
2645 hot_button->SetHotTracked(true); 2648 hot_button->SetHotTracked(true);
2646 return; 2649 return;
2647 } 2650 }
2648 if (hot_button_) 2651 if (pending_state_.hot_button)
2649 hot_button_->SetHotTracked(false); 2652 pending_state_.hot_button->SetHotTracked(false);
2650 hot_button_ = hot_button; 2653 pending_state_.hot_button = hot_button;
2651 if (hot_button) 2654 if (hot_button)
2652 hot_button->SetHotTracked(true); 2655 hot_button->SetHotTracked(true);
2653 } 2656 }
2654 2657
2655 } // namespace views 2658 } // namespace views
OLDNEW
« ui/views/controls/menu/menu_controller.h ('K') | « ui/views/controls/menu/menu_controller.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698