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

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

Issue 12529012: Context menu on views must show on mouse down for non-WIN. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: patch Created 7 years, 8 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 | Annotate | Revision Log
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/run_loop.h" 9 #include "base/run_loop.h"
10 #include "base/time.h" 10 #include "base/time.h"
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
50 static const int kCloseOnExitTime = 1200; 50 static const int kCloseOnExitTime = 1200;
51 51
52 // If a context menu is invoked by touch, we shift the menu by this offset so 52 // If a context menu is invoked by touch, we shift the menu by this offset so
53 // that the finger does not obscure the menu. 53 // that the finger does not obscure the menu.
54 static const int kCenteredContextMenuYOffset = -15; 54 static const int kCenteredContextMenuYOffset = -15;
55 55
56 namespace views { 56 namespace views {
57 57
58 namespace { 58 namespace {
59 59
60 // When showing context menu on mouse down, the user might accidentally select
61 // the menu item on the subsequent mouse up. To prevent this, we add the
62 // following delay before the user is able to select an item.
63 static int g_context_menu_selection_hold_time_ms = 200;
sky 2013/04/05 19:41:36 This isn't global. I think you want context_menu_s
varunjain 2013/04/05 21:58:42 Done.
64
60 // The spacing offset for the bubble tip. 65 // The spacing offset for the bubble tip.
61 const int kBubbleTipSizeLeftRight = 12; 66 const int kBubbleTipSizeLeftRight = 12;
62 const int kBubbleTipSizeTopBottom = 11; 67 const int kBubbleTipSizeTopBottom = 11;
63 68
64 // Returns true if the mnemonic of |menu| matches key. 69 // Returns true if the mnemonic of |menu| matches key.
65 bool MatchesMnemonic(MenuItemView* menu, char16 key) { 70 bool MatchesMnemonic(MenuItemView* menu, char16 key) {
66 return menu->GetMnemonic() == key; 71 return menu->GetMnemonic() == key;
67 } 72 }
68 73
69 // Returns true if |menu| doesn't have a mnemonic and first character of the its 74 // Returns true if |menu| doesn't have a mnemonic and first character of the its
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
279 MenuButton* button, 284 MenuButton* button,
280 MenuItemView* root, 285 MenuItemView* root,
281 const gfx::Rect& bounds, 286 const gfx::Rect& bounds,
282 MenuItemView::AnchorPosition position, 287 MenuItemView::AnchorPosition position,
283 bool context_menu, 288 bool context_menu,
284 int* result_event_flags) { 289 int* result_event_flags) {
285 exit_type_ = EXIT_NONE; 290 exit_type_ = EXIT_NONE;
286 possible_drag_ = false; 291 possible_drag_ = false;
287 drag_in_progress_ = false; 292 drag_in_progress_ = false;
288 closing_event_time_ = base::TimeDelta(); 293 closing_event_time_ = base::TimeDelta();
294 menu_start_time_ = base::TimeTicks::Now();
295
296 // If we are shown on mouse press, we will eat the subsequent mouse down and
297 // the parent widget will not be able to reset its state (it might have mouse
298 // capture from the mouse down). So we clear its state here.
299 if (parent && parent->GetRootView())
300 parent->GetRootView()->SetMouseHandler(NULL);
289 301
290 bool nested_menu = showing_; 302 bool nested_menu = showing_;
291 if (showing_) { 303 if (showing_) {
292 // Only support nesting of blocking_run menus, nesting of 304 // Only support nesting of blocking_run menus, nesting of
293 // blocking/non-blocking shouldn't be needed. 305 // blocking/non-blocking shouldn't be needed.
294 DCHECK(blocking_run_); 306 DCHECK(blocking_run_);
295 307
296 // We're already showing, push the current state. 308 // We're already showing, push the current state.
297 menu_stack_.push_back(state_); 309 menu_stack_.push_back(state_);
298 310
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
489 return; 501 return;
490 } 502 }
491 if (part.menu->GetDelegate()->ShouldExecuteCommandWithoutClosingMenu( 503 if (part.menu->GetDelegate()->ShouldExecuteCommandWithoutClosingMenu(
492 part.menu->GetCommand(), event)) { 504 part.menu->GetCommand(), event)) {
493 part.menu->GetDelegate()->ExecuteCommand(part.menu->GetCommand(), 505 part.menu->GetDelegate()->ExecuteCommand(part.menu->GetCommand(),
494 event.flags()); 506 event.flags());
495 return; 507 return;
496 } 508 }
497 if (!part.menu->NonIconChildViewsCount() && 509 if (!part.menu->NonIconChildViewsCount() &&
498 part.menu->GetDelegate()->IsTriggerableEvent(part.menu, event)) { 510 part.menu->GetDelegate()->IsTriggerableEvent(part.menu, event)) {
499 Accept(part.menu, event.flags()); 511 int64 time_since_menu_start =
512 (base::TimeTicks::Now() - menu_start_time_).InMilliseconds();
513 if (!state_.context_menu || !View::ShouldShowContextMenuOnMousePress() ||
514 time_since_menu_start > g_context_menu_selection_hold_time_ms)
515 Accept(part.menu, event.flags());
500 return; 516 return;
501 } 517 }
502 } else if (part.type == MenuPart::MENU_ITEM) { 518 } else if (part.type == MenuPart::MENU_ITEM) {
503 // User either clicked on empty space, or a menu that has children. 519 // User either clicked on empty space, or a menu that has children.
504 SetSelection(part.menu ? part.menu : state_.item, 520 SetSelection(part.menu ? part.menu : state_.item,
505 SELECTION_OPEN_SUBMENU | SELECTION_UPDATE_IMMEDIATELY); 521 SELECTION_OPEN_SUBMENU | SELECTION_UPDATE_IMMEDIATELY);
506 } 522 }
507 SendMouseCaptureLostToActiveView(); 523 SendMouseCaptureLostToActiveView();
508 } 524 }
509 525
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after
725 HandleMouseLocation(submenu, point); 741 HandleMouseLocation(submenu, point);
726 } 742 }
727 } 743 }
728 744
729 void MenuController::OnWidgetDestroying(Widget* widget) { 745 void MenuController::OnWidgetDestroying(Widget* widget) {
730 DCHECK_EQ(owner_, widget); 746 DCHECK_EQ(owner_, widget);
731 owner_->RemoveObserver(this); 747 owner_->RemoveObserver(this);
732 owner_ = NULL; 748 owner_ = NULL;
733 } 749 }
734 750
751 // static
752 void MenuController::TurnOffContextMenuSelectionHoldForTest() {
753 g_context_menu_selection_hold_time_ms = -1;
754 }
755
735 void MenuController::SetSelection(MenuItemView* menu_item, 756 void MenuController::SetSelection(MenuItemView* menu_item,
736 int selection_types) { 757 int selection_types) {
737 size_t paths_differ_at = 0; 758 size_t paths_differ_at = 0;
738 std::vector<MenuItemView*> current_path; 759 std::vector<MenuItemView*> current_path;
739 std::vector<MenuItemView*> new_path; 760 std::vector<MenuItemView*> new_path;
740 BuildPathsAndCalculateDiff(pending_state_.item, menu_item, &current_path, 761 BuildPathsAndCalculateDiff(pending_state_.item, menu_item, &current_path,
741 &new_path, &paths_differ_at); 762 &new_path, &paths_differ_at);
742 763
743 size_t current_size = current_path.size(); 764 size_t current_size = current_path.size();
744 size_t new_size = new_path.size(); 765 size_t new_size = new_path.size();
(...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after
1086 possible_drag_(false), 1107 possible_drag_(false),
1087 drag_in_progress_(false), 1108 drag_in_progress_(false),
1088 valid_drop_coordinates_(false), 1109 valid_drop_coordinates_(false),
1089 last_drop_operation_(MenuDelegate::DROP_UNKNOWN), 1110 last_drop_operation_(MenuDelegate::DROP_UNKNOWN),
1090 showing_submenu_(false), 1111 showing_submenu_(false),
1091 menu_button_(NULL), 1112 menu_button_(NULL),
1092 active_mouse_view_(NULL), 1113 active_mouse_view_(NULL),
1093 delegate_(delegate), 1114 delegate_(delegate),
1094 message_loop_depth_(0), 1115 message_loop_depth_(0),
1095 menu_config_(theme), 1116 menu_config_(theme),
1096 closing_event_time_(base::TimeDelta()) { 1117 closing_event_time_(base::TimeDelta()),
1118 menu_start_time_(base::TimeTicks()) {
1097 active_instance_ = this; 1119 active_instance_ = this;
1098 } 1120 }
1099 1121
1100 MenuController::~MenuController() { 1122 MenuController::~MenuController() {
1101 DCHECK(!showing_); 1123 DCHECK(!showing_);
1102 if (owner_) 1124 if (owner_)
1103 owner_->RemoveObserver(this); 1125 owner_->RemoveObserver(this);
1104 if (active_instance_ == this) 1126 if (active_instance_ == this)
1105 active_instance_ = NULL; 1127 active_instance_ = NULL;
1106 StopShowTimer(); 1128 StopShowTimer();
(...skipping 1146 matching lines...) Expand 10 before | Expand all | Expand 10 after
2253 (!pending_state_.item->HasSubmenu() || 2275 (!pending_state_.item->HasSubmenu() ||
2254 !pending_state_.item->GetSubmenu()->IsShowing())) { 2276 !pending_state_.item->GetSubmenu()->IsShowing())) {
2255 // On exit if the user hasn't selected an item with a submenu, move the 2277 // On exit if the user hasn't selected an item with a submenu, move the
2256 // selection back to the parent menu item. 2278 // selection back to the parent menu item.
2257 SetSelection(pending_state_.item->GetParentMenuItem(), 2279 SetSelection(pending_state_.item->GetParentMenuItem(),
2258 SELECTION_OPEN_SUBMENU); 2280 SELECTION_OPEN_SUBMENU);
2259 } 2281 }
2260 } 2282 }
2261 2283
2262 } // namespace views 2284 } // namespace views
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698