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

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

Issue 1741093002: Fixes alternating keyboard and mouse hot-tracking in menus (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: 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 697 matching lines...) Expand 10 before | Expand all | Expand 10 after
708 const ui::MouseEvent& event) { 708 const ui::MouseEvent& event) {
709 if (current_mouse_event_target_) { 709 if (current_mouse_event_target_) {
710 ui::MouseEvent event_for_root(event); 710 ui::MouseEvent event_for_root(event);
711 ConvertLocatedEventForRootView(source, current_mouse_event_target_, 711 ConvertLocatedEventForRootView(source, current_mouse_event_target_,
712 &event_for_root); 712 &event_for_root);
713 current_mouse_event_target_->ProcessMouseMoved(event_for_root); 713 current_mouse_event_target_->ProcessMouseMoved(event_for_root);
714 return; 714 return;
715 } 715 }
716 716
717 MenuHostRootView* root_view = GetRootView(source, event.location()); 717 MenuHostRootView* root_view = GetRootView(source, event.location());
718 if (root_view) 718 if (root_view) {
719 root_view->ProcessMouseMoved(event); 719 root_view->ProcessMouseMoved(event);
720
721 ui::MouseEvent event_for_root(event);
722 ConvertLocatedEventForRootView(source, root_view, &event_for_root);
723 View* view =
724 root_view->GetEventHandlerForPoint(event_for_root.location());
725 CustomButton* button = CustomButton::AsCustomButton(view);
726 if (button && button->IsHotTracked())
727 SetHotTrackedButton(button);
728 }
729
720 HandleMouseLocation(source, event.location()); 730 HandleMouseLocation(source, event.location());
721 } 731 }
722 732
723 void MenuController::OnMouseEntered(SubmenuView* source, 733 void MenuController::OnMouseEntered(SubmenuView* source,
724 const ui::MouseEvent& event) { 734 const ui::MouseEvent& event) {
725 // MouseEntered is always followed by a mouse moved, so don't need to 735 // MouseEntered is always followed by a mouse moved, so don't need to
726 // do anything here. 736 // do anything here.
727 } 737 }
728 738
729 bool MenuController::OnMouseWheel(SubmenuView* source, 739 bool MenuController::OnMouseWheel(SubmenuView* source,
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
793 View* MenuController::GetTooltipHandlerForPoint(SubmenuView* source, 803 View* MenuController::GetTooltipHandlerForPoint(SubmenuView* source,
794 const gfx::Point& point) { 804 const gfx::Point& point) {
795 MenuHostRootView* root_view = GetRootView(source, point); 805 MenuHostRootView* root_view = GetRootView(source, point);
796 return root_view ? root_view->ProcessGetTooltipHandlerForPoint(point) 806 return root_view ? root_view->ProcessGetTooltipHandlerForPoint(point)
797 : nullptr; 807 : nullptr;
798 } 808 }
799 809
800 void MenuController::ViewHierarchyChanged( 810 void MenuController::ViewHierarchyChanged(
801 SubmenuView* source, 811 SubmenuView* source,
802 const View::ViewHierarchyChangedDetails& details) { 812 const View::ViewHierarchyChangedDetails& details) {
803 // If the current mouse handler is removed, remove it as the handler. 813 if (!details.is_add) {
804 if (!details.is_add && details.child == current_mouse_event_target_) { 814 // If the current mouse handler is removed, remove it as the handler.
805 current_mouse_event_target_ = nullptr; 815 if (details.child == current_mouse_event_target_) {
806 current_mouse_pressed_state_ = 0; 816 current_mouse_event_target_ = nullptr;
817 current_mouse_pressed_state_ = 0;
818 }
819 // Update |hot_button_| if it gets deleted while a menu is up.
820 if (details.child == hot_button_)
821 hot_button_ = nullptr;
807 } 822 }
808 } 823 }
809 824
810 bool MenuController::GetDropFormats( 825 bool MenuController::GetDropFormats(
811 SubmenuView* source, 826 SubmenuView* source,
812 int* formats, 827 int* formats,
813 std::set<ui::Clipboard::FormatType>* format_types) { 828 std::set<ui::Clipboard::FormatType>* format_types) {
814 return source->GetMenuItem()->GetDelegate()->GetDropFormats( 829 return source->GetMenuItem()->GetDelegate()->GetDropFormats(
815 source->GetMenuItem(), formats, format_types); 830 source->GetMenuItem(), formats, format_types);
816 } 831 }
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
1026 std::vector<MenuItemView*> new_path; 1041 std::vector<MenuItemView*> new_path;
1027 BuildPathsAndCalculateDiff(pending_state_.item, menu_item, &current_path, 1042 BuildPathsAndCalculateDiff(pending_state_.item, menu_item, &current_path,
1028 &new_path, &paths_differ_at); 1043 &new_path, &paths_differ_at);
1029 1044
1030 size_t current_size = current_path.size(); 1045 size_t current_size = current_path.size();
1031 size_t new_size = new_path.size(); 1046 size_t new_size = new_path.size();
1032 1047
1033 bool pending_item_changed = pending_state_.item != menu_item; 1048 bool pending_item_changed = pending_state_.item != menu_item;
1034 if (pending_item_changed && pending_state_.item) { 1049 if (pending_item_changed && pending_state_.item) {
1035 CustomButton* button = GetFirstHotTrackedView(pending_state_.item); 1050 CustomButton* button = GetFirstHotTrackedView(pending_state_.item);
1036 if (button) 1051 if (button) {
1037 button->SetHotTracked(false); 1052 DCHECK_EQ(hot_button_, button);
1053 SetHotTrackedButton(nullptr);
1054 }
1038 } 1055 }
1039 1056
1040 // Notify the old path it isn't selected. 1057 // Notify the old path it isn't selected.
1041 MenuDelegate* current_delegate = 1058 MenuDelegate* current_delegate =
1042 current_path.empty() ? NULL : current_path.front()->GetDelegate(); 1059 current_path.empty() ? NULL : current_path.front()->GetDelegate();
1043 for (size_t i = paths_differ_at; i < current_size; ++i) { 1060 for (size_t i = paths_differ_at; i < current_size; ++i) {
1044 if (current_delegate && 1061 if (current_delegate &&
1045 current_path[i]->GetType() == MenuItemView::SUBMENU) { 1062 current_path[i]->GetType() == MenuItemView::SUBMENU) {
1046 current_delegate->WillHideMenu(current_path[i]); 1063 current_delegate->WillHideMenu(current_path[i]);
1047 } 1064 }
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
1279 drop_target_(NULL), 1296 drop_target_(NULL),
1280 drop_position_(MenuDelegate::DROP_UNKNOWN), 1297 drop_position_(MenuDelegate::DROP_UNKNOWN),
1281 owner_(NULL), 1298 owner_(NULL),
1282 possible_drag_(false), 1299 possible_drag_(false),
1283 drag_in_progress_(false), 1300 drag_in_progress_(false),
1284 did_initiate_drag_(false), 1301 did_initiate_drag_(false),
1285 valid_drop_coordinates_(false), 1302 valid_drop_coordinates_(false),
1286 last_drop_operation_(MenuDelegate::DROP_UNKNOWN), 1303 last_drop_operation_(MenuDelegate::DROP_UNKNOWN),
1287 showing_submenu_(false), 1304 showing_submenu_(false),
1288 active_mouse_view_id_(ViewStorage::GetInstance()->CreateStorageID()), 1305 active_mouse_view_id_(ViewStorage::GetInstance()->CreateStorageID()),
1306 hot_button_(nullptr),
1289 delegate_(delegate), 1307 delegate_(delegate),
1290 message_loop_depth_(0), 1308 message_loop_depth_(0),
1291 closing_event_time_(base::TimeDelta()), 1309 closing_event_time_(base::TimeDelta()),
1292 menu_start_time_(base::TimeTicks()), 1310 menu_start_time_(base::TimeTicks()),
1293 async_run_(false), 1311 async_run_(false),
1294 is_combobox_(false), 1312 is_combobox_(false),
1295 item_selected_by_touch_(false), 1313 item_selected_by_touch_(false),
1296 current_mouse_event_target_(nullptr), 1314 current_mouse_event_target_(nullptr),
1297 current_mouse_pressed_state_(0), 1315 current_mouse_pressed_state_(0),
1298 message_loop_(MenuMessageLoop::Create()) { 1316 message_loop_(MenuMessageLoop::Create()) {
(...skipping 16 matching lines...) Expand all
1315 } 1333 }
1316 1334
1317 bool MenuController::SendAcceleratorToHotTrackedView() { 1335 bool MenuController::SendAcceleratorToHotTrackedView() {
1318 CustomButton* hot_view = GetFirstHotTrackedView(pending_state_.item); 1336 CustomButton* hot_view = GetFirstHotTrackedView(pending_state_.item);
1319 if (!hot_view) 1337 if (!hot_view)
1320 return false; 1338 return false;
1321 1339
1322 ui::Accelerator accelerator(ui::VKEY_RETURN, ui::EF_NONE); 1340 ui::Accelerator accelerator(ui::VKEY_RETURN, ui::EF_NONE);
1323 hot_view->AcceleratorPressed(accelerator); 1341 hot_view->AcceleratorPressed(accelerator);
1324 CustomButton* button = static_cast<CustomButton*>(hot_view); 1342 CustomButton* button = static_cast<CustomButton*>(hot_view);
1325 button->SetHotTracked(true); 1343 SetHotTrackedButton(button);
1326 return true; 1344 return true;
1327 } 1345 }
1328 1346
1329 void MenuController::UpdateInitialLocation(const gfx::Rect& bounds, 1347 void MenuController::UpdateInitialLocation(const gfx::Rect& bounds,
1330 MenuAnchorPosition position, 1348 MenuAnchorPosition position,
1331 bool context_menu) { 1349 bool context_menu) {
1332 pending_state_.context_menu = context_menu; 1350 pending_state_.context_menu = context_menu;
1333 pending_state_.initial_bounds = bounds; 1351 pending_state_.initial_bounds = bounds;
1334 if (bounds.height() > 1) { 1352 if (bounds.height() > 1) {
1335 // Inset the bounds slightly, otherwise drag coordinates don't line up 1353 // Inset the bounds slightly, otherwise drag coordinates don't line up
(...skipping 741 matching lines...) Expand 10 before | Expand all | Expand 10 after
2077 void MenuController::IncrementSelection( 2095 void MenuController::IncrementSelection(
2078 SelectionIncrementDirectionType direction) { 2096 SelectionIncrementDirectionType direction) {
2079 MenuItemView* item = pending_state_.item; 2097 MenuItemView* item = pending_state_.item;
2080 DCHECK(item); 2098 DCHECK(item);
2081 if (pending_state_.submenu_open && item->HasSubmenu() && 2099 if (pending_state_.submenu_open && item->HasSubmenu() &&
2082 item->GetSubmenu()->IsShowing()) { 2100 item->GetSubmenu()->IsShowing()) {
2083 // A menu is selected and open, but none of its children are selected, 2101 // A menu is selected and open, but none of its children are selected,
2084 // select the first menu item that is visible and enabled. 2102 // select the first menu item that is visible and enabled.
2085 if (item->GetSubmenu()->GetMenuItemCount()) { 2103 if (item->GetSubmenu()->GetMenuItemCount()) {
2086 MenuItemView* to_select = FindInitialSelectableMenuItem(item, direction); 2104 MenuItemView* to_select = FindInitialSelectableMenuItem(item, direction);
2087 if (to_select) 2105 if (to_select) {
2088 SetSelection(to_select, SELECTION_DEFAULT); 2106 SetSelection(to_select, SELECTION_DEFAULT);
2107 View* to_make_hot = GetInitialFocusableView(
2108 to_select, direction == INCREMENT_SELECTION_DOWN);
2109 CustomButton* button_hot = CustomButton::AsCustomButton(to_make_hot);
2110 if (button_hot)
2111 SetHotTrackedButton(button_hot);
varkha 2016/02/26 22:09:06 This block will not be necessary after https://cod
varkha 2016/02/26 22:34:42 Done.
2112 }
2089 return; 2113 return;
2090 } 2114 }
2091 } 2115 }
2092 2116
2093 if (item->has_children()) { 2117 if (item->has_children()) {
2094 CustomButton* button = GetFirstHotTrackedView(item); 2118 CustomButton* button = GetFirstHotTrackedView(item);
2095 if (button) { 2119 if (button) {
2096 button->SetHotTracked(false); 2120 DCHECK_EQ(hot_button_, button);
2121 SetHotTrackedButton(nullptr);
2097 View* to_make_hot = GetNextFocusableView( 2122 View* to_make_hot = GetNextFocusableView(
2098 item, button, direction == INCREMENT_SELECTION_DOWN); 2123 item, button, direction == INCREMENT_SELECTION_DOWN);
2099 CustomButton* button_hot = CustomButton::AsCustomButton(to_make_hot); 2124 CustomButton* button_hot = CustomButton::AsCustomButton(to_make_hot);
2100 if (button_hot) { 2125 if (button_hot) {
2101 button_hot->SetHotTracked(true); 2126 SetHotTrackedButton(button_hot);
2102 return; 2127 return;
2103 } 2128 }
2104 } else { 2129 } else {
2105 View* to_make_hot = 2130 View* to_make_hot =
2106 GetInitialFocusableView(item, direction == INCREMENT_SELECTION_DOWN); 2131 GetInitialFocusableView(item, direction == INCREMENT_SELECTION_DOWN);
2107 CustomButton* button_hot = CustomButton::AsCustomButton(to_make_hot); 2132 CustomButton* button_hot = CustomButton::AsCustomButton(to_make_hot);
2108 if (button_hot) { 2133 if (button_hot) {
2109 button_hot->SetHotTracked(true); 2134 SetHotTrackedButton(button_hot);
2110 return; 2135 return;
2111 } 2136 }
2112 } 2137 }
2113 } 2138 }
2114 2139
2115 MenuItemView* parent = item->GetParentMenuItem(); 2140 MenuItemView* parent = item->GetParentMenuItem();
2116 if (parent) { 2141 if (parent) {
2117 int parent_count = parent->GetSubmenu()->GetMenuItemCount(); 2142 int parent_count = parent->GetSubmenu()->GetMenuItemCount();
2118 if (parent_count > 1) { 2143 if (parent_count > 1) {
2119 for (int i = 0; i < parent_count; ++i) { 2144 for (int i = 0; i < parent_count; ++i) {
2120 if (parent->GetSubmenu()->GetMenuItemAt(i) == item) { 2145 if (parent->GetSubmenu()->GetMenuItemAt(i) == item) {
2121 MenuItemView* to_select = 2146 MenuItemView* to_select =
2122 FindNextSelectableMenuItem(parent, i, direction); 2147 FindNextSelectableMenuItem(parent, i, direction);
2123 if (!to_select) 2148 if (!to_select)
2124 break; 2149 break;
2125 SetSelection(to_select, SELECTION_DEFAULT); 2150 SetSelection(to_select, SELECTION_DEFAULT);
2126 View* to_make_hot = GetInitialFocusableView( 2151 View* to_make_hot = GetInitialFocusableView(
2127 to_select, direction == INCREMENT_SELECTION_DOWN); 2152 to_select, direction == INCREMENT_SELECTION_DOWN);
2128 CustomButton* button_hot = CustomButton::AsCustomButton(to_make_hot); 2153 CustomButton* button_hot = CustomButton::AsCustomButton(to_make_hot);
2129 if (button_hot) 2154 if (button_hot)
2130 button_hot->SetHotTracked(true); 2155 SetHotTrackedButton(button_hot);
2131 break; 2156 break;
2132 } 2157 }
2133 } 2158 }
2134 } 2159 }
2135 } 2160 }
2136 } 2161 }
2137 2162
2138 MenuItemView* MenuController::FindInitialSelectableMenuItem( 2163 MenuItemView* MenuController::FindInitialSelectableMenuItem(
2139 MenuItemView* parent, 2164 MenuItemView* parent,
2140 SelectionIncrementDirectionType direction) { 2165 SelectionIncrementDirectionType direction) {
(...skipping 461 matching lines...) Expand 10 before | Expand all | Expand 10 after
2602 pending_state_.item->GetParentMenuItem() && 2627 pending_state_.item->GetParentMenuItem() &&
2603 (!pending_state_.item->HasSubmenu() || 2628 (!pending_state_.item->HasSubmenu() ||
2604 !pending_state_.item->GetSubmenu()->IsShowing())) { 2629 !pending_state_.item->GetSubmenu()->IsShowing())) {
2605 // On exit if the user hasn't selected an item with a submenu, move the 2630 // On exit if the user hasn't selected an item with a submenu, move the
2606 // selection back to the parent menu item. 2631 // selection back to the parent menu item.
2607 SetSelection(pending_state_.item->GetParentMenuItem(), 2632 SetSelection(pending_state_.item->GetParentMenuItem(),
2608 SELECTION_OPEN_SUBMENU); 2633 SELECTION_OPEN_SUBMENU);
2609 } 2634 }
2610 } 2635 }
2611 2636
2637 void MenuController::SetHotTrackedButton(CustomButton* hot_button) {
2638 if (hot_button == hot_button_)
2639 return;
2640 if (hot_button_)
2641 hot_button_->SetHotTracked(false);
2642 hot_button_ = hot_button;
2643 if (hot_button)
2644 hot_button->SetHotTracked(true);
2645 }
2646
2612 } // namespace views 2647 } // namespace views
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698